# Third-party scripts loaded asynchronously or deferred

- **Pattern:** `ab-002041` (`performance-deep-dive.network-waterfall.third-party-scripts-async`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002041
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002041)

## Why it matters

A synchronous third-party `<script>` tag in `<head>` blocks HTML parsing until the script is downloaded, parsed, and executed. A single slow analytics script — say, a 400ms load from a third-party CDN under load — delays your entire page render by 400ms. ISO 25010:2011 time-behaviour captures the blocking cost; the full impact is that your first-party performance work is held hostage to the availability and speed of external vendors you do not control.

## Severity rationale

Low because blocking third-party scripts delay render but rarely cause total page failures; the risk scales with the number of synchronous scripts and the reliability of the external CDNs serving them.

## Remediation

Add `async` or `defer` to every third-party `<script>` tag. For analytics and monitoring loaded via Next.js `<Script>`, use `strategy="afterInteractive"` or `strategy="lazyOnload"`.

```tsx
// app/layout.tsx — defer third-party scripts
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script src="https://analytics.example.com/script.js" strategy="afterInteractive" />
      </body>
    </html>
  )
}
```

## Detection

- **ID:** `third-party-scripts-async`
- **Severity:** `low`
- **What to look for:** Count all `<script>` tags for third-party services (analytics, ads, chat, monitoring). Enumerate which use `async`, `defer`, or neither. Examine the HTML and component code for `<script>` tags or dynamic script loading. Look for third-party services (analytics, ads, chat widgets, Sentry, etc.). Check whether they use `async` or `defer` attributes, or are loaded dynamically after page load. Before evaluating, extract and quote the first 2 third-party script tags found in the codebase.
- **Pass criteria:** Third-party scripts (analytics, ads, chat widgets, monitoring) are loaded asynchronously or deferred. Main thread is not blocked by third-party code. Script loading patterns log blocking time. 100% of third-party scripts must use `async` or `defer`.
- **Fail criteria:** Third-party scripts are loaded synchronously with `<script src="..."></script>` (no async/defer), blocking page rendering.
- **Skip (N/A) when:** Never — third-party scripts should always be async/deferred.

- **Cross-reference:** For prefetching third-party domains, see `prefetching-configured`.
- **Detail on fail:** `"Google Analytics loaded synchronously — blocks rendering for 400ms"` or `"Chat widget script has no async or defer, loaded in <head> and blocks initial render"`
- **Remediation:** Add `async` or `defer` to third-party script tags, or load them dynamically after page load:

  ```html
  <!-- Async (loads in parallel, runs when ready) -->
  <script async src="https://cdn.example.com/analytics.js"></script>

  <!-- Defer (loads in parallel, runs after DOM parse) -->
  <script defer src="https://cdn.example.com/widget.js"></script>
  ```

---

## External references

- iso-25010 time-behaviour

Taxons: performance

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