When CSS Blocks: The Hidden Cost of Async Stylesheet Tricks

Tim Kadlec highlights a common but problematic pattern for loading non-critical CSS: the preload/polyfill approach. In this technique, stylesheets are loaded via preload and then switched back to regular stylesheets using their onload events. While meant to make stylesheets more asynchronous, it introduces two major issues:

  1. It raises the download priority of the stylesheet above all other assets.
  2. It blocks the HTML parser, thanks to the polyfill being an inline script.

Firefox has a clever workaround for the second problem, but every other browser suffers the consequence. Kadlec admits he’s never had success with such intricate browser-tricking methods, preferring the straightforward approach of stylesheets in the head and scripts at the end of the body. He notes that even Jetpack inserts an inline script into his <head> — albeit with an obfuscated type attribute that gets changed later, likely to avoid this exact blocking issue.

His recommendations for better performance:

  • If using loadCSS with the preload/polyfill pattern, switch to the print stylesheet pattern instead.
  • When loading external stylesheets normally, move any inline scripts above them in the markup whenever possible.
  • Inline critical CSS to achieve the fastest start render times.

The print pattern works like this:

<link rel="stylesheet" href="https://css-tricks.com/path/to/my.css" media="print" onload="this.media='all'">

Direct Link →