References

Beginner-friendly references for web development, with live, editable examples.

The HTML blocking attribute

Attribute
In short

The HTML blocking attribute, set to render, holds the first paint until the element's resource is ready. It works on external <script>, <style> and stylesheet or expect <link> elements added before the body exists. It has no effect in Firefox.

Overview

The HTML blocking attribute puts rendering on hold until the element's resource is ready. Its only value is render. It's valid on external <script> elements, on <style>, and on <link> when rel is stylesheet or expect.

Some elements block rendering without it. A stylesheet link, style element or classic script without async or defer is render-blocking when the parser creates it in the head.

The attribute matters for resources that wouldn't block otherwise, such as async, defer and module scripts, and scripts and styles added from JavaScript.

On <link rel="expect" href="#main" blocking="render">, the attribute waits for markup instead of a file. Rendering then holds until the element with id main has been parsed. With view transitions between pages, this makes sure that content renders consistently before the transition runs.

An element that blocks through the attribute stops blocking once it leaves the document or its value loses render. Only elements added before the body exists can block rendering. In parsed markup, that means the head, so put these tags there.

Syntax

<script async src="theme.js" blocking="render"></script>
<script type="module" src="app.js" blocking="render"></script>

Values

Value
render

Example

Live example
<script>
  let theme = 'light';
  try {
    theme = localStorage.getItem('theme') || 'light';
  } catch (e) {}
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = '/css/theme-' + theme + '.css';
  link.blocking = 'render';
  document.head.append(link);
</script>
<script async src="/js/layout.js" blocking="render"></script>

Best practices

  • Limit blocking="render" to a script or stylesheet the first view can't do without. Each one can hold the first paint, which waits for the slowest of them.
  • Make a render-blocking script async as well. The parser then keeps reading the HTML while the file downloads, and only painting waits.
  • Check that the href of a rel=expect link matches an id in the HTML. With no matching element, rendering waits until the whole document has been parsed.
  • Plan a usable first view without the attribute, since browsers without support ignore it and can paint before the resource arrives.

Frequently asked questions

When does rendering resume under blocking=render?
Rendering resumes under blocking=render once the script has run, the stylesheet is applied, or the load fails. A rel=expect link holds rendering until its target element is parsed, and the attribute on its own doesn't pause the parser.
What does Firefox do with blocking=render?
Firefox doesn't support the blocking attribute, so it adds no wait there. Chrome and Edge support it on script, link and style from version 105 and on rel=expect links from 124, and Safari has both from 18.2.
How long can blocking=render delay a page?
The blocking attribute holds rendering as long as the resource takes, up to a timeout each browser sets. In Chrome, for example, a render-blocking async script that takes 1.2 seconds to arrive delays the first paint by about 1.2 seconds.
Can script code set blocking=render?
Yes, set the element's blocking property to render, or call blocking.add('render'), before you insert the element into the head. Setting it on a stylesheet link that is already in the document doesn't hold rendering.
Can blocking=render depend on screen size?
Yes, on a link or style element, a media attribute makes the blocking apply only if its query matches. One use is blocking on less content for narrow screens, since less of the page is visible there at first.