Reference guide · performance · Published 2026-08-15 · 3 min read
Render-blocking CSS and JavaScript
Identify and remove render-blocking CSS and JavaScript: inline critical CSS, defer and async script loading, and preload the rest.
- ·What blocks paint
- ·Defer and async
- ·Preload and inline
What blocks paint
"Render-blocking resource" means a request the browser must wait for before it can draw the first frame. The critical rendering path shows the order: the browser parses the HTML into the DOM, builds the CSSOM from stylesheets, and can only paint a frame once both exist. Any CSS file named in the document is render-blocking by default, because the browser will not paint with the page unstyled. Synchronous JavaScript in the body is also render-blocking, because the parser cannot continue until it downloads, parses, and executes the script.
Lighthouse reports this as the "Eliminate render-blocking resources" audit and lists every blocking URL with its estimated savings. If that list is empty, the fix is already in place.
| Resource | Blocking by default | Removed by |
|---|---|---|
CSS via <link> | Yes | Inline critical CSS, load the rest async |
JS via <script> | Yes | defer or async |
| Preloadable image | No | Preload the hero, demote the rest |
| Fonts | No | Preload the display font |
The ordered fix list
Step 1: Inline the critical CSS
The CSS you need for first paint, layout of the hero and above-the-fold region, and the base typography, is small. Inline it in the <head>. The remaining stylesheet loads after first paint via a small loader that swaps it in once the page is idle. Keep the two in sync by building the inlined chunk from the same stylesheet source, never editing both by hand.
Step 2: Defer everything else
For every <script> that does not have to run before first paint, use defer. A deferred script downloads in parallel with parsing but executes only after the DOM is ready, so it never delays the first paint. If the script just needs a fast, non-blocking run and has no DOM dependency, async splits it into its own stream.
Step 3: Preload the LCP asset
The largest element waits. Preloading the hero image with fetchpriority="high" moves its download earlier, and it is the difference between a slow and a fast LCP. Do not preload everything at once; preloading is a budget, not a habit. The LCP optimisation route shows the exact check.
Step 4: Remove what blocks
Cut round trips from within the page: remove unused CSS rules and dead plugins rather than loading an unused bundle. Every link that survives in the head is a chance to block paint.
Verify
Run a fresh Lighthouse pass. The Eliminate render-blocking resources audit should drop below a handful of bytes and move no assets with a warning. The visual order that holds: first paint shows only the critical CSS, the rest of the stylesheet arrives after, and no script owns the first frame. This is the fast-path page structure that keeps LCP under 2.5 seconds as described in the fix order.