Skip to content
Adam Bradley edited this page Jan 12, 2022 · 19 revisions
Partytown github fit 2x

A fun location for your third-party scripts to hang out

Partytown is a lazy-loaded library to help relocate resource intensive scripts into a web worker, and off of the main thread. Its goal is to help speed up sites by dedicating the main thread to your code, and offloading third-party scripts to a web worker.

Getting Started

Negative Impacts From Third-Party Scripts

Even with a fast and highly tuned following all of today's best practices, it's all too common for your performance wins to be erased the moment third-party scripts are added. By third-party scripts we mean code that is embedded within your site, but not directly under your control. A few examples include: analytics, metrics, ads, A/B testing, trackers, etc. Their inclusion are often a double-edged sword.

Below is a summary of potential issues, referenced from Loading Third-Party JavaScript:

  • Firing too many network requests to multiple servers. The more requests a site has to make, the longer it can take to load.
  • Sending too much JavaScript which keeps the main thread busy. Too much JavaScript can block DOM construction, delaying how quickly pages can render.
  • CPU-intensive script parsing and execution can delay user interaction and cause battery drain.
  • Third-party scripts that were loaded without care can be a single-point of failure (SPOF).
  • Insufficient HTTP caching, forcing resources to be fetched from the network often.
  • The use of legacy APIs (e.g document.write()), which are known to be harmful to the user experience.
  • Excessive DOM elements or expensive CSS selectors.
  • Including multiple third-party embeds that can lead to multiple frameworks and libraries being pulled in several times, which exacerbates the performance issues.
  • Third-party scripts also often use embed techniques that can block window.onload, even if the embed is using async or defer.

Goals

We set out to solve this situation, so that apps of all sizes will be able to continue to use third-party scripts without the performance hit. Some of Partytown's goals include:

  • Free up main thread resources to be used only for the primary web app execution.
  • Sandbox third-party scripts and allow or deny their access main thread APIs.
  • Isolate long-running tasks within the web worker thread.
  • Reduce layout thrashing coming from third-party scripts.
  • Throttle third-party scripts' access to the main thread.
  • Allow third-party scripts to run exactly how they're coded and without any alterations.
  • Read and write main thread DOM operations synchronously from within a web worker, allowing scripts running from the web worker to execute as expected.
  • No build-steps or bundling required, but rather update scripts the same way as traditional third-party scripts are updated.

Web Workers

Partytown's philosophy is that the main thread should be dedicated to your code, and any scripts that are not required to be in the critical path should be moved to a web worker. Main thread performance is, without question, more important than web worker thread performance. See the example page and test pages for some live demos.

If you're looking to run your app within a web worker, we recommend the WorkerDom project.

Trade-Offs

Nothing is without trade-offs. Using Partytown to orchestrate third-party scripts vs adding them to your pages has the following considerations to keep in mind:

  • Partytown library scripts must be hosted from the same origin as the HTML document (not a CDN).
  • DOM operations within the worker are purposely throttled, slowing down execution compared to the same code running on the main thread. (We also see this as a feature.)
  • A total of three threads are used: Main Thread, Web Worker, Service Worker (in the future we may explore Atomics which would bring it down to two).
  • Not ideal for scripts that are required to block the main document (blocking is bad).
  • event.preventDefault() will have no effect, similar to passive event listeners.
  • Trade-offs with intercepted network requests:
    • Many service worker network requests may show up in the network tab.
    • Partytown service worker requests are intercepted by the client, and transfer 0 bytes over the network.
    • Lighthouse scores are unaffected by the intercepted requests (any work on thread other than main has no impact on Lighthouse).

Use-Cases

While full webapps "could" run from within Partytown, it's actually best intended for code that doesn't need to be in the critical rendering path. Most third-party scripts fall into this category, as they're not required for the first-paint. Additionally, the asynchronous natural of most third-party script works well with Partytown, as they can lazily receive updates and post data to their respective services.

Below are just a few examples of third-party scripts that might be a good candidate to run from within a web worker. The goal is to continue validating commonly used services to ensure Partytown has the correct API, but Partytown itself does not hardcode to any specific services. Help us test!

Clone this wiki locally