# Non-critical third-party scripts defer-loaded or async

- **Pattern:** `ab-002011` (`performance-core.script-style-efficiency.third-party-async`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002011
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002011)

## Why it matters

Synchronous third-party scripts in `<head>` block HTML parsing from the moment the browser encounters them (ISO-25010 time-behaviour). A page with four analytics and marketing scripts loading synchronously — Google Analytics, Segment, Drift, Intercom — commonly adds 200–400ms of render-blocking time before any content displays. That delay is entirely external to your codebase: network latency, third-party CDN performance, and script execution time are all out of your control, yet they block your page from rendering.

## Severity rationale

High because synchronous third-party scripts block the entire HTML parsing pipeline, adding uncontrolled latency from external CDNs before any first-party content can render.

## Remediation

Move all non-critical third-party scripts to `async` or `defer` loading. Analytics, chat widgets, and pixel trackers are never critical for initial render:

```html
<!-- async: executes as soon as downloaded, does not block HTML parsing -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script>

<!-- defer: executes after HTML is parsed, in source order -->
<script defer src="https://cdn.segment.com/analytics.js"></script>
```

For the heaviest scripts (chat widgets, heatmap tools), delay loading until after the page is interactive:
```ts
// src/components/providers.tsx
if (typeof window !== 'undefined') {
  window.addEventListener('load', () => {
    const script = document.createElement('script')
    script.src = 'https://js.intercomcdn.com/shim.latest.js'
    document.body.appendChild(script)
  })
}
```

With Next.js `<Script>` component, set `strategy="afterInteractive"` or `strategy="lazyOnload"` instead of `strategy="beforeInteractive"`.

## Detection

- **ID:** `third-party-async`
- **Severity:** `high`
- **What to look for:** Count all relevant instances and enumerate each. Identify third-party scripts in the HTML: analytics (Google Analytics, Segment), marketing (pixel trackers, conversion tags), chat widgets, A/B testing, ads, etc. Check whether they are loaded synchronously in `<head>`, or with `async` or `defer` attributes. Look for script loading libraries or custom deferred loading patterns.
- **Pass criteria:** Non-critical third-party scripts (analytics, ads, chat, tracking) use `async` or `defer`, or are loaded asynchronously after page interactive. At least 1 implementation must be verified. Critical scripts (auth, feature flags affecting core functionality) may load synchronously if necessary.
- **Fail criteria:** Multiple non-critical third-party scripts loaded synchronously in `<head>` or early in `<body>`, blocking page rendering. No `async` or `defer` attributes.
- **Skip (N/A) when:** The project has no third-party scripts.
- **Detail on fail:** Name the blocking scripts. Example: `"Google Analytics, Segment, Drift chat widget, and Intercom all loaded synchronously in <head>. Total 245KB blocks rendering. No async attribute"` or `"Facebook Pixel and TikTok pixel block initial page load for 1.5s"`.
- **Remediation:** Defer non-critical third-party scripts:

  ```html
  <!-- Good: async loading -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=..."></script>

  <!-- Or defer for sequential execution -->
  <script defer src="analytics.js"></script>
  <script defer src="widget.js"></script>

  <!-- Or load after page is interactive -->
  <script>
    window.addEventListener('load', () => {
      const script = document.createElement('script')
      script.src = 'https://cdn.example.com/widget.js'
      document.body.appendChild(script)
    })
  </script>
  ```

## External references

- iso-25010 performance-efficiency.time-behaviour

Taxons: performance

HTML version: https://auditbuffet.com/patterns/ab-002011
