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.
High because render-blocking CSS directly delays First Contentful Paint and LCP, and the penalty scales with file size and network conditions.
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.
ID: performance-core.loading-resource-priority.render-blocking-css
Severity: high
What to look for: Count all relevant instances and enumerate each. Check HTML source for <link rel="stylesheet"> tags without media attributes or with media="all" or media="screen". These block rendering. Also check for embedded <style> tags and their sizes. Look for critical CSS inlining patterns or <link rel="preload"> with onload handlers for deferred styles.
Pass criteria: Non-critical CSS is deferred via media queries 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 media attributes for print or non-essential styles:
<link rel="stylesheet" href="print.css" media="print">