Partytown is a lazy-loaded library to help relocate resource intensive scripts into a web worker.
🔗 Partytown By builder.io 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.
It’s important because third-party scripts have a habit of slowing down the time it takes for your website to load, and a slow-to-load website isn’t good for users, or performance metrics…. or $business!
What we know: adding third-party scripts on the main thread impacts performance by delaying the time it takes for your site to become available and ready to use by your end users.
But with Partytown, third-party scripts are offloaded to a web worker (which runs in its own thread), which means your site is available more quickly to your end users.
Your users thank you, your business thanks you, and we thank you for making a faster web!
⚠️ A word of warning
I should point out that Partytown is currently in BETA and the method I’m about to describe can also be considered BETA! – It does work but it could change in the future!
…but fear ye not! I have it on good authority that a Script component will be coming to Gatsby later in 2022 and all of the Partytown goodness I’m about to explain will be baked in and ready for you to use in the usual sweet, sweet Gatsby way! 💜
Oh also, before I forget, we’ve added some of the methods used in this post to the official Partytown docs, these can be found on the following links.
I just changed my file’s like the plugin,
gatsby-gtag-partytown, would do.
Remove any modules as in,
gatsby-plugin-google-gtag or google analytics
Google Analytics GA4 property
There’s quite a lot going on here, so let me talk you through it.
onRenderBody is one of gatsby-ssr’s extension points and runs after each page is created by Gatsby. It can be used to set HTMLor elements.
<script /> tags in the HTML
<head /> you can use the setHeadComponents function.
There’s an if condition right at the beginning to ensure the script tags and Partytown component aren’t added while in development
It’s also worth pointing out that the actual gtag script is ever so slightly different to the example given on the Google docs: Install the global site tag, i’ll explain why in a moment. – Read on 💅
<Partytown /> React component can be configured using regular React Jsx props. You can read more about the Partytown React component in the docs, but I will explain the forward prop as this is where things can get a little complicated.
The forward Prop “Problem”
If you have a look at Google’s recommended approach you might notice some differences between the code snippet i’ve used above and the one shown in: Add gtag.js to your site.
There’s a small but important difference shown here in the diff.
When Partytown moves scripts into a web worker it creates a kind of clone of the window object, and when it does, function gtag() isn’t hoisted onto the cloned window object.
By defining window.gtag = function gtag() we can ensure that the gtag function as referenced by the forward prop will exist on the Partytown cloned window object.
Hat tip to Ward Peeters (Gatsby’s Principal Engineer, Tech Lead Open-Source) for this solution 🎩.
There’s one other small difference in the code snippet. Here’s the diff.
To ensure that a page view isn’t sent once the script is loaded you can set send_page_view to false.
In the next section I’ll explain how you can fire off events containing location data. For reference here’s the Google docs for: Measure Google Analytics Events.
The onRouteUpdate function is called when the user changes routes, including on the initial load of the page. You can access the current location from the destructured props.
As with onRenderBody there’s an if condition right at the beginning to ensure the gtag event isn’t called while in development, and then inside a 100ms setTimeout is where you can fire off any event you like. I’ve called this one page_view and passed in a pagePath which can be constructed from properties contained within the location prop. The 100ms delay is required to ensure all side-effects such as React Helmet setting titles etc are complete before the gtag event is fired.
The onPreBuild extension point is used to copy the ~partytown files into Gatsby’s static directory, this happens quite early on in the build process.
Once Gatsby’s build steps are finished Gatsby copies the files from the static directory into the public directory, ready for when Partytown needs them and when your site is served from your CDN.
It’s worth noting onPreBuild is only called during the build process.
If you need to use copyLibFiles while in development you can use onPreBootstrap which is called when running both gatsby build or gatsby develop.
And that’s it, it’s a little more work than slamming a tag in your HTMLbut offloading third-party scripts into web workers using Partytown will no doubt yield a substantial performance boost. In this demo, understandably, there’s not a huge perf boost but if you were to offload all of your third-party scripts you’d start to really get a taste of the vibe 😛.
This is a bit manual for now, but manual optimizations and those small efforts that can land in a big way. So rest assured, we’ll plan to make this even more seamless in the future!
You choose Gatsby because of your need for speed, and we want to make the fast thing, the easiest thing.