Logo

지연 없는 서드파티 스크립트 로딩을 위한 Partytown 🎉

웹사이트 개발을 하다보면 여러가지 이유로 내가 작성하지 않은 서드파티(3rd-party) 스크립트를 불러와야 하는 경우가 있습니다. 대표적인 예로 Google Analytics와 같은 통계용 스크립트와 Google AdSense와 같은 광고용 스크립트를 들 수 있는데요.

이번 글에서는 웹 워커(Web Worker)라는 기술을 사용하여 이러한 서드파티 스크립트를 매우 빠르게 로딩해주는 혁신적인 라이브러리인 Partytown을 소개해드리겠습니다.

기존 스크립트 로딩 방식의 문제점

Partytown에 대해서 이야기하기 전에 기존에 웹에서 어떻게 스크립트를 불러왔는지를 잠깐 살펴보겠습니다.

보통 서드파티 스크립트를 로딩할 때는 아래와 같이 HTML에서 <script> 요소를 사용하죠?

<html>
  <head>
    <script src="서드파티 스크립트 주소"></script>
    <script>
      <!-- 서드파티 스크립트 코드 -->
    </script>
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

그런데 브라우저는 기본적으로 HTML 요소를 위에서 부터 아래로 순차적으로 처리하기 때문에 <head> 요소 아래에 스크립트를 불러오기 위한 <script> 요소가 많은 경우 웹사이트 성능과 사용자 경험에 악영향을 끼칠 수 있는데요. 왜냐하면 해당 스크립트를 네트워크를 통해 내려받아 실행이 끝날 때까지 브라우저 화면에는 아무 것도 나타나지 않기 때문입니다.

이러한 지연을 극복하기 위해서 <script> 요소의 deferasync 속성을 이용하여 최대한 스크립트를 빠르게 내려받게 하는데요. 하지만 스크립트의 실행은 여전히 브라우저의 몫이기 때문에 근본적인 해결책이 되지 못하는 경우가 많습니다.

script 요소의 defer과 async 속성을 통해서 자바스크립트를 효과적으로 로드하는 방법에 대해서는 관련 글을 참고 바랍니다

웹 워커(Web Worker)의 등장

많은 분들이 아시는 것처럼 브라우저는 기본적으로 하나의 웹사이트를 하나의 쓰레드(thread)로 실행합니다. 하지만 웹에서 돌아가는 애플리케이션의 복잡도가 증가함에 따라서 단일 쓰레드는 한계에 부딪히기 쉽죠.

하지만 Web Workers API가 도입되면서 드디어 웹에서도 멀티 쓰레딩이 가능한 시대가 열리고 있습니다. 웹 워커(Web Worker)는 브라우저의 백그라운드(background)에서 메인 쓰레드와 별도로 돌아가는 쓰레드라고 보시면 되는데요. 이 것을 잘 활용하면 기존에 브라우저의 메인 쓰레드에 몰빵되어 있던 처리 부담을 획기적으로 경감시켜줄 수 있습니다.

뿐만 아니라 웹 워커라는 기술은 기존에 웹에서 불가능하던 소위 동시성 프로그래밍(Concurrent Programming)을 가능하게 해줍니다. 현재 대부분의 모던 브라우저에서는 이 웹 표준 API를 제공하고 있으며 웹 워커를 활용한 라이브러리들이 활발하게 개발되고 속속들이 출시되고 있습니다.

Partytown

Partytown은 웹 워커 쓰레드를 이용하여 서드파티 스크립트를 백그라운드에서 로딩하도록 해주는 라이브러리입니다. 이를 통해 브라우저의 메인 쓰레드는 우리가 해당 사이트를 위해서 직접 작성한 코드를 실행하는데만 집중할 수 있게 됩니다.

Partytown

(이미지 출처: https://partytown.builder.io/)

그런데 라이브러리 이름이 상당히 재밌죠? 여기서 party는 3rd-party의 “party”와 즐거운 “party”의 중의적인 뜻을 내포하고 있는 것 같습니다.

참고로 Partytown을 만든 개발 팀에서 만든 또 다른 유명한 라이브러리로 Qwik이 있습니다. React와 비슷한 용도로 쓰이지만 상대적으로 속도가 엄청 빠른 걸로 알려져있는데요. 여기는 정말 성능에 진심인 것 같습니다. 🏎️

Partytown 라이브러리 설치

Partytown 라이브러리는 npm 공개 저장소에 @builder.io/partytown라는 이름의 패키지로 올라와 있습니다. 따라서 npm 패키지 매지저를 통해서 어떤 자바스크립트 프로젝트에서도 쉽게 설치해서 사용해볼 수 있습니다.

$ npm i @builder.io/partytown

Partytown 라이브러리 복사

Partytown이 제대로 동작하려면 브라우저에서 웹 워커를 활성화해주기 위한 기본적인 정적(static) 코드가 필요한데요. 다행히도 웹 워커에 대해서 잘 몰라도 Partytown에서 제공하는 CLI 도구를 사용하면 이 코드를 쉽게 복사해 올 수 있습니다.

$ npx partytown copylib public/~partytown

위 명령어에서 public/ 부분에는 자신의 프로젝트에서 정적 리소스를 두는 경로를 지정해줘야하는데요. 만약에 프로젝트에서 static/과 같은 다른 경로에 정적 리소스를 두신다면 그에 따라 바꿔주시면 됩니다.

Partytown으로 스크립트 로딩

이제 서드파티 스크립트를 로딩하고 있는 <script> 요소의 type 속성을 text/partytown으로 설정해주겠습니다. text/partytown 브라우저가 인식할 수 없는 스크립트 타입이기 때문에 브라우저는 더 이상 해당 스크립트를 내려 받거나 실행하려 하지 않을 것입니다.

<html>
  <head>
    <script type="text/partytown" src="서드파티 스크립트 주소"></script>
    <script type="text/partytown">
      <!-- 서드파티 스크립트 코드 -->
    </script>
    <script type="module">
      import { partytownSnippet } from "@builder.io/partytown/integration";
      const script = document.createElement("script");
      script.innerText = partytownSnippet();
      document.body.appendChild(script);
    </script>
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

type 속성이 module로 설정되어 있는 <script> 요소 안에 Partytown을 사용하는 코드를 추가했는데요. 이를 통해서 Partytown은 해당 웹페이지에서 text/partytown 타입의 <script> 요소를 모두 찾아서 웹 워커 쓰레드로 실행해줍니다.

이제 브라우저에서 소스 보기를 해보시면 Partytown이 처리해준 <script> 요소는 type 속성이 text/partytown-x로 바뀐 것을 보실 수 있으실 거에요. 이를 통해서 우리는 어렵지 않게 Partytown에 의해서 해당 스크립트가 로딩되었는지를 알 수 있습니다. 🥳

프레임워크와 통합

본 포스팅에서는 개념 설명을 위해서 Partytown의 정적 코드를 직접 복사해오고 스크립트를 로딩하는 부분도 손수 코딩했는데요. 사실 Partytown은 시중에 나와있는 대부분의 메타 프레임워크와의 매끄한 통합을 지원하고 있어서 실제 프로젝트에서는 훨씬 나은 개발자 경험을 하실 수 있습니다.

Next.js나 SvelteKit, Nuxt, Astro 등과 같은 프레임워크를 사용하고 계시다면 이렇게 번거로운 작업은 모두 빌드 도구를 통해 자동화되고요. 개발자들은 간편하게 서드파티 스크립트를 로딩하고 있는 <script> 요소의 type 속성을 text/partytown으로 지정해주기만 하면 됩니다.

프레임워크와 통합에 대한 자세한 내용은 공식 문서를 참고 바라겠습니다.

마치면서

이상으로 서드파티 스크립트를 로딩하는 기존 방식에 대한 문제점을 알아보고 웹 워커를 사용하여 이러한 성능 문제를 어떻게 해결할 수 있는지 알아보았습니다. 그리고 Partytown을 사용하여 어떻게 서드파티 스크립트를 백그라운드에서 지연 없이 로딩하는 방법에 대해서도 살펴보았습니다.

본 글이 여러분의 웹사이트의 성능을 향상시키고 사용자에게 쾌적한 경험을 제공하는데 도움이 되었으면 좋겠습니다.