Render-blocking CSS eliminated or inlined
Why it matters
A render-blocking stylesheet halts all HTML parsing and painting until the browser has fully downloaded and parsed the CSS file (ISO-25010 time-behaviour). On a 3G connection, a 145 KB uncompressed stylesheet can block rendering for 800–1200ms on its own. Tailwind's JIT output, bundled third-party component libraries, and global reset files are common offenders — they pull in styles for elements that are not in the initial viewport, making the user wait for CSS they do not need until the page scrolls.
Severity rationale
High because render-blocking CSS directly delays First Contentful Paint and LCP, and the penalty scales with file size and network conditions.
Remediation
Split CSS into critical (above-fold) and non-critical (below-fold). Inline critical styles and load the rest asynchronously in your root <head>:
<!-- Inline critical CSS — keep under 14 KB -->
<style>{criticalCSS}</style>
<!-- Defer non-critical stylesheet -->
<link rel="preload" as="style" href="/styles/non-critical.css"
onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles/non-critical.css"></noscript>
For print or conditional styles, use media attributes to prevent render blocking:
<link rel="stylesheet" href="/styles/print.css" media="print">
For Tailwind projects, verify your content array in tailwind.config.ts is not too broad — unused class purging is essential to keeping the output small.
Detection
-
ID:
render-blocking-css -
Severity:
high -
What to look for: Count all relevant instances and enumerate each. Check HTML source for
<link rel="stylesheet">tags withoutmediaattributes or withmedia="all"ormedia="screen". These block rendering. Also check for embedded<style>tags and their sizes. Look for critical CSS inlining patterns or<link rel="preload">withonloadhandlers for deferred styles. -
Pass criteria: Non-critical CSS is deferred via
mediaqueries or async loading patterns. Critical CSS (under 14KB) is inlined for above-fold content.<link rel="preload" as="style" href="...">used for async CSS loading. -
Fail criteria: All CSS is render-blocking (large monolithic stylesheet loaded synchronously), or no distinction between critical and non-critical CSS. Initial stylesheets exceed 20KB.
-
Skip (N/A) when: The project has no CSS or uses CSS-in-JS that doesn't produce external stylesheets.
-
Detail on fail: Specify the blocking stylesheet size. Example:
"main.css 145KB loaded render-blocking in <head>; media attribute not used. Critical CSS not identified or inlined"or"Tailwind CSS output 78KB not split; no critical/non-critical separation". -
Remediation: Non-critical CSS should not block rendering. Separate your CSS into critical (above-fold) and non-critical (below-fold):
<!-- Critical CSS inlined --> <style>{criticalCSS}</style> <!-- Non-critical CSS deferred --> <link rel="preload" as="style" href="non-critical.css" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="non-critical.css"></noscript>Or use
mediaattributes for print or non-essential styles:<link rel="stylesheet" href="print.css" media="print">
External references
- iso-25010:2011 · performance-efficiency.time-behaviour — Time Behaviour
Taxons
History
- 2026-04-18·v1.0.0·Initial import from performance-core·automated