Google Analytics, Facebook Pixel, HubSpot, Intercom — your page loads 500KB of third-party JavaScript that blocks rendering. Partytown moves it all to a Web Worker, freeing your main thread.
The Problem
Third-party scripts are the #1 cause of poor Core Web Vitals:
- Google Tag Manager: 100-300ms blocking time
- Analytics scripts: 50-200ms each
- Chat widgets: 200-500ms
- Ad tracking: 100-400ms
Total: 500ms-1.5s of main thread blocking before your app becomes interactive.
How Partytown Works
Main Thread (your code) Web Worker (3rd party scripts)
┌──────────────────┐ ┌──────────────────────┐
│ Your React app │ │ Google Analytics │
│ User interactions│ ←───→ │ Facebook Pixel │
│ Smooth 60fps │ proxy │ HubSpot tracking │
│ │ │ Intercom widget │
└──────────────────┘ └──────────────────────┘
Partytown proxies DOM access from the worker thread. Third-party scripts run as if they are on the main thread but they are actually isolated.
Setup (Next.js)
npm install @builder.io/partytown
// app/layout.tsx
import { Partytown } from "@builder.io/partytown/react";
export default function Layout({ children }) {
return (
<html>
<head>
<Partytown forward={["dataLayer.push", "gtag"]} />
<script
type="text/partytown"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag(js, new Date());
gtag(config, G-XXXXXXX);
`,
}}
/>
<script
type="text/partytown"
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"
/>
</head>
<body>{children}</body>
</html>
);
}
The key: change type="text/javascript" to type="text/partytown". That is it.
Setup (Astro)
// astro.config.mjs
import { defineConfig } from "astro/config";
import partytown from "@astrojs/partytown";
export default defineConfig({
integrations: [
partytown({
config: {
forward: ["dataLayer.push", "gtag"],
},
}),
],
});
<script type="text/partytown" src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
Results
Typical improvements:
- Total Blocking Time (TBT): -60 to -80%
- Largest Contentful Paint (LCP): -200 to -500ms
- First Input Delay (FID): near zero
- Lighthouse Performance: +15 to +30 points
What Scripts to Move
Safe to move (tracking/analytics):
- Google Analytics / GA4
- Google Tag Manager
- Facebook Pixel
- HubSpot tracking
- Segment
- Mixpanel
- Hotjar
Keep on main thread (needs DOM interaction):
- Chat widgets (Intercom, Drift) — if they need to show UI
- Payment forms (Stripe Elements)
- reCAPTCHA
The forward Config
Partytown needs to know which global functions to proxy:
forward: [
"dataLayer.push", // GTM
"gtag", // GA4
"fbq", // Facebook Pixel
"_hsq.push", // HubSpot
]
Need performance optimization for your web app? I build fast web solutions and data tools. Email spinov001@gmail.com or check my Apify tools.
Top comments (0)