Skip to content

자바스크립트의 책임: Part Ⅲ

웹사이트의 자바스크립트 문제를 다루기 위해 가능하다고 생각한 모든 작업을 수행했다. 여러분은 사용할 수 있는 웹 플랫폼에 의존했으며, Babel을 피하고(‘변환 컴파일 줄이기’), 더 작은 대체 프레임워크를 찾았다(‘더 작은 대체제로 오버헤드 덜어주기’). 애플리케이션 코드는 가능한 한 가장 효율적인 형식으로 다듬었다. 그러나 아직 충분히 빠르지는 않다. 디자이너와 개발자가 기대하는 방식으로 웹사이트가 동작하지 않으면 우리는 스스로에게 다음과 같이 물을 수밖에 없다.

“뭘 잘못하고 있는 걸까? 우리가 작성한 코드는 어떤 작업을 수행할 수 있을까? 아키텍처의 어떤 부분이 문제인가?”

많은 성능 문제가 우리 자신의 코드에서 비롯되기 때문에 이런 질문은 유효하다. 하지만 오롯이 자신에게만 책임을 돌리는 것은 성능 문제에 대한 꽤 큰 공격이 외부로부터 온다는 불편한 진실에 눈을 감는 것이다.

 

서드파티가 문제의 원인이 될 때

편리함에는 항상 대가가 따르며, 모두가 편리함만 추구하면 웹은 결국 황폐해진다. 특히 자바스크립트는 주로 우리가(제1 당사자) 원치 않는 일을 외부에 의존하는 방식으로 해결하는 경향을 급격히 증가시킨다. 때로는 이런 결정이 필요하다. 많은 상황에서 그런 결정이 완벽한 가성비를 제공한다.

그러니 판단을 잘하지 않으면 서드파티 자바스크립트 때문에 비싼 비용을 치르게 된다. 공급자는 여러분이 겪는 문제에 대한 솔루션으로 유혹하지만 이런 거래는 해당 솔루션이 부작용을 통제하지 못한다는 점을 망각하게 하는 악마의 거래다. 서드파티 공급자가 자신들의 제품에 기능을 추가하면 그런 상황에 대응해야 한다. 공급자가 그들의 하부 구조를 변경한다면 우리는 그 변경의 영향을 고스란히 받게 된다. 영향을 받은 여러분의 사이트를 이용하는 사람들은 불만을 느낄 것이고, 참기 힘든 사용자 경험을 견디려고 애쓰지 않을 것이다. 서드파티의 영향을 다소 완화할 수 있지만 솔루션을 전부 제거하지 않는 한 문제를 해결할 수 없으며, 이마저도 항상 가능한 것은 아니다.

“자바스크립트의 책임: Part Ⅲ”에서는 이전 편보다 약간 덜 기술적인 접근 방식을 취한다. 여기서는 서드파티의 인간적인 면에 관해 더 다룰 것이다. 그 후에 문제를 어떻게 다룰지에 관해서 기술적인 방안을 살펴보겠다.

 

편리함이 오히려 방해가 될 때

오늘날 웹의 안타까운 상태에 관해 이야기할 때 곧바로 개발자 편의가 문제에 원인을 제공한다고 지적하는 이들이 있다. 개발자 편의가 사용자 경험을 해치는 경향이 있다는 관점에 찬성하지만, 개발자 편의가 웹사이트를 느리고 엉망진창으로 만드는 유일한 요인은 아니다.

작업의 편의는 아주 골치 아픈 기술 부채technical debt의 전조가 될 수 있다. 자체적으로 확대되어가는 문제를 해결할 수 없을 때 편의가 부채였다고 깨닫게 된다. 아키텍처적인 유연성과 적절한 개발 리소스가 없는 상태로 문제를 다루는 서드파티 솔루션이 부채의 원인이다.

불편하다고 느낄 때마다 포괄적인 방식으로 그 문제를 어떻게 다룰지 논의해야 할 시간이 된 것이다. 따라서 좀더 인간적인 시각에서 이런 종류의 시나리오를 다루는 모습에 관해 이야기해보자.

 

문제는 고통이다

애당초 서드파티가 끼어들게 된 이유는 고통 때문이었다. 조직의 의사결정자가 특정 문제에 관해 느끼는 고통이 임계치에 이르면 의사결정자는 고통을 벗어나는 가장 빠른 방식을 찾기 위해 매우 인간적인 결정을 한다.

시장은 지속 가능하거나 원격으로 도움이 되지 않더라도 항상 이런 고통 포인트를 다루는 방법을 찾는다. 웹 접근성 오버레이(접근성 문제를 자동으로 해결한다고 주장하는 서드파티 스크립트)가 가장 나쁜 주범이다. 먼저 어떤 것도 고치지 않아도 되는 해결책을 찾느라 돈을 낭비한다. 그 뒤 그 ‘해결책’이 웹사이트의 사용성을 해칠 때 완전히 다른 차원의 비용을 지불하게 된다. 이런 지적은 서드파티 공급자가 제공하는 도구의 유용성을 불신해서 늘어놓는 이야기가 아니라 객관적으로 끔찍한 솔루션일지 모르는 서드파티 솔루션이 어떻게 채택되는지 설명하고 싶어서다.

A depiction of a long task in a flame chart from the performance panel in Chrome DevTools.
서드파티 웹 접근성 오버레이 스크립트가 시작한 오랫동안 돌아가는 작업의 크롬 성능 추적. 이 작업은 2017 레티나 맥북에서 메인 스레드가 600ms 동안 실행된다.

 

어떤 공급자가 우리가 겪고 있는 아주 고통스런 문제를 해결해준다고 약속할 때, 여기에 끼어들 좋은 기회라고 생각하는 사람이 나타날지 모른다. 그가 조직에서 상당한 상위 직급이라면 (이들을 의사결정 과정에서 완전히 배제하지 않는 한) 공급자의 제품을 구매하도록 압력을 가할 것이다. 반대로 현장에 있는 이들이 압력을 받고 있고 스스로 필요한 기능을 만들 리소스가 충분하지 않다면 서드파티 솔루션을 채택할 수도 있다.

기폭제가 무엇이든 동료를 모아 그들의 집단 지성으로, 직면한 문제를 탐색하고 완화하는 계획을 세우는 일은 도움이 된다.

 

완화 계획 만들기

조직원들이 서드파티 솔루션을 고집하지만 문제를 인식하고 변경하려 할 때 직면하게 될 어려움은 해당 솔루션이 제공하는 서비스가 얼마나 긴급한가에 달려 있다. 사실 잘못 결정된 솔루션 지지자들을 설득하려고 하지 말아야 한다. 그런 노력은 거의 대부분 역효과를 일으키며, 사람들은 공격받는다고 느낄 수 있고 여러분이 하려는 이야기에 더 저항할지도 모른다. 더 나쁜 것은 이런 노력이 서로를 외면하는 험악한 분위기를 만들 수 있으며, 문제를 더 심각하게 만드는 촉매제가 된다.

내가 자주 그렇게 했듯이 여러분의 불만을 제쳐놓고 동료를 더 나은 결과로 안내할 완화 계획을 제시해야 한다면 동료들의 불만에 동조하면서 한편으로 다독여주는 역할을 하자. 서드파티 자체와 조직 구조에 따라 접근 방식의 세부적인 사항은 다르지만 다음과 같은 일련의 핵심 질문은 던질 수 있을 것이다.

 

솔루션이 어떤 문제를 다루는가?

서드파티 솔루션을 선택했을 때는 그만한 이유가 있을 것이다. 그러므로 이 질문은 솔루션 채택의 근거가 올바른지 파악하는 데 도움을 줄 것이다. 필요한 사람 모두가 방 안에 없어도 결정을 내려야 할 때가 있다는 사실을 기억하자. 여러분이 그 결정의 여파에 대응해야 하는 위치에 있을 수 있지만, 이 질문의 답은 자연스런 후속 조치로 이어질 것이다.

 

솔루션을 얼마나 오랫동안 사용하려고 하는가?

이 질문은 솔루션의 유통기한을 파악하는 데 도움을 준다. 접근성 오버레이의 경우처럼 근본적인 문제가 처리되면 제거할 용도로 임시로 적용한 것인가? A/B 테스트 스위트에서 제공한 데이터처럼 보다 장기적인 필요에 의한 것인가? 다른 가능성은 분석 스크립트처럼 중요한 목적이 있기 때문에 그 솔루션을 사실상 제거할 수 없는 경우다. 마치 수영장에 매트리스를 던지는 경우와 같다. 던지기는 쉽지만 다시 끌고 나오기는 쉽지 않다.

어쨌든 요청하지 않으면 서드파티 스크립트가 제공 중인 서비스에 남아 있는지 알 수 없다. 사실 해당 솔루션이 임시로 사용된 것을 알게 된다면 근본적인 문제가 해결된 경우 결국 사이트에서 제거할 계획을 세울 수 있다.

 

문제가 발생할 경우 연락할 사람이 누군가?

서드파티 솔루션이 투입될 때 문제가 발생하면 연락할 누군가가 있어야 한다.

서드파티 스크립트를 제어할 수 없을 때 발생하는 문제를 너무나 자주 접한다. 예를 들어, 태그 관리자나 A/B 테스트 프레임워크의 자바스크립트가 서서히 느리게 늘어나는 이유는 마케팅 담당자가 오래된 태그나 완료된 A/B 테스트를 정리하지 않아서다. 바로 이런 이유로 사이트에서 사용 중인 서드파티 솔루션을 조직 내 특정인에게 책임을 부여해야 한다. 책임 범위는 상황마다 다르겠지만 다음과 같은 내용일 수 있다.

  • 서드파티 스크립트의 사용 공간 모니터링
  • 서드파티 스크립트가 너무 커져 통제 범위를 벗어나지 않도록 유지 관리
  • 공급자와 조직의 미래 관계를 논의하는 비정기적 회의
  • 여러 서드파티 간 기능 중복 여부 확인, 잠재적인 중복 제거 가능성
  • 특히 느린 서드파티 스크립트에 대한 보다 나은 대체제로서 더 빠른 대안을 찾는 연구

 

이런 맥락에서 책임이라는 화두는 팀 동료에게 멍에를 씌우는 부담스럽고 가혹한 의무가 아니라, 동료의 주의력을 높이는 도구여야 한다. 이를 염두에 두지 않으면 더 이상 무시할 수 없는 끔찍한 괴물이 될 때까지 서드파티 스크립트가 웹사이트에 미치는 악영향을 간과하게 될 것이다. 서드파티에 대한 책임을 할당하면 그런 일이 발생하지 않도록 도울 수 있다.

 

서드파티 솔루션을 책임감 있게 사용하기

완화 계획을 함께 세우고 모두를 참여시킬 수 있다면 서드파티 솔루션을 사용할 때 책임을 부여할 수 있다. 다행히도 실제 기술적인 작업은 사람들과 논쟁하는 것보다 더 쉬운 일이다. 따라서 여기까지 해냈다면 결과를 얻는 데 필요한 것은 시간과 끈기뿐이다.

 

필요한 것만 로드한다

두말하면 잔소리지만 필요한 것만 로드하자. 서드파티 자바스크립트는 고사하고 로드해서 사용하지 않는 퍼스트파티 자바스크립트의 양만 봐도 분명히 문제가 있다. 옷장에 잡동사니를 쑤셔 넣고 집을 청소하려는 것과 같다. 실제로 필요 여부와 상관없이 각 페이지마다 서드파티 스크립트를 로드하는 경우는 흔하지 않으므로, 관련된 사람과 연락해 어떤 페이지에 서드파티 스크립트가 필요한지부터 파악하자.

한 예로, 과거 내 고객은 특정 제품의 소매업체 목록을 얻고자 여러 브랜드 사이트에서 인기 있는 서드파티 도구를 사용했다. 도구는 분명한 가치를 제공했지만 그 스크립트는 사이트의 제품 상세 페이지에만 필요했다. 사실 그 스크립트가 모든 페이지에서 자주 로드되었다. 이 스크립트를 필요하지 않은 페이지에서 제거하면 제품 페이지가 아닌 곳의 성능이 크게 향상되어, 표면상으로는 전환 경로상의 성능 저하를 줄일 수 있었다.

페이지에 필요한 서드파티 스크립트를 파악하려면 확실히 기술적이지 않은 작업 몇 가지를 수행해야 한다. 실제로 책상에서 일어나 고민 중인 서드파티 솔루션의 책임자와 대화해야 한다. 이는 내게 매우 어려운 작업이지만 선의의 협력이 일어날 때 보람을 느끼며, 결국 좋은 결과를 얻는다.

 

서드파티 스크립트를 자체 호스팅하자

이 충고는 어느 면으로 보나 더 이상 비밀이 아니다. 이 시리즈의 이전 편에서 한 번 다루기도 했지만(‘서드파티 호스팅 코드 외부화’) 기회가 있을 때마다 모두에게 알려야 한다. 가능한 한 많은 서드파티 리소스를 직접 호스팅해야 한다. 자체 호스팅을 할 수 있는지는 서드파티 스크립트에 따라 다르다.

구글이 호스팅하는 라이브러리cdnjs, 기타 유사 공급자에게서 가져온 프레임워크가 있는가? 지금 당장 그것들을 자체 호스팅하자.

Casper.com은 옵티마이즐리Optimizely 스크립트를 자체 호스팅하는 방법을 찾았고 문제였던 초기 렌더링 소요 시간을 크게 줄였다. 이 사례로 서드파티 리소스가 끼치는 주요 문제는 다른 서버에 존재하기만 해도 성능이 가장 나쁜 병목현상을 일으킬 수 있다는 사실을 이해할 수 있다.

분석 솔루션이나 유사한 종류의 스크립트를 자체 호스팅하기 위해 알아보고 있다면 자체 호스팅은 더 높은 수준의 어려움과 씨름해야 한다. 일부 서드파티 스크립트를 간단히 자체 호스팅할 수 없다는 점을 파악하게 될 것이다. 그렇다고 자체 호스팅 문제에 대해 알아낼 가치가 없다는 뜻은 아니다. 서드파티 스크립트를 자체 호스팅하는 옵션을 선택하지 못하더라도 조바심 낼 필요는 없다. 시도해볼 만한 다른 완화 방법들이 있다.

 

교차 원본CROSS-ORIGIN 연결의 지연 상쇄하기

서드파티 스크립트를 자체 호스팅할 수 없는 경우 다음으로 가장 좋은 작업은 그 스크립트를 호스팅하는 서버에 사전 연결하는 것이다. 웹페이지테스트WebPageTest의 커넥션 뷰Connection View는 사이트에서 리소스를 수집하는 서버와 서버의 연결 수립에 따른 지연을 보여주는 환상적인 작업을 수행한다.

A screenshot of WebPageTest's connection view, which visualizes the latency involved with all the servers that serve content for a given page in a waterfall chart.
웹페이지테스트의 커넥션 뷰는 페이지를 로드하는 동안 페이지가 리소스를 요청하는 다른 서버 모두를 표시한다.

 

사전 연결은 브라우저가 적절한 때에 서드파티 서버를 발견하는 과정에 앞서 연결을 수립하기 때문에 효과적이다. HTML 파싱은 시간이 걸리고, 파서는 스타일시트와 다른 스크립트 때문에 종종 차단된다. 서드파티 스크립트를 자체 호스팅할 수 없는 환경이라면 사전 연결이 확실한 해결책이다.

 

서드파티 스크립트를 사전 로드하지 않아야 경우

앤디 데이비스Andy Davies가 지적한 것처럼 잠재적인 역효과를 고려하기 전에는 리소스를 사전 로드하는 작업이 처음에는 멋지게 들린다. 여러분이 사전 로드에 익숙하지 않다면 사전 연결과 비슷하지만 한 걸음 더 나아가 브라우저가 평소에 수행하는 것보다 훨씬 빨리 특정 리소스를 가져오도록 지시하는 것이라고 생각하자.

사전 로드의 문제점은 리소스를 가능한 한 빠르게 로드하는 작업에는 좋지만 그 리소스의 검색 순서를 바꾼다는 점이다. 이는 사전 로드를 수행하면 렌더링에 중요한 자원이나 심지어 핵심 기능까지 포함해 다른 리소스가 덜 중요하다는 암시를 주기 때문이다.

서드파티 코드 대부분이 자신이 작성한 코드만큼은 사이트 기능에 중요한 역할을 하지 않아야 안전할 것이다. 즉 서드파티 리소스를 사전 로드해야 한다면 페이지 렌더링에 중요하지 않은 서드파티 스크립트만 그렇게 해야 한다.

여러분 사이트의 초기 렌더링이 서드파티 스크립트에 의존하고 있다면 완화 계획을 참조해 그 스크립트에 대한 의존성을 제거하거나 개선하기 위해 할 수 있는 작업을 확인하자. 핵심 기능에 대한 서드파티 의존성은 마치 여러분의 최고 관심사를 염두에 두지 않는 이에게 많은 통제권을 주는 격이라서 결코 좋은 태도는 아니다.

 

비핵심 서드파티 스크립트의 지연 로드

최고의 요청은 요청을 하지 않는 것이다. 바로 로드할 필요가 없는 서드파티 스크립트가 있다면 교차 관찰자Intersection Observer를 통한 스크립트 지연 로드를 고려하자. 다음은 뷰포트로 스크롤할 때 페이스북의 좋아요 버튼을 지연 로드하는 코드다.

See the Pen <a href=’https://codepen.io/wabooks/pen/poJJvqY’>poJJvqY</a> by wa (<a href=’https://codepen.io/wabooks’>@wabooks</a>) on <a href=’https://codepen.io’>CodePen</a>

 

앞의 코드 조각에서 페이스북 SDK 자바스크립트 로드 여부를 추적하는 변수를 설정했다. 그다음 관찰한 요소가 뷰포트에 있는지와 페이스북 SDK가 로드되었는지를 확인하는 IntersectionListener를 만들었다. SDK 자바스크립트가 로드되지 않았다면 DOM에 SDK에 대한 참조를 주입해 요청을 시작한다.

모든 서드파티 스크립트를 지연 로드할 수 있는 것은 아니다. 그 스크립트 중 일부는 페이지 로드 시간에 동작해야 하며 지연될 수 없다. 그렇더라도 몇몇 서드파티 자바스크립트를 지연 로드할 수 있는지 확인하기 위해 해당 작업을 살펴보자.

서드파티 스크립트를 지연 로드하라는 제안을 할 때 대개 동료들은 서드파티가 제공하는 모든 상호작용을 어떻게 지연시킬 수 있는지 걱정한다. 어떤 것을 지연 로드할 때 리소스 로드에 눈에 띄는 지연을 일으킬 수 있기 때문에 그런 염려는 당연하다. 이 문제는 리소스 프리페치 작업으로 어느 정도 해결할 수 있다. 프리페치는 앞서 설명한 사전 로드와는 다르다. 프리페치는 비슷한 양의 데이터를 소비하지만 프리페치된 리소스는 더 낮은 우선순위를 가지며 중요 리소스와 대역폭을 경쟁하는 경우가 적다.

 

문제에 정통하자

서드파티 자바스크립트를 계속 지켜보는 데는 과하다 싶을 정도의 주의력이 필요하다. 기술 부채에 대한 빈약한 성과를 인식하면 자연스레 다른 유형의 기술 부채처럼 인식하고 다루려는 마음이 생길 것이다.

서드파티에 정통하다는 것은 태그 관리자와 A/B 테스트 정리, 서드파티 솔루션 통합, 더 이상 필요 없는 것 제거, 앞서 설명한 코딩 기법 적용과 같은 작업을 주기적으로 수행해야 하는 일종의 리팩터링이다. 더욱이 이 기술 부채를 주기적으로 다루려면 팀으로 작업해야 한다. 이런 종류의 작업은 자동화할 수 없으므로 실제 사람들과 얼굴을 맞대고 대화해야 한다.

이미 일정 간격을 두고 ‘스프린트 정리’ 일정을 잡는 습관이 있다면 그다음은 서드파티 또는 퍼스트파티 코드를 포함하는 것과는 관계없이 성능 관련 기술 부채를 다루는 시간과 공간 차례다. 기능 개발 시간이 전체 근무 시간을 모두 차지해서는 안 된다. 기능 개발에만 집중하는 개발 조직은 필연적으로 발생할 기술 부채에 완전히 장악될 것이다.

따라서 이 시리즈의 네 번째이자 마지막 편에서는 프로세스라는 맥락에서 자바스크립트를 책임감 있게 사용하려는 노력이 무엇을 뜻하는지 이야기한다. 더 빠르고 더 나은 접근성을 제공해 누구나 어디에서나 웹사이트를 더 많이 사용할 수 있게 만든다는 기치 아래 조직 연합에 관한 내용을 살펴볼 것이다.

 

도서 소개


매트 마키스의 『웹디자이너를 위한 자바스크립트』
자바스크립트의 기본 원리를 상세히 설명하여 디자이너나 개발자 또는 자바스크립트 초보자도 손쉽게 자바스크립트를 배울 수 있습니다. 기본 문법과 규칙, 함수, 객체, 루프의 개념을 예제와 함께 알기 쉽게 설명하고 자바스크립트의 강점인 간결하고 반복을 최소화하는 코드 작성법을 보여줍니다.

저작권 정보이 글은 A List Apart 기사를 번역한 것입니다. 저작권자의 정당한 허락을 받은 저작물로 한국어판 저작권은 웹액츄얼리에 있습니다. 웹액츄얼리의 서면 동의 없이 무단 전재, 복제를 금합니다. 원본은 Responsible JavaScript : Part Ⅲ에서 확인할 수 있습니다.
참여를 기다립니다!웹액츄얼리에서 웹디자인 관련 영문 번역자를 찾습니다. 웹 콘텐츠 번역에 관심 있는 분은 메일로 간략한 본인 소개와 번역 이력을 보내주시면 연락드리겠습니다.
books@webactually.com


맨위로