Websites that use cookies, analytics, advertising, and other tracking technologies need to obtain user consent. Consent Management Platforms (CMPs) are essential for websites: CMPs scan sites for cookies, collect and manage user consent, and block script execution before consent.
However, CMP scripts can also add JavaScript execution to the browser's main execution thread, which may affect page responsiveness and overall performance.
One way to reduce that impact is to use Web Workers that provide a method to run JavaScript in the background, separate from the main execution thread. This allows for performing expensive tasks like computation, parsing, and third-party execution without blocking the user interface, leading to smoother webpage performance and user experience.
Workers don’t have access to the DOM, which stores the page content. But they can handle heavy computational tasks without blocking site rendering.
To reduce this impact and improve CMP performance, developers use Partytown.
Developers use Partytown, an open-source library, to offload third-party scripts into web workers automatically. Partytown moves certain third-party scripts away from the main browser thread and executes them inside web workers. As a result, the main thread can focus on rendering page content and handling user interactions.
Partytown can be a useful tool for websites that rely heavily on third-party JavaScript. By moving compatible scripts into web workers, it can reduce pressure on the browser's main thread and help keep pages responsive.
In this Partytown setup guide, we'll explain what Partytown does, how you can configure a CMP to work with Partytown, and what the best practices are for running CMP Scripts in web workers.
What is Partytown and What Is It Used For?
Partytown is an open-source library maintained by Builder.io, that is designed to move third party scripts from the main JavaScript thread into a web worker. Web workers operate separately from the main browser thread, allowing JavaScript tasks to run without directly blocking rendering and user interaction.
Normally, analytics tools, advertising platforms, tag managers, and other third-party scripts (Google Analytics, Google Tag Manager, Meta Pixel, TikTok Pixel, Hotjar, etc.) execute alongside your application's own JavaScript. When several of these scripts run at the same time, they can consume CPU resources and block the main thread.
The main thread also handles key browser tasks such as rendering page content, responding to clicks and taps, processing JavaScript, updating the DOM, and responding to user input. Heavy third-party JavaScript can therefore slow interactions and overall website performance.
Partytown changes the JavaScript execution architecture by moving third-party scripts from the main browser thread into a web worker. This allows for performing heavy tasks without blocking rendering, leading to a smoother user experience.
Developers integrate Partytown into Next.js, Astro, Nuxt, and many other frameworks.
Consent Management Platform scripts are also third-party scripts, that are moved by Partytown into a web worker. However, the wrapped scripts still set cookies, obtain consent, and perform other consent obligations.
CMP web workers help perform heavy tasks without blocking rendering. However, Partytown is used only for performance optimization, it is not a privacy tool. You should configure your CMP to make cookies, analytics, or ad pixels GDPR compliant.
Use a CMP like CookieScript to manage consent obligations under eprivacy, the GDPR, and other privacy laws.
Use a CookieScript CMP, one of the best CMPs, to manage third-party scripts. It’s a Google-certified CMP with the Golden tier in Google’s tiering system, and is recommended by Google to use with its analytics and marketing tools.
CookieScript CMP offers the following features, needed for global privacy compliance:
- Integrations with website builders like Wix, Shopify, and Webflow, etc.
- Highly customizable cookie banner.
- Google Consent Mode v2 integration
- IAB TCF v2.2 integration
- Google Tag Manager integration
- Global Privacy Control
- Certification by Google
- CookieScript API
- Cookie Scanner
- Consent recordings
- Third-party cookie blocking
- Geo-targeting
- Self-hosted code
- Cookie banner sharing
- Cross-domain cookie consent sharing
CookieScript also offers a 14-day free trial.
How to Set Up Your CMP with Partytown and Web Workers
To set up your CMP like CookieScript with Partytown, install Partytown, initialize Google Consent Mode defaults on the main thread, move consent-dependent scripts into a web worker, configure Partytown JavaScript forwarding, bridge the CMP state to Partytown, and load GTM and trackers via Partytown. Also test consent management before loading tracking scripts.
Integrating a Consent Management Platform (CMP) like CookieScript while using Partytown requires careful architectural planning. Because Partytown executes scripts inside an isolated Web Worker using a proxied window object, the standard asynchronous CMP banner can easily break, fail to read DOM elements, or experience race conditions with Google Consent Mode v2.
Partytown CMP integration raises several issues. Before setting your CMP with Partytown, keep in mind these core architectural challenges:
- The main thread problem: Your CMP banner needs to render UI elements (HTML/CSS) directly onto the main thread so the user can see the banner and click it.
- The Web Worker isolation: Partytown strips third-party JavaScript off the main thread and push it into a worker. If you blindly set your CMP script into Partytown, the UI will break because web workers cannot directly manipulate the DOM.
- The timing problem: Google Consent Mode defaults must fire on the main thread before any tag manager or tracking pixel loads. If your CMP is delayed inside Partytown, Consent Mode updates will fail.
Use this step-by-step Partytown setup guide for setting up a CMP. When introducing Partytown, you must preserve this sequence of CMP script execution.
Step 1. Install Partytown
To install Partytown, install the package via npm (npm install @qwik.dev/partytown or npm install partytown), copy the library files to your public server path, include the inline snippet and library script in your HTML <head>, and change your third-party script tags to use type="text/partytown".
- Install package: Run
npm install @qwik.dev/partytown(or@builder.io/partytown) in your project terminal. - Copy library files: Copy the core Partytown library files from
node_modules/@qwik.dev/partytown/lib(or/~partytown/) to your public server path so they are served from your domain. - Add to HTML head: Place the configuration object, the inline snippet loader, and the script reference inside the <head> of your main HTML layout.
- Update third-party scripts: Change the type attribute of any tracking or analytics script you want to offload from text/javascript to text/partytown.
Instead of loading a third-party script as a standard script:
<script src="https://example.com/cmp.js"></script>
a Partytown-managed script may use a different script type:
<script type="text/partytown" src="https://example.com/cmp.js"></script>
This tells Partytown to process the script through its web-worker environment rather than execute it normally on the main thread.
Note: Do not automatically convert every CMP script to text/Partytown. Keep critical consent logic and the CMP UI on the main thread.
Step 2: Initialize Google Consent Mode defaults on the main thread
Set default Google Consent Mode settings before loading Google Analytics or marketing scripts. Consent management must be performed first, and only later analytics and marketing scripts.
Thus, set Google Consent Mode defaults on the main thread:
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// 1. Set strict defaults (Consent Mode v2)
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied',
'wait_for_update': 500
});
</script>
Step 3: Move consent-dependent scripts into a web worker (not the entire CMP)
The most practical architecture is not move the entire CMP into a web worker.
The CMP should remain responsible for consent management on the main thread, while the scripts it controls should be moved to Partytown.
For example:
<script src="/cmp-loader.js"></script>
<script type="text/partytown" src="https://example.com/analytics.js"></s
This setup lets you use the benefits of Partytown while keeping the most critical consent management on the main JavaScript thread.
Step 4. Configure Partytown JavaScript forwarding
If you use Google Tag Manager (or direct gtag calls) inside Partytown, instruct Partytown to forward function calls from the main thread into the web worker, and vice versa:
<script>
partytown = {
forward: ['dataLayer.push', 'gtag']
};
</script>
Some third-party libraries expect global JavaScript functions to exist on window.
Analytics implementations commonly follow a pattern like:
window.dataLayer = window.dataLayer || [];
function track() {
dataLayer.push(arguments);
}
The exact functions depend on the CMP and other third-party services used by your site. Inspect the CMP's integration documentation and identify any global variables, callback functions, or event queues that the platform expects to access.
Also read how to manage GPC and consent signals across MACH architectures.
Step 5: Bridge the CMP state to Partytown (the event listener)
When a user interacts with your main-thread CMP banner (e.g., clicking "Accept All"), the CMP fires an event. You must catch this event on the main thread and push the updated consent signals into the dataLayer so that Partytown-managed tags receive the update.
Make sure communication between the main thread and the worker happens correctly. You may need to forward functions, expose specific values, or keep the callback itself on the main thread.
For example, you could use a generalized event listener for your CMP:
JavaScript
// Example: Listening for a CMP consent change event
window.addEventListener('cmp-consent-changed', function(e) {
var consentState = e.detail; // Expected: 'granted' or 'denied'
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'update_consent',
'ad_storage': consentState.ads,
'analytics_storage': consentState.analytics,
'ad_user_data': consentState.userData,
'ad_personalization': consentState.personalization
});
});
It is important to clearly define consent state. Do not create one consent state inside the main thread and another independently inside the worker.
Note: If you use Google Tag Manager with a built-in CMP template, GTM handles the consent('update', ...) mapping automatically once the dataLayer catches the interaction).
Step 6: Load GTM and trackers via Partytown
Now, load your downstream marketing tags using Partytown's execution attribute (type="text/partytown"):
HTML
<!—Use this script to run safely inside the Web Worker, listening to the shared dataLayer -->
<script type="text/partytown" src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXX"></script>
Step 7. Test consent management before loading tracking scripts
After Partytown implementation, test consent management under several consent scenarios.
For a first-time visitor, test whether:
- CMP loads.
- No tracking scripts are executed before users give consent.
- Consent banner appears.
- Users can select cookie preferences.
- Only permitted services (analytics, marketing, etc.) initialize.
For a returning visitor, test whether:
- The setup implementation detects existing consent.
- Only allowed services initialize.
- Blocked categories of trackers remain disabled.
You should also test what happens when a visitor changes or withdraws consent. The resulting script behavior must stay synchronized with the user's latest preference and the CMP script execution order must be preserved.
Best Practices for Running CMP Scripts in Web Workers
When using Partytown, focus on which scripts can safely leave the main thread, not on how to move more JavaScript into a web worker. Prioritize consent before performance optimization, keep the consent UI on the main thread, start with analytics and marketing scripts, do not move scripts that depend heavily on the DOM, do not proxy cross-origin CMP requests blindly, watch for race conditions, test across browsers and devices, and monitor your network requests.
Use the following practices to make your implementation more reliable and GDPR compliant:
1. Prioritize consent before performance optimization
Your CMP's should manage consent correctly. This means that the CMP should first establish the appropriate consent state, and only then load analytics or tracking tools.
Always keep the consent initialization sequence strict.
2. Keep the consent UI on the main thread
Consent banners and preference options usually require direct interaction with the DOM. Users should be able to open the banner, select cookie categories, expand preference options, and save their decisions without noticeable delays.
Thus, it is important to keep UI-related CMP code on the main thread.
A practical separation, where to keep third-party scripts:
Main thread:
- Cookie Consent banner
- Preference options
- Consent state
- Consent revokes.
Web worker:
- Analytics scripts
- Advertising scripts
- Marketing integrations.
3. Start with analytics and marketing scripts
If you're introducing Partytown to an existing site, start with third-party scripts that are downstream of the CMP.
Start by moving these third-party scripts into a web worker:
- Analytics libraries
- Advertising tags
- Conversion tracking scripts
- Marketing pixels
- A/B testing tools
- Some customer-engagement platforms.
This can reduce main-thread JavaScript without immediately changing the CMP's architecture.
Once those integrations are stable, you can evaluate whether moving additional CMP-related scripts offers a meaningful benefit.
4. Avoid moving scripts that depend heavily on the DOM
Partytown provides mechanisms that allow worker-based scripts to interact with browser APIs, but it is not a good idea to move scripts that need synchronous DOM access into a web worker.
Before moving a CMP or related script into a web worker, check whether it performs operations such as:
document.querySelector(...)
element.getBoundingClientRect()
document.cookie
localStorage.getItem(...)
Frequent browser API interactions can complicate worker execution and reduce the benefit of moving the script.
5. Do not proxy cross-origin CMP requests blindly
If your CMP uses advanced asset requests that get caught by Partytown's synchronous XHR/fetch proxy restrictions, utilize Partytown's resolveUrl config hook to let direct asset requests bypass the worker proxy.
6. Watch for race conditions
Moving JavaScript into workers changes execution timing: a script that previously initialized immediately may now run slightly later.
For example:
initializeCMP();
initializeAnalytics();
may have worked previously because both functions executed synchronously.
After moving analytics or consent-related code to a web worker, you may need an explicit event-driven dependency:
onConsentReady(function () {
initializeAnalytics();
});
Use event-driven initialization. It is generally more reliable than assuming the scripts will be executed in the right order.
Use Google Tag Manager's Tag Assistant to verify that the Consent tab shows your initial default state immediately, followed by an update state the exact moment you click a button on your CMP banner.
7. Test across browsers and devices
Performance and timing issues may be different depending on the browser and device.
Testing slower devices is especially useful because race conditions that are invisible on a fast development computer may become obvious when CPU resources are limited.
Test your configuration in commonly used desktop and mobile browsers, particularly on less powerful mobile hardware.
When testing, look whether:
- The banner appears correctly.
- Consent choices can be saved.
- Previous choices are restored.
- Tracking scripts remain blocked until consent.
- Approved integrations initialize correctly.
- Changing consent updates script behavior.
- No persistent JavaScript errors appear in the console.
8. Monitor your network requests
One of the easiest ways to validate CMP integration is to inspect network activity.
No requests should be sent to analytics, advertising, or marketing domains before consent is granted. Check whether this is so.
After consent is granted, verify that the expected requests load.
Network inspection is a practical way to confirm that runtime behavior matches your intended consent configuration.
9. Measure the performance difference
Moving scripts to Partytown introduces additional architectural complexity, so verify that the change produces a meaningful improvement.
Compare performance before and after the implementation by checking:
- Main-thread JavaScript execution time.
- Long tasks.
- Page responsiveness.
- Interaction latency.
- Total third-party JavaScript activity.
If moving a particular CMP component provides very little performance improvement but significantly increases implementation complexity, keep that component on the main thread instead of a web worker.
Frequently Asked Questions
How to set up Partytown with a CMP?
To set up your CMP like CookieScript with Partytown, install Partytown, initialize Google Consent Mode defaults on the main thread, move consent-dependent scripts into a web worker, configure Partytown JavaScript forwarding, bridge the CMP state to Partytown, and load GTM and trackers via Partytown. Also test consent management before loading tracking scripts.
How to run CMP scripts in web workers?
To run CMP-related scripts in a web worker, use Partytown architecture. Install Partytown, mark the CMP script for worker execution, forward CMP functions when necessary, bridge the CMP state to Partytown, and load GTM and trackers via Partytown. Don't automatically move the entire CMP and test consent management before loading tracking scripts. CookieScript CMP offers a good Partytown CMP integration.
How to optimize CMP script execution?
You can optimize CMP script execution by loading the CMP as early as needed, then delaying non-essential third-party scripts (analytics, advertising, and marketing) until you know the user's consent status. For better performance, consider moving compatible third-party scripts to web workers using tools such as Partytown, while keeping the CMP banner, consent state, and other DOM-dependent functionality on the main thread. CookieScript CMP offers a good Partytown CMP integration.
What are best practices for Partytown web workers?
Prioritize consent before performance optimization, keep the consent UI on the main thread, start with analytics and marketing scripts, do not move scripts that depend heavily on the DOM, do not proxy cross-origin CMP requests blindly, watch for race conditions, test across browsers and devices, and monitor your network requests. CookieScript CMP is a good option for Partytown web workers.