Performance & CWV · Glossary · Updated Apr 2026

Render-blocking Resources

Definition

Render-blocking resources are CSS or JavaScript files in the document `<head>` that the browser must download and process before it can render anything. They delay First Contentful Paint and Largest Contentful Paint. Common fixes: inline critical CSS, async/defer JS, split CSS by media, preload the LCP element.

Find related

Long definition

The browser's render pipeline has a hard rule: it cannot paint pixels until it has built both the DOM (from HTML) and the CSSOM (from all CSS in the head). If CSS is missing, paint waits. If a synchronous script is in the head, the parser stops until that script downloads and executes. These are the two render-blocking patterns.

CSS is render-blocking by default. A <link rel="stylesheet"> in the head blocks rendering until the file downloads, parses, and the CSSOM is updated. Even a 10ms-to-download stylesheet adds 10ms to FCP, and slow CDN response times multiply directly into worse LCP.

Synchronous JS is parser-blocking. A <script src="..."> without async or defer halts the HTML parser entirely. The browser must download the script, execute it, then resume parsing. This is worse than CSS blocking because it blocks both DOM construction and rendering.

The standard set of fixes, in order of impact:

  • Inline critical CSS — extract the styles needed for above-the-fold and inline them in <style> in the head. Defer the rest with <link rel="stylesheet" media="print" onload="this.media='all'">.
  • Defer or async JavaScriptdefer runs scripts in document order after the parser finishes. async runs them as soon as they download. Either eliminates parser blocking. Use defer unless execution order doesn't matter.
  • Split CSS by media query<link rel="stylesheet" href="print.css" media="print"> is non-blocking. Same for media="(min-width: 1024px)" on small screens.
  • Preload the LCP image<link rel="preload" as="image" href="..." fetchpriority="high"> to start the LCP request before CSS finishes parsing.
  • Audit third-party tags — analytics, A/B testing, and chat widgets often load synchronously. Most have async variants; switch them.

Lighthouse flags render-blocking resources as an opportunity with the estimated savings. PSI surfaces the same audit. Cross-reference resource hintspreconnect, preload, dns-prefetch — for the upstream connection optimizations that pair with eliminating blocks.

Common misconceptions

  • "Async and defer are equivalent." Async runs scripts in network-arrival order, can interrupt parsing, and runs immediately after download. Defer runs scripts in document order, after the parser finishes, before DOMContentLoaded. Different ordering guarantees, different use cases.
  • "All CSS in the head is bad." Critical CSS belongs in the head — it's how above-the-fold styles arrive without a flash of unstyled content. The problem is non-critical CSS in the head, not all CSS.
  • "Moving scripts to the bottom of body fixes blocking." It avoids parser blocking but creates a different problem: the browser doesn't discover those scripts until late, delaying execution. defer in the head is strictly better — early discovery, late execution.
  • "Preload eliminates render-blocking." Preload signals priority and starts the download earlier. It does not change whether the resource blocks rendering. A preloaded blocking stylesheet is still blocking — just faster to arrive.