WebTech1223411 logo WebTech1223411Web tech, read closely
Browsers

What Render Blocking Resources Are and How to Fix Them

Your page has a fast server, compressed images and a tidy bundle, yet users still stare at a white screen for a second and a half before anything appears.

A developer's monitor showing a browser performance timeline with colored bars and a blank white page loading beside it

Your page has a fast server, compressed images and a tidy bundle, yet users still stare at a white screen for a second and a half before anything appears. A performance audit flags "eliminate render blocking resources" and lists six files, but it does not explain why those files stop the browser from painting or which ones you can safely change.

This article walks through what the browser is waiting for during that blank second, how to identify the real culprits in DevTools, and the specific fixes that work for CSS, JavaScript and fonts. I will also explain why chasing a zero on that audit line can make the page feel worse.

What render blocking resources actually are

When the browser parses HTML, it builds the DOM. To paint anything, it also needs the CSSOM, the parsed form of every stylesheet that applies to the page. Render blocking resources are files the browser must fetch and process before it is willing to draw the first pixel.

Two kinds of file block by default:

  • Stylesheets in the head. Any link with rel="stylesheet" that applies to the current media blocks rendering until it has downloaded and parsed. The browser does this on purpose, because painting unstyled content and then restyling it would cause a jarring flash.
  • Synchronous scripts in the head. A plain script tag without async, defer or type="module" stops the HTML parser. The browser cannot continue building the DOM until the script downloads and runs, because the script might change the document.

Scripts also wait for any stylesheet above them, since a script may read computed styles. That chain is why one slow CSS file on a third-party domain can delay everything after it. If you want the bigger picture of what happens before this stage, see what happens between typing a URL and seeing a page.

How to find the files that block your first paint

  1. Open DevTools, go to the Performance panel, enable network throttling at a mid-range mobile profile, and record a page load.
  2. Find the First Contentful Paint marker. Everything that finishes downloading before it, and sits in the head, is a candidate.
  3. Switch to the Network panel and add the Priority column. Render blocking CSS usually shows as Highest priority.
  4. Look for long bars that start late. A stylesheet that only begins downloading after another file finishes points to a chain, often an @import inside CSS.

Our step-by-step guide to reading the DevTools network waterfall covers how to read those bars and gaps in detail. A typical finding on a content site: one main stylesheet of 90 KB, a font stylesheet from another origin, a cookie banner script and an analytics script all sitting in the head, adding 600 to 900 ms on a slow 4G connection.

Fixes for CSS, JavaScript and fonts

ResourceFixEffect
Main stylesheetInline critical CSS for above-the-fold content, load the rest normallyFirst paint no longer waits for the full file
Print or wide-screen CSSAdd a media attribute such as media="print"Downloaded at low priority, never blocks
CSS @import chainsReplace with separate link tagsFiles download in parallel instead of in sequence
App scriptsAdd defer, or use type="module"Parser keeps going, script runs after parsing
Independent third-party scriptsAdd asyncRuns when ready, does not block parsing
Third-party font CSSSelf-host fonts, preload the main file, use font-display: swapRemoves a cross-origin hop from the critical path

The difference between defer and async matters. Deferred scripts run in document order after the HTML is parsed, which is what most application code expects. Async scripts run as soon as they arrive, in any order, which suits analytics but can break code that depends on another library loading first.

Critical CSS should be small. Aim for under 14 KB compressed so it fits in the first round trip of a new connection. Inline only the rules needed for the header, navigation and the first visible block of content. Everything else can load from the normal stylesheet, which the browser will usually have cached on the next page view anyway, as explained in our piece on how browser caching decides what reloads.

Why removing every blocking stylesheet is the wrong goal

A popular trick is to load all CSS asynchronously: set the stylesheet's media to print and switch it to all once it loads. The audit warning disappears. What often appears instead is a flash of unstyled content followed by a layout jump, which hurts Cumulative Layout Shift and looks broken to users.

CSS blocks rendering for a good reason. The goal is not zero blocking resources but a short, fast critical path: as few blocking requests as possible, all on your own origin, and small enough to arrive quickly. One well-compressed 25 KB stylesheet served from the same domain is a perfectly healthy result, even if the audit still lists it.

The same caution applies to deferring everything. If your page renders content with JavaScript, deferring that script delays the content itself. Measure Largest Contentful Paint before and after rather than trusting the audit line.

A worked example from a real audit

A recipe site I reviewed recently had a First Contentful Paint of 2.4 seconds on a throttled mobile profile. The head contained a 110 KB theme stylesheet, a Google-hosted font stylesheet, a slider library script loaded synchronously, and a consent banner script.

We made four changes. The slider script got defer, since the slider sat below the fold anyway. The fonts were self-hosted with a preload for the single weight used in headings. About 9 KB of critical CSS was inlined, with the full stylesheet still linked normally. The consent script moved to async, after confirming it did not depend on anything else. First Contentful Paint dropped to 1.3 seconds, and layout shift stayed at zero because the main stylesheet still blocked as intended.

Nothing exotic was involved. Each change took under an hour, and the order mattered: fixing the synchronous script first gave the biggest single gain.

A quick checklist before you ship

  • No synchronous scripts in the head unless they truly must run before parsing, such as a tiny theme switcher that prevents a dark mode flash.
  • No @import inside CSS files on the critical path.
  • Fonts self-hosted or preconnected, with font-display set.
  • Third-party tags loaded async or after user interaction.
  • First Contentful Paint compared on a throttled profile before and after each change.

Frequently asked questions

Does defer make JavaScript non render blocking?

Yes. A script with defer downloads in parallel while the HTML parser continues, and runs only after parsing finishes. It no longer stops the browser from building the DOM or painting the first content.

Is inline CSS bad for performance?

Not in small amounts. Inlining a few kilobytes of critical CSS removes a network request from the critical path. Inlining an entire large stylesheet bloats every HTML response and prevents the browser from caching it separately.

Do images block rendering?

No. Images do not block the first paint, although a large hero image can delay Largest Contentful Paint. Only stylesheets, synchronous scripts and, indirectly, some font loading behaviour hold back the initial render.

MC
Maren Castellanos

Maren worked in cross-browser QA before editing, and knows the DevTools Network tab better than most people know their inbox. She writes about how browsers load and render pages and about the tools that show what is really happening.

More posts by Maren

More in Browsers

01doorganico 084goad 3hot8 4465456 after5internprogram ahandfulofblessings ahmadpc ahomcybersecurity allodialresources annodex antiquesandperiodcollectibles aotc asianworldkashmir beedlectrics bloggertemplatefree bluefeatheragency bodyweightsolution campaign08blog carfixadvisor catstreetcollective cbstvsports cnfanspurchasing committeeof500yearsofdignityandresistance covertopsdjs cs-kaiyuangame cuestacomunicaciontotal cxoutlet dancebetgame deskgearhub destinyvillastay detectmagazine di33 diamondsteelbuildings donmo dyanadropship emarsysfinance emimattl escapechan eskitarih evautoplay everythingweddings-orlando farmzone feedviewerapp foxstudiosscratch gamevui123 gleasongrade greetingsday hacklabasu haskell iw-kaiyun jagoanproperti jilidskripsi joltbusinessfinance juegodepokergratis juegospucca kaeru-festival latestmehndidesigns lestanzediottaviano litemagazines localcommunityhero lustrsazan mariashebets menswheels newwebstechs1 nikkit ootheday oxigenvpn plurfitness prefetial probudgetcarpetcleaning psychicmrsmartin pyaten qvantor rejoignezlogis rexzbot riselayouts ruchin rwxqsgd5 sakaltime shibiaowang shop-bot skrtips strcoding tetapatrium topselller uneplanteartificielle vipertechcr wo-kygaming yamaha-mekar yeknava yoybuysheets zenunwa yamaha-mekar jilidskripsi ankertoto ankertoto ankertoto ankertoto