blocking

Explicitly marks resources as render-blocking, preventing the browser from painting until they load. Gives developers direct control over what was previously an implicit browser behavior.

Overview

The blocking attribute gives developers explicit control over which resources must load before the browser performs its first paint. Previously, render-blocking behavior was implicit and varied by element type and position: stylesheets in <head> were render-blocking, scripts without async or defer were parser-blocking. The blocking attribute makes this behavior explicit and intentional.

The only supported value is render, which prevents the browser from rendering any content until the resource has loaded.

Values

ValueBehavior
renderBlock rendering until this resource has loaded and been processed

Applies to: <link>, <style>, <script>

Examples

Basic Usage

<!-- Explicitly render-blocking: browser will not paint until this loads --> <link rel="stylesheet" href="/css/critical.css" blocking="render" /> <!-- Render-blocking script: page waits for this before first paint --> <script src="/js/theme-init.js" blocking="render"></script> <!-- Render-blocking inline style --> <style blocking="render"> :root { --brand-color: #0066cc; } body { font-family: system-ui; } </style>

When to Use blocking="render"

  • Critical CSS: Stylesheets defining layout, colors, and typography that prevent a flash of unstyled content (FOUC) if missing.
  • Theme initialization: A small script that reads the user's theme preference and sets CSS custom properties before paint.
  • Design tokens: CSS custom property definitions that all other styles depend on.
  • Critical font faces: Font declarations that must be available before text renders to avoid layout shift.

blocking vs async/defer

These attributes control different things. async and defer control when scripts execute relative to HTML parsing. blocking controls whether the browser can paint before a resource loads. They can be combined.

<!-- RENDER-BLOCKING: controls when the page first paints --> <link rel="stylesheet" href="/css/critical.css" blocking="render" /> <!-- DEFER: controls when a script executes (after parsing) --> <!-- But the page CAN paint before this script runs --> <script src="/js/app.js" defer></script> <!-- ASYNC: controls when a script executes (as soon as ready) --> <!-- But the page CAN paint before this script runs --> <script src="/js/analytics.js" async></script> <!-- BOTH: render-blocking AND deferred execution --> <!-- Page waits for download, then defers execution until after parsing --> <script src="/js/framework.js" defer blocking="render"></script>

Practical Loading Strategy

Mark only the minimum set of resources as render-blocking. Every render-blocking resource adds to the time before first paint. Non-critical styles and scripts should load without blocking.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Blocking Strategy</title> <!-- Critical: must load before first paint to avoid FOUC --> <link rel="stylesheet" href="/css/tokens.css" blocking="render" /> <link rel="stylesheet" href="/css/layout.css" blocking="render" /> <script src="/js/theme-detect.js" blocking="render"></script> <!-- Non-critical: can load after first paint --> <link rel="stylesheet" href="/css/components.css" /> <script src="/js/app.js" defer></script> </head> <body> <h1>Visible only after critical resources load</h1> </body> </html>

Combining with Preload

Pair blocking="render" with <link rel="preload"> to start fetching critical resources as early as possible. The preload hint begins the download; the blocking attribute ensures the page waits for it.

<!-- Preload + blocking: fetch early AND block rendering --> <link rel="preload" href="/css/critical.css" as="style" /> <link rel="stylesheet" href="/css/critical.css" blocking="render" /> <!-- Preload a font that must be ready before first paint --> <link rel="preload" href="/fonts/heading.woff2" as="font" type="font/woff2" crossorigin /> <style blocking="render"> @font-face { font-family: 'Heading'; src: url('/fonts/heading.woff2') format('woff2'); font-display: block; } </style>

Limitations

  • Browser support: The blocking attribute is relatively new (Chrome 105+, Edge 105+). Firefox and Safari do not yet support it as of early 2026. In unsupported browsers, the attribute is ignored and the browser falls back to its default render-blocking heuristics.
  • Only "render" is defined: The spec allows for future blocking tokens, but currently only render is supported.
  • Performance tradeoff: Every render-blocking resource delays first paint. Overusing blocking="render" hurts Core Web Vitals (FCP, LCP). Only block rendering for resources that truly must be ready before the user sees anything.
  • Does not control execution order: For scripts, blocking="render" prevents painting but does not change execution timing. Combine with defer if you also need ordered execution after parsing.
  • No effect on body resources: Resources in <body> with blocking="render" may behave inconsistently. Place render-blocking resources in <head>.

See Also

  • async / defer — control script execution timing
  • loading — lazy loading and fetch priority
  • rel — preload and preconnect resource hints