Asynchronous loading CSS? You’re probably doing it wrong & doing the opposite of what you intend. Learn how to async CSS the right way!
The Quick & Dirty
The RIGHT way to async CSS using the print pattern:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">
The WRONG way to aync CSS using the preload pattern:
<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
Two Problems with the Preload Async CSS Pattern
Unlike script elements, there is no
defer attribute to simply apply to a link element. To counter this, clever developers came up with the preload pattern — though it does have it’s issues.
- It throws network priorities out of whack
- It blocks the HTML parser*
* Firefox has a way to avoid #2, but it affects every other browser.
Whatever you apply to it is gonna jump up the line to be downloaded. The use of
preload means that these stylesheets, assuming you’re making asynchronous because they aren’t critical, are given a very high priority by browsers — a little bit of the opposite effect. Check out the example below:
Don’t forget about critical CSS
The most effective ways to boost the time to Start Render is to make use of the Critical CSS pattern:
Identify all of the styles needed for Start Render (commonly the styles needed for everything above the fold), inline them in
<style> tags in the
<head> of your document, and asynchronously load the remaining stylesheet off of the Critical Path.
While this strategy is effective, it’s not simple: highly dynamic sites can be difficult to extract styles from, the process needs to be automated, we have to make assumptions about what above the fold even is, it’s hard to capture edge cases, and tooling still in its relative infancy. If you’re working with a large or legacy codebase, things get even more difficult…
Long story short…
- If you’re using the preload/polyfill pattern, switch to the print stylesheet pattern instead.
- If there’s external stylesheets that are being loading normally (that is, as a regular stylesheet link), move all inline scripts that you can above it in the markup.
- Inline your critical CSS for the fastest possible start render times.