By clicking “Accept All Cookies”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.

Optimizing Page Load with Web Workers and Partytown

Luca Dardenne
February 5, 2024

Introduction

One of the first things we hear about JavaScript is that it is single-threaded and incapable of running tasks in parallel. But that is not entirely true, at least in the context of web browsers. As specified in HTML5 spec, Web Workers allow us to execute asynchronous code in background threads that runs independently of the main thread. 

The need for Third-Party Script Initializations:

Very often, we need (or our client wants) to integrate a third-party service or functionality into our webpage that is not crucial to the main functionality of the page, such as sending a page-view to an analytics tool. Well, this comes with a downside: it increases the amount of time that our page needs to fully load, directly affecting our site performance. The result: when running a Lighthouse test, it will flag the high blocking time - screenshot below. The impact: Degraded user experience, which will impact the user and other aspects like SEO.This is where we can take advantage of Web Workers, but only if we use them in conjunction with Partytown.

Why with Partytown?

Native Web Workers have their limitations, for example, they cannot access the DOM and can trigger cross-origin restrictions (I believe you too have encountered a CORS issue at least once). This is where Partytown comes in handy. It introduces a layer of abstraction that enables us to easily load any <script> element into our HTML code, providing DOM access and tools for proxying requests.

How-to guide into Partytown 🎉?

In this article, we are going to see how to initialize a Google Tag Manager (GTM) script in a separate thread using Partytown in a React application. This library was required as a set of integrations that our client requested. First step is to install Partytown itself.

Step 1. Install the library

Step 2. Add the script

Partytown provides us with a script for copying the necessary files that we need to serve to our page from our /public directory in order to use the library. This is important because these files must be served from the same origin. So, include it in our package.json

Tip: You can integrate this script into your build process directly as shown below

Step 3. Use it in the code 

3.1. Configuring Partytown

Although Partytown can be used in any webpage (you can refer to their Integration section), when working with React, we need to import the Wrapper Component for the Partytown Snippet and include it within the <head> tag of our page. I've done some testing and you can put it anywhere but that's their recommendation. You can archive this using a library like Helmet or, if you're using NextJS, within your <Head> tag (be sure to check their experimental API first).

If you're wondering about the forward={["dataLayer.push"]} property, this is because we need to do a little bit of configuration for some scripts to run as intended. In this case, Partytown requires us to specify which variables from the window object should be forwarded to the web worker. Since GTM calls window.dataLayer, by setting up this forward configuration, the web worker can still receive and process the data.

3.2. The Script:

Here I'm using the Next.js Script component to initialize our scripts that will be executed by a web worker. We specify this by setting the type property of the script tag to "text/partytown".

In our case, users have the ability to add their custom tracking tags into their pages, so we need to add the tags dynamically. You can create multiple <Script/> elements with the src property, one for each tag you have. Then for the inlined script, you need to only repeat the last line, so you can create a function that generates it.

Results

We can see how this impacted our main thread blocking time by running again a Lighthouse report, it tells us that we effectively initialized the script but it does not block the main-thread by any means. So we successfully reduced the impact of third-party code.

Conclusion

In the article we've discussed how Web Workers can be used to improve website performance by executing asynchronous code in the background. We exemplified it with a concrete, real-world problem: slow page loading caused by third-party scripts. We provide a detailed step-by-step guide on how to integrate Partytown into a React application to load scripts like Google Tag Manager in a separate thread. The results demonstrate a significant reduction in main thread blocking time, effectively improving the handling of third-party code and resulting in faster, smoother websites.

Interested in our services?
Please book a call now.