Marketing pages accumulate third-party scripts faster than any other page type — analytics, heatmapping, chat, A/B testing, and advertising pixels each run JavaScript on the main thread, and their combined effect on ISO-25010 resource-utilisation is additive. Five third-party script domains loading synchronously or with beforeInteractive strategy can contribute 300–500ms of main thread blocking time on a mid-range Android device, which directly causes INP failures above the 200ms threshold. Beyond user experience, each additional third-party domain adds a DNS lookup and TLS handshake — typically 100–300ms per new origin — before any bytes are received. Google's CrUX data consistently shows that pages with four or more synchronous marketing scripts have significantly worse INP distributions.
High because synchronous third-party marketing scripts collectively cause main thread blocking that exceeds Google's INP threshold on mid-range mobile, degrading Core Web Vitals and page experience rankings.
Consolidate all marketing pixels into Google Tag Manager so they fire through a single script tag, then defer GTM itself with afterInteractive. Load the chat widget on-demand rather than on page load.
import Script from 'next/script'
import { useState } from 'react'
// One tag for all pixels — consolidate in GTM dashboard
<Script
src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXX"
strategy="afterInteractive"
/>
// Chat widget — load only when user signals intent
const [chatReady, setChatReady] = useState(false)
const initChat = () => !chatReady && setChatReady(true)
{chatReady && (
<Script src="https://cdn.intercom.com/widget.js" strategy="lazyOnload" />
)}
<button onMouseEnter={initChat} onClick={initChat}>Chat with us</button>
Aim for no more than 3 third-party script domains on initial page load. Run npx lighthouse --output=json and check the "Third-Party Summary" section for main thread blocking time per origin.
ID: marketing-page-speed.loading-strategy.third-party-impact
Severity: high
What to look for: Marketing pages commonly accumulate many third-party scripts: analytics (GA, Plausible, Fathom), heat mapping (Hotjar, FullStory), chat (Intercom, Drift, Crisp), A/B testing (Optimizely, VWO), ad pixels (Meta Pixel, LinkedIn Insight, Google Ads). Each adds main thread blocking time. Check: (1) how many third-party script domains are loaded, (2) whether they use async/defer/afterInteractive, (3) total estimated script payload from third parties > 200KB is a concern. Count <Script> components and <script> tags in layout files. Count all instances found and enumerate each.
Pass criteria: Third-party scripts collectively add fewer than 150ms of main thread blocking time. This is achievable by: loading all analytics via afterInteractive, using a tag manager to consolidate multiple pixels, and not loading chat widgets until user interaction.
Fail criteria: More than 3 third-party script domains loaded synchronously or with beforeInteractive. Combined third-party JS > 300KB. Chat widget loaded immediately rather than on first interaction.
Skip (N/A) when: No third-party scripts detected in the project.
Detail on fail: "5 third-party script domains detected: GTM, Hotjar, Intercom, Meta Pixel, LinkedIn Insight. Intercom loaded synchronously. Combined payload estimated >400KB. Main thread blocking time likely exceeds 300ms on mobile."
Remediation: Consolidate and defer third-party scripts:
// Preferred: route all pixels through Google Tag Manager
// One script tag, fire all pixels from GTM
<Script
src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXX"
strategy="afterInteractive"
/>
// Chat — load only on first interaction (massive saving)
const [chatLoaded, setChatLoaded] = useState(false)
const loadChat = () => {
if (!chatLoaded) {
setChatLoaded(true)
// dynamically inject Intercom script
}
}
<button onClick={loadChat} onMouseEnter={loadChat}>Chat with us</button>