Boost Next.js Performance by Offloading Third-Party Scripts with PartyTown 🎉

I spent a number of years working in the WordPress agency space, and during that time, we frequently received requests from clients asking us to improve their website performance. They would run Lighthouse audits and come to us concerned that their sites weren’t meeting the performance standards they wanted.

We’d dive into their custom codebase and find optimizations, but often, the biggest culprits weren’t their code—they were third-party scripts like Google Analytics, Google Tag Manager, Intercom chat widgets, advertising networks, and so on. We’d report our findings and hear, “Oh, well, we have to have those…but can’t we make it faster anyway?”

That tension—between essential third-party functionality and website speed—is a challenge many web developers face. Fortunately, there’s a compelling solution that helps strike a balance: Partytown.

This article will cover:

The performance issues that can be caused by third-party scripts

What PartyTown is and how it can alleviate those issues

An example Next.js application to demonstrate the impact PartyTown can have

How you can implement PartyTown in your own Next.js app

A video version of this content is also available here:

Prerequisites

To benefit from this article, you should be familiar with the following:

JavaScript fundamentals

The basics of how web browsers load and execute scripts

Tools like Lighthouse for performance auditing

The structure of a Next.js project (specifically using the App Router)*

* Even if you’re not using Next.js, you can still learn the core concept of Partytown from this article and integrate it into your preferred framework using one of Partytown’s Integration Guides.

Understanding the Problem: Main Thread Overload

In modern web applications, the browser’s main thread is where critical tasks like rendering, user interaction, and layout updates occur. But third-party scripts often hog this thread, leading to sluggish performance. Chrome’s Lighthouse documentation breaks down how script execution dominates the main thread, especially from third-party code.

These scripts can:

Block rendering

Cause input delay

Significantly impact metrics like FID (First Input Delay) and TTI (Time to Interactive)

While some optimization techniques help—like adding async or defer attributes to tags (MDN reference), or using tools like @next/third-parties—they’re often not enough.

Meet Partytown

Partytown is an open-source library from Builder.io that offloads third-party scripts to a web worker, freeing up the main thread. This means your app’s critical work (like rendering UI and responding to user input) can continue smoothly while third-party scripts run in isolation.

Partytown is currently in beta and actively developed. While it doesn’t support every use case yet, it provides a powerful way to boost site performance.

Why is it called “Partytown”?

The name “Partytown” is a playful metaphor:

The main thread = your app’s “downtown,” where essential work happens.

Third-party scripts = noisy neighbors cluttering up your downtown.

Partytown moves those noisy neighbors out to the suburbs—a separate part of town—so they can “party” without disturbing downtown’s flow! 😄 In other words, they’re offloaded to a web worker.

Before You Reach for Partytown

Before integrating Partytown, consider these best practices:

Add async or defer to third-party tags so they don’t block rendering. Learn more on MDN.

Use the @next/third-parties package for smarter loading in Next.js projects (experimental as of this writing).

Follow performance tips on web.dev to minimize script impact.

Use Next.js’s component with a strategy prop:

beforeInteractive — for critical scripts

afterInteractive — for non-blocking scripts

lazyOnload — loads during idle time

worker — (experimental) loads in a worker using Partytown, but only works with Pages Router for now, not the App Router (Next.js script docs).

I recommend implementing these best practices first to optimize third-party scripts, then running a Lighthouse audit to test the site’s performance, paying particular attention to the “Minimize main-thread work” and “Reduce the impact of third-party code” sections of the report. Then, if you find that third-party scripts are still an appreciable performance issue, consider using Partytown to offload them from the main thread to web workers.

Testing Partytown’s Impact

Next, let’s run a few Lighthouse performance audits on a Next.js project that uses several third-party scripts. We’ll run one test with Partytown disabled and a second one with it enabled to measure its impact.

To get started, you can clone this example repository that demonstrates Partytown in action. Once you clone it, you can run npm install to install its dependencies, then npm run dev to get it running locally at http://localhost:3000.

This example project loads these third-party scripts:

slow-script.js: a generic script I wrote for testing that blocks the main thread for 300ms

fake-ads.js: a script I wrote that simulates advertisement scripts that block the thread, inject iframes, and load large images

Google Tag Manager

Intercom chat widget

Test 1: Without Partytown

You can disable Partytown in the example project by commenting out the <Partytown debug={true} forward={["dataLayer.push"]} /> line and removing type="text/partytown" from each of the scripts in src/app/layout.tsx.

Running a Lighthouse performance audit from the Chrome DevTools should then yield a result like this:

Note that the overall performance score is only 70/100, and that two of the main culprits are the “Minimize main-thread work” and “Reduce the impact of third-party code” items on the list.

If you open the Chrome DevTools and view the Sources tab, you can confirm that the main thread (labeled “top”) is doing all the work required by the third-party scripts:

Test 2: With Partytown

Now, restore the <Partytown debug={true} forward={["dataLayer.push"]} /> line and the type="text/partytown" prop for each of the Script components. This will enable Partytown.

Run another Lighthouse performance audit to see a result like this:

Note that the performance score is now 99/100, and that the “Minimize main-thread work” and “Reduce the impact of third-party code” are no longer present on the list of issues. Vastly improved!

If you open the Chrome DevTools and view the Sources tab, you can see that the main thread (labeled “top”) is still taking care of rendering the page, but that a new “Partytown 🎉” web worker has been added to the list. This “Partytown 🎉” web worker is now doing the work required by the third-party scripts:

The Takeaway

Take a step back and remember that for both the “Without Partytown” and “With Partytown” tests we ran, the browser had to download, parse, compile, and execute exactly the same third-party JavaScript code. The difference is that in the first test, the browser’s main thread had to do all of that work in addition to rendering the page, but in the second test, the third-party JS work was done by web workers running in a separate thread instead.

Implementing Partytown in a Next.js App Router Project

You can follow the steps below to implement Partytown in your own Next.js App Router projects.

⚠️ Be aware of trade-offs when using Partytown. Some scripts may not behave identically in a web worker. Review Partytown’s trade-offs before deploying to production.

Steps to Add Partytown

Install Partytown:

npm install @builder.io/partytown

Add a command to copy Partytown scripts
Add the script below to the scripts object in your package.json file, save it, then run npm run partytown to run the script and copy Partytown’s scripts into your public directory.

"scripts": {
// ...
"partytown": "partytown copylib public/~partytown"
},

Optionally, you can also add this partytown command to the dev and/or build scripts to copy Partytown’s files whenever the development server starts or the production app is built. Example:

"scripts": {
// ...
"dev": "npm run partytown && next dev --turbopack",
"build": "npm run partytown && next build",
"partytown": "partytown copylib public/~partytown"
},

Load Partytown in your RootLayout

In src/app/layout.tsx, add this line to import the Partytown component:

import { Partytown } from "@qwik.dev/partytown/react";

Then render it inside the element, like this:


// ...
<Partytown forward={["dataLayer.push"]} />


Partytown’s Configuration page lists all the options that can be passed to the Partytown component. Included among them is a debug option you can enable with debug={true} if you encounter any issues and need to debug them.

Add type="text/partytown" to Scripts

Pass a type="text/partytown" prop to the scripts you’d like to load via Partytown. If you have a script you want to remain on the main thread instead, simply omit the type="text/partytown" prop for that script.

<Script
src="https://cdn.jsdelivr.net/.../slow-script.js"
type="text/partytown"
/>

Here’s what the full root layout file might look like:

import Script from "next/script";
import { Partytown } from "@qwik.dev/partytown/react";

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (


<Partytown forward={["dataLayer.push"]} />


{children}

{/* Slow third-party script */}
<Script
src="https://cdn.jsdelivr.net/gh/kellenmace/partytown-nextjs/third-party-scripts/slow-script.js"
type="text/partytown"
/>


);
}

After implementing this, open Chrome DevTools and check the Sources tab. You’ll see the third-party scripts now load in a web worker (rather than under the main “top” frame), confirming that Partytown is working, just as we did in our tests.

Conclusion

Third-party scripts are necessary, but they can be performance killers. Partytown offers a creative, effective way to keep them around without dragging down your app’s speed. By offloading them to a web worker, your main thread stays responsive and users get a faster experience.

As web developers, it’s up to us to make smart trade-offs. And when it comes to performance vs. functionality, Partytown helps us have our cake and eat it too.

To learn more, check out:

Partytown Docs

Partytown + Next.js Guide

Next.js Scripts Guide

Happy coding, and enjoy the party (out of town)! 🎉