The common belief is that loading third-party scripts with async or defer attributes neutralizes their performance impact. This is only true for render-blocking behavior during initial page load. Once a third-party script is loaded, its execution consumes main-thread time regardless of how it was loaded. Analytics scripts processing events, ad scripts running auctions and rendering creatives, A/B testing tools evaluating variants, and chat widgets polling for updates all execute JavaScript on the same main thread that processes user interactions. This main-thread competition is the mechanism by which asynchronously loaded third-party scripts degrade INP, and to a lesser extent, LCP and CLS.
The Single Main Thread: Why Async Loading Does Not Mean Async Execution
Browsers run JavaScript on a single main thread per page. The async attribute changes when a script is fetched and executed relative to HTML parsing, but the execution itself is synchronous and main-thread-bound. When an async third-party script executes a 100ms task, the main thread is blocked for 100ms. Any user interaction arriving during this 100ms experiences elevated input delay — the first phase of INP measurement — because the browser cannot begin processing the interaction’s event handler until the current task completes.
The distinction between async loading and async execution is fundamental to understanding third-party script impact. Async loading means the script downloads in parallel with HTML parsing and executes as soon as it finishes downloading. defer loading means the script downloads in parallel and executes after HTML parsing completes. Neither attribute changes the execution model: the script’s code runs synchronously on the main thread, monopolizing it for the duration of each task.
Multiple third-party scripts executing interleaved tasks create a pattern of frequent main-thread occupancy that raises the baseline input delay for every interaction throughout the page session. If five third-party scripts each execute 50ms tasks at various intervals, the probability that any given user interaction coincides with one of these tasks is significantly higher than with a single script. The cumulative effect is a persistent degradation of interaction responsiveness that manifests as elevated INP at the 75th percentile in CrUX field data.
Google’s web.dev documentation on optimizing INP identifies third-party scripts as one of the most common causes of poor INP scores, noting that each script might individually add only 50-100ms of delay but 10+ third-party scripts together easily produce 500ms+ of interaction delay (web.dev, 2025). Position confidence: Confirmed through Chrome team documentation and consistent field observations across performance monitoring platforms.
How Third-Party Scripts Affect Each Core Web Vital
INP is the most severely affected metric because it measures interaction responsiveness across the full page session, and third-party scripts execute throughout the session — not just during initial load. Every analytics event dispatch, every ad viewability check, every A/B test evaluation, and every chat widget poll creates a main-thread task that can coincide with and delay a user interaction. The INP impact accumulates across the session because INP selects a high-percentile interaction (approximately the 98th percentile for pages with 50+ interactions), meaning even occasional third-party long tasks during the session can define the page’s INP value.
LCP is affected when third-party scripts block the main thread during the critical rendering window. A synchronously executing analytics initialization script that runs for 200ms during page load delays the browser’s ability to process resource loading callbacks, decode images, and paint the LCP element. Even scripts loaded with async can interfere with LCP if they happen to execute during the rendering-critical window between TTFB and LCP paint. The async attribute controls when the script executes relative to HTML parsing but not relative to rendering milestones.
CLS is affected when third-party scripts inject DOM elements without reserved space. Ad containers that expand after the creative loads, chat widget bubbles that push content down, cookie consent banners that shift page content, and notification overlays that displace visible elements all produce layout shifts. These shifts are caused by the third-party script’s DOM manipulation, not by its main-thread execution cost, making CLS the one CWV metric where the mechanism is DOM mutation rather than main-thread competition.
The Long Task Problem: Third-Party Scripts as Long Task Generators
The Performance API defines a long task as any main-thread task exceeding 50ms. Third-party scripts are disproportionately responsible for long tasks because they are optimized for their own functionality — maximizing ad revenue, capturing comprehensive analytics, or providing feature-rich chat experiences — not for the host page’s interaction performance. The incentive structure misaligns: the third-party vendor benefits from comprehensive functionality while the publisher bears the performance cost.
Common third-party long task patterns measured in production environments:
- Header bidding scripts: auction processing executes 200-400ms tasks as multiple demand partners respond with bids, compute bid values, and select winners. Each auction cycle is a long task that blocks the main thread during a window where users are actively attempting to interact with the page.
- Analytics event batching: analytics scripts batch DOM events (clicks, scrolls, form interactions) and periodically transmit them to collection endpoints. The batching and serialization logic can execute 100-200ms tasks, particularly when the event queue is large.
- A/B testing variant evaluation: client-side A/B testing tools evaluate targeting rules, select variants, and modify DOM elements to apply the selected variant. Complex targeting (geographic, behavioral, cookie-based) combined with DOM manipulation produces long tasks during initialization and during subsequent page navigation in SPAs.
- Ad viewability monitoring: scripts that check whether ad containers are visible in the viewport run IntersectionObserver callbacks or scroll event handlers at regular intervals. Each check is short (5-20ms), but the frequency (every 100-200ms) creates a steady stream of main-thread interruptions.
The Long Animation Frames API (LoAF) provides per-script attribution that identifies which script URL generated each long frame. LoAF reports the sourceURL of scripts contributing to frames exceeding 50ms, enabling direct measurement of each third-party script’s long-task contribution. SpeedCurve’s documentation notes that script attribution is the most valuable feature of LoAF for third-party performance analysis, as it enables data-driven decisions about which scripts to optimize, defer, or remove (speedcurve.com, 2025).
Third-Party Execution Patterns That Create Persistent Main-Thread Contention
Beyond initial execution, many third-party scripts create recurring main-thread work that persists throughout the page session:
Polling patterns: ad viewability checkers poll scroll position at intervals (typically every 100-200ms) to determine whether ad containers are in the viewport. Real-time chat widgets poll for new messages every 5-30 seconds. Social media embed scripts poll for engagement metrics. Each poll is a main-thread task that, while often short individually, creates a background level of main-thread occupation.
Event listener cascades: analytics scripts attach event listeners to document-level events (click, scroll, resize, input) to capture user behavior. Each user interaction triggers not only the page’s own event handlers but also every third-party listener attached to the same event. A single click may invoke the page’s click handler (5ms), Google Analytics’ click tracker (10ms), a heatmap tool’s click recorder (15ms), and an A/B testing tool’s conversion tracker (10ms) — totaling 40ms of processing time from listeners the page developer did not write.
DOM mutation observers: some third-party scripts use MutationObserver to monitor DOM changes for tracking purposes or to inject content in response to page updates. Each DOM mutation triggers the observer callbacks, adding main-thread work proportional to the number of observing scripts and the frequency of DOM changes.
The combined effect of 5-10 third-party scripts with recurring tasks can occupy 10-20% of available main-thread time during an average session. On mid-tier devices where the main thread is already slower due to limited CPU performance, this background occupation is proportionally more impactful, explaining why third-party script impact disproportionately affects the 75th percentile device tier that determines CrUX scores.
Cross-Origin Iframe Isolation as the Primary Mitigation
Loading third-party scripts in cross-origin iframes moves their JavaScript execution to a separate browsing context with its own main thread. Ad scripts running in cross-origin iframes cannot block the host page’s main thread, eliminating their direct INP contribution. This is the single most effective mitigation for third-party main-thread impact.
The Google Publisher Tag (GPT) supports iframe-based ad rendering by default, serving ad creatives in cross-origin iframes where their JavaScript and rendering work does not affect the host page’s main thread. This isolation is why well-configured GPT ad implementations often have lower INP impact than other third-party integrations that run in the host page context.
The limitation of iframe isolation is that some third-party functionality requires access to the host page’s DOM:
- A/B testing tools that modify page content (changing headlines, rearranging layouts, showing/hiding elements) must execute in the host page context because they need direct DOM access.
- Analytics tools that track specific DOM interactions (form field focus, scroll depth on specific elements, clicks on particular buttons) need host-page event listener access.
- Personalization engines that dynamically alter page content based on user segments require host-page DOM manipulation.
- Cookie consent managers that must intercept and control other scripts’ loading behavior need host-page script management access.
For scripts that require host-page DOM access, the fallback mitigations are: deferring initialization until after the first user interaction (reducing the collision window), requesting lighter script builds from the vendor that strip non-essential features, using scheduler.yield() within first-party event handlers to create main-thread windows between third-party tasks where the browser can process user interactions, and setting explicit loading order priorities so critical first-party scripts execute before non-critical third-party scripts.
Limitations: The Unresolvable Tension Between Functionality and Performance
Some third-party scripts provide essential business functionality — analytics for decision-making, ad monetization for revenue, personalization for conversion optimization — that requires main-thread access on the host page. These scripts cannot be eliminated or fully isolated without sacrificing the business outcomes they deliver.
The achievable strategy is not elimination but cost management: quantify each script’s main-thread cost using LoAF attribution data, negotiate lighter implementations with vendors who exceed their allocated main-thread budget, defer non-critical scripts to post-first-interaction timing, and optimize first-party code to create sufficient INP headroom to absorb the remaining third-party impact. Accepting some INP impact from essential third-party scripts while optimizing every controllable factor to maintain passing CrUX scores is the pragmatic equilibrium for most production sites.
The 47% INP pass rate across the web as of 2025 reflects, in significant part, the accumulated main-thread cost of third-party scripts across the average site’s tag stack. Improving this pass rate requires either reducing third-party script counts, reducing per-script main-thread costs through vendor optimization, or both.
Does loading a third-party script in an iframe eliminate its main-thread impact?
Only if the iframe is cross-origin. A same-origin iframe shares the main thread with the parent document, so scripts within it compete for execution time exactly like scripts in the parent. A cross-origin iframe runs on a separate process with its own main thread, isolating its CPU impact from the parent page. However, cross-origin iframes can still affect CLS if they resize after load, and their network requests compete for bandwidth.
Can Google Tag Manager’s built-in triggers (scroll, timer, visibility) affect INP?
Yes. GTM trigger evaluations run on the main thread. Scroll-based triggers fire during scroll events, visibility triggers use Intersection Observer callbacks, and timer triggers execute their tag payloads at scheduled intervals. When these triggers fire during or near a user interaction, the tag execution competes with the interaction’s event handler for main-thread time, increasing INP.
Does the order of third-party scripts in the HTML document affect their CWV impact?
Yes. Scripts earlier in the document parse and execute before scripts later in the document. An early third-party script that blocks the main thread delays the parsing and execution of all subsequent scripts, including first-party code responsible for rendering above-the-fold content and setting up interaction handlers. Moving performance-sensitive first-party scripts before third-party scripts in the document order reduces the risk of third-party delays affecting LCP and initial interactivity.
Sources
- https://web.dev/explore/how-to-optimize-inp
- https://developer.chrome.com/docs/web-platform/long-animation-frames
- https://www.speedcurve.com/blog/guide-long-animation-frames-loaf/
- https://www.debugbear.com/blog/long-animation-frames
- https://developer.mozilla.org/en-US/docs/Web/API/PerformanceAPI/Longanimationframetiming