[{"data":1,"prerenderedAt":874},["ShallowReactive",2],{"content:\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css":3,"surroundings:\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css":866},{"id":4,"title":5,"body":6,"description":846,"extension":847,"meta":848,"navigation":476,"path":860,"seo":861,"stem":864,"__hash__":865},"content\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002Findex.md","Fixing LCP Render Delay from Render-Blocking CSS",{"type":7,"value":8,"toc":838},"minimark",[9,14,43,48,89,223,227,236,242,248,261,265,274,424,431,444,504,507,518,528,605,608,612,615,618,621,723,730,734,746,755,769,778,791,800,804,824,829,832,835],[10,11,13],"h1",{"id":12},"how-to-fix-lcp-render-delay-caused-by-render-blocking-css","How to Fix LCP Render Delay Caused by Render-Blocking CSS",[15,16,17,18,23,24,28,29,33,34,38,39,42],"p",{},"This walkthrough extends ",[19,20,22],"a",{"href":21},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F","Measuring LCP with Chrome DevTools"," inside ",[19,25,27],{"href":26},"\u002Fcore-web-vitals-measurement\u002F","Core Web Vitals & Measurement",". The signature is unmistakable once you know it: the hero image finishes downloading at ",[30,31,32],"code",{},"900ms",", and ",[19,35,37],{"href":36},"\u002Fcore-web-vitals-measurement\u002Funderstanding-core-web-vitals-thresholds\u002F","LCP"," is recorded at ",[30,40,41],{},"2.8s",". Nearly two seconds of the metric is spent with the pixels already in memory and nothing on screen. That gap is render delay, and when the resource is already there, the usual culprit is a stylesheet that blocks the first frame.",[44,45,47],"h2",{"id":46},"rapid-diagnosis-isolate-the-render-delay-phase","Rapid Diagnosis: Isolate the Render-Delay Phase",[49,50,51,59,77,83],"ul",{},[52,53,54,58],"li",{},[55,56,57],"strong",{},"Break LCP into its four phases."," Time to first byte, resource load delay, resource load time, render delay. If the last one is over half the total, this page is your case.",[52,60,61,64,65,68,69,72,73,76],{},[55,62,63],{},"Read the render-blocking column."," In the Network panel, enable the ",[55,66,67],{},"Blocking"," column; every ",[30,70,71],{},"\u003Clink rel=\"stylesheet\">"," in ",[30,74,75],{},"\u003Chead>"," will be marked as blocking.",[52,78,79,82],{},[55,80,81],{},"Check when the last blocking stylesheet completes."," Compare it against the LCP timestamp. If they are within a frame of each other, the CSS is defining your metric.",[52,84,85,88],{},[55,86,87],{},"Count the bytes that were needed."," The Coverage panel will usually show that 5–15% of the blocking CSS was used above the fold — the rest delayed the paint for nothing.",[90,91,98,99,106,107,106,111,106,115,106,124,106,131,106,136,106,144,106,151,106,155,106,159,106,164,106,168,106,175,106,180,106,184,106,188,106,191,106,194,106,196,106,198,106,200,106,202,106,204,106,208,106,212,106,218,106],"svg",{"xmlns":92,"viewBox":93,"width":94,"role":95,"ariaLabel":96,"style":97},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","0 0 760 236","100%","img","LCP broken into four phases before and after the fix, showing render delay shrinking from 1900 milliseconds to 300 while the other phases are unchanged","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)","\n  ",[100,101],"rect",{"className":102,"x":104,"y":104,"width":94,"height":94,"fill":105},[103],"svg-canvas","0","#ffffff"," ",[108,109,110],"title",{},"The four LCP phases, before and after unblocking CSS",[112,113,114],"desc",{},"Before the fix, time to first byte, load delay and load time total 900 milliseconds while render delay adds 1900; after, render delay falls to 300 and the other phases are unchanged.",[100,116],{"x":117,"y":117,"width":118,"height":119,"rx":120,"fill":121,"stroke":122,"style":123},"1","758","234","10","none","currentColor","stroke-opacity:0.18",[125,126,130],"text",{"x":127,"y":128,"fill":122,"style":129},"24","32","font-size:16px;font-weight:700","The metric is almost entirely one phase",[125,132,135],{"x":127,"y":133,"fill":122,"style":134},"76","font-size:11.5px;font-weight:700","Before",[100,137],{"x":138,"y":139,"width":140,"height":141,"rx":142,"fill":122,"stroke":122,"style":143},"100","58","60","28","3","fill-opacity:0.1;stroke-opacity:0.35",[125,145,150],{"x":146,"y":147,"fill":122,"style":148,"textAnchor":149},"130","77","font-size:10px;","middle","TTFB",[100,152],{"x":153,"y":139,"width":154,"height":141,"rx":142,"fill":122,"stroke":122,"style":143},"160","40",[125,156,158],{"x":157,"y":147,"fill":122,"style":148,"textAnchor":149},"180","delay",[100,160],{"x":161,"y":139,"width":140,"height":141,"rx":142,"fill":162,"stroke":162,"style":163},"200","#0466c8","fill-opacity:0.18;stroke-opacity:0.5",[125,165,167],{"x":166,"y":147,"fill":122,"style":148,"textAnchor":149},"230","load",[100,169],{"x":170,"y":139,"width":171,"height":141,"rx":142,"fill":172,"stroke":173,"style":174},"260","380","#ffc300","#b8860b","fill-opacity:0.3",[125,176,179],{"x":177,"y":147,"fill":122,"style":178,"textAnchor":149},"450","font-size:11px;font-weight:700;","render delay 1900ms",[125,181,41],{"x":182,"y":147,"fill":122,"style":183},"660","font-size:11px;font-weight:700",[125,185,187],{"x":127,"y":186,"fill":122,"style":134},"146","After",[100,189],{"x":138,"y":190,"width":140,"height":141,"rx":142,"fill":122,"stroke":122,"style":143},"128",[125,192,150],{"x":146,"y":193,"fill":122,"style":148,"textAnchor":149},"147",[100,195],{"x":153,"y":190,"width":154,"height":141,"rx":142,"fill":122,"stroke":122,"style":143},[125,197,158],{"x":157,"y":193,"fill":122,"style":148,"textAnchor":149},[100,199],{"x":161,"y":190,"width":140,"height":141,"rx":142,"fill":162,"stroke":162,"style":163},[125,201,167],{"x":166,"y":193,"fill":122,"style":148,"textAnchor":149},[100,203],{"x":170,"y":190,"width":140,"height":141,"rx":142,"fill":172,"stroke":173,"style":174},[125,205,207],{"x":206,"y":193,"fill":122,"style":148,"textAnchor":149},"290","300",[125,209,211],{"x":210,"y":193,"fill":122,"style":183},"336","1.2s",[213,214],"line",{"x1":127,"y1":215,"x2":216,"y2":215,"stroke":122,"style":217},"176","736","stroke-opacity:0.2",[125,219,222],{"x":127,"y":220,"fill":122,"style":221},"204","font-size:11.5px;fill-opacity:0.85","Nothing about the image changed. A smaller hero would not have helped this page at all.",[44,224,226],{"id":225},"root-cause-analysis","Root Cause Analysis",[15,228,229,232,233,235],{},[55,230,231],{},"1. CSS blocks the first paint by design."," The browser will not paint until it has a complete style sheet for the document, because painting with incomplete styles produces a flash of unstyled content. Every blocking stylesheet in ",[30,234,75],{}," therefore adds its full download and parse time to the first frame.",[15,237,238,241],{},[55,239,240],{},"2. One bundle for the whole site."," Most build setups emit a single CSS file containing every component's styles. The above-the-fold view needs a small fraction of it, but the browser cannot know that and waits for all of it.",[15,243,244,247],{},[55,245,246],{},"3. Third-party stylesheets on the critical path."," A font service, a design system CDN, or a consent tool adds an entire extra origin — DNS, TLS, then the file — before the first paint can happen. Removing them from the blocking set is often the single biggest win.",[15,249,250,257,258,260],{},[55,251,252,253,256],{},"4. ",[30,254,255],{},"@import"," inside a stylesheet."," An ",[30,259,255],{}," is discovered only after the parent file downloads and parses, so it serialises two round trips inside a resource that is already blocking. This is the worst-case CSS pattern for LCP.",[44,262,264],{"id":263},"step-by-step-resolution","Step-by-Step Resolution",[15,266,267,270,271,273],{},[55,268,269],{},"1. Inline the critical subset and defer the rest."," Extract the rules needed for the initial viewport, inline them in ",[30,272,75],{},", and load the full sheet without blocking.",[275,276,281],"pre",{"className":277,"code":278,"language":279,"meta":280,"style":280},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Cstyle>\u002F* critical: layout, header, hero, typography — under ~14KB *\u002F\u003C\u002Fstyle>\n\u003Clink rel=\"preload\" href=\"\u002Fcss\u002Fmain.css\" as=\"style\"\n      onload=\"this.rel='stylesheet'\">\n\u003Cnoscript>\u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Fmain.css\">\u003C\u002Fnoscript>\n\u003C!-- trade-off: inlined CSS is not cached separately, so repeat visitors\n     re-download it inside the HTML. Keep it small — past roughly 14KB the\n     inline block starts costing more on repeat views than it saves on first. -->\n","html","",[30,282,283,310,345,373,406,412,418],{"__ignoreMap":280},[284,285,287,291,295,298,302,305,307],"span",{"class":213,"line":286},1,[284,288,290],{"class":289},"saISM","\u003C",[284,292,294],{"class":293},"sZBmE","style",[284,296,297],{"class":289},">",[284,299,301],{"class":300},"sjfSM","\u002F* critical: layout, header, hero, typography — under ~14KB *\u002F",[284,303,304],{"class":289},"\u003C\u002F",[284,306,294],{"class":293},[284,308,309],{"class":289},">\n",[284,311,313,315,318,322,325,329,332,334,337,340,342],{"class":213,"line":312},2,[284,314,290],{"class":289},[284,316,317],{"class":293},"link",[284,319,321],{"class":320},"sPXB4"," rel",[284,323,324],{"class":289},"=",[284,326,328],{"class":327},"sZ8jY","\"preload\"",[284,330,331],{"class":320}," href",[284,333,324],{"class":289},[284,335,336],{"class":327},"\"\u002Fcss\u002Fmain.css\"",[284,338,339],{"class":320}," as",[284,341,324],{"class":289},[284,343,344],{"class":327},"\"style\"\n",[284,346,348,351,353,356,359,362,365,368,371],{"class":213,"line":347},3,[284,349,350],{"class":320},"      onload",[284,352,324],{"class":289},[284,354,355],{"class":327},"\"",[284,357,358],{"class":320},"this",[284,360,361],{"class":327},".",[284,363,364],{"class":289},"rel",[284,366,324],{"class":367},"sPARh",[284,369,370],{"class":327},"'stylesheet'\"",[284,372,309],{"class":289},[284,374,376,378,381,384,386,388,390,393,395,397,399,402,404],{"class":213,"line":375},4,[284,377,290],{"class":289},[284,379,380],{"class":293},"noscript",[284,382,383],{"class":289},">\u003C",[284,385,317],{"class":293},[284,387,321],{"class":320},[284,389,324],{"class":289},[284,391,392],{"class":327},"\"stylesheet\"",[284,394,331],{"class":320},[284,396,324],{"class":289},[284,398,336],{"class":327},[284,400,401],{"class":289},">\u003C\u002F",[284,403,380],{"class":293},[284,405,309],{"class":289},[284,407,409],{"class":213,"line":408},5,[284,410,411],{"class":300},"\u003C!-- trade-off: inlined CSS is not cached separately, so repeat visitors\n",[284,413,415],{"class":213,"line":414},6,[284,416,417],{"class":300},"     re-download it inside the HTML. Keep it small — past roughly 14KB the\n",[284,419,421],{"class":213,"line":420},7,[284,422,423],{"class":300},"     inline block starts costing more on repeat views than it saves on first. -->\n",[15,425,426,427,430],{},"Expected outcome: first paint no longer waits for the full stylesheet; render delay typically falls by the download-plus-parse time of the deferred file, often ",[30,428,429],{},"400–1200ms"," on mobile.",[15,432,433,439,440,443],{},[55,434,435,436,438],{},"2. Remove ",[30,437,255],{}," from blocking stylesheets."," Replace each one with a ",[30,441,442],{},"\u003Clink>"," in the document so the requests happen in parallel rather than in series.",[275,445,449],{"className":446,"code":447,"language":448,"meta":280,"style":280},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F* Before — serialised: main.css must parse before tokens.css is requested. *\u002F\n@import url(\"tokens.css\");\n\n\u002F* After — both discovered by the preload scanner at once. *\u002F\n\u002F* \u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Ftokens.css\">\n   \u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Fmain.css\"> *\u002F\n\u002F* trade-off: separate files mean more requests. On HTTP\u002F2 and HTTP\u002F3 that is\n   cheap; on a legacy HTTP\u002F1.1 origin it is not — check your protocol first. *\u002F\n","css",[30,450,451,456,472,478,483,488,493,498],{"__ignoreMap":280},[284,452,453],{"class":213,"line":286},[284,454,455],{"class":300},"\u002F* Before — serialised: main.css must parse before tokens.css is requested. *\u002F\n",[284,457,458,460,463,466,469],{"class":213,"line":312},[284,459,255],{"class":367},[284,461,462],{"class":320}," url",[284,464,465],{"class":289},"(",[284,467,468],{"class":327},"\"tokens.css\"",[284,470,471],{"class":289},");\n",[284,473,474],{"class":213,"line":347},[284,475,477],{"emptyLinePlaceholder":476},true,"\n",[284,479,480],{"class":213,"line":375},[284,481,482],{"class":300},"\u002F* After — both discovered by the preload scanner at once. *\u002F\n",[284,484,485],{"class":213,"line":408},[284,486,487],{"class":300},"\u002F* \u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Ftokens.css\">\n",[284,489,490],{"class":213,"line":414},[284,491,492],{"class":300},"   \u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Fmain.css\"> *\u002F\n",[284,494,495],{"class":213,"line":420},[284,496,497],{"class":300},"\u002F* trade-off: separate files mean more requests. On HTTP\u002F2 and HTTP\u002F3 that is\n",[284,499,501],{"class":213,"line":500},8,[284,502,503],{"class":300},"   cheap; on a legacy HTTP\u002F1.1 origin it is not — check your protocol first. *\u002F\n",[15,505,506],{},"Expected outcome: removes one full round trip from the blocking chain.",[15,508,509,512,513,517],{},[55,510,511],{},"3. Take third-party CSS off the critical path."," Load font and widget stylesheets asynchronously, as described in ",[19,514,516],{"href":515},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fpreloading-google-fonts-without-blocking-render\u002F","preloading Google Fonts without blocking render",", and preconnect the origins that remain.",[15,519,520,527],{},[55,521,522,523,526],{},"4. Scope stylesheets with ",[30,524,525],{},"media"," so only the relevant ones block."," A print stylesheet or a wide-viewport sheet should never delay a phone's first paint.",[275,529,531],{"className":277,"code":530,"language":279,"meta":280,"style":280},"\u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Fprint.css\" media=\"print\">\n\u003Clink rel=\"stylesheet\" href=\"\u002Fcss\u002Fwide.css\" media=\"(min-width: 900px)\">\n\u003C!-- trade-off: non-matching sheets are still downloaded, just at low priority\n     and without blocking. This reduces render delay, not bytes — pair it with\n     splitting if the byte count is the problem. -->\n",[30,532,533,562,590,595,600],{"__ignoreMap":280},[284,534,535,537,539,541,543,545,547,549,552,555,557,560],{"class":213,"line":286},[284,536,290],{"class":289},[284,538,317],{"class":293},[284,540,321],{"class":320},[284,542,324],{"class":289},[284,544,392],{"class":327},[284,546,331],{"class":320},[284,548,324],{"class":289},[284,550,551],{"class":327},"\"\u002Fcss\u002Fprint.css\"",[284,553,554],{"class":320}," media",[284,556,324],{"class":289},[284,558,559],{"class":327},"\"print\"",[284,561,309],{"class":289},[284,563,564,566,568,570,572,574,576,578,581,583,585,588],{"class":213,"line":312},[284,565,290],{"class":289},[284,567,317],{"class":293},[284,569,321],{"class":320},[284,571,324],{"class":289},[284,573,392],{"class":327},[284,575,331],{"class":320},[284,577,324],{"class":289},[284,579,580],{"class":327},"\"\u002Fcss\u002Fwide.css\"",[284,582,554],{"class":320},[284,584,324],{"class":289},[284,586,587],{"class":327},"\"(min-width: 900px)\"",[284,589,309],{"class":289},[284,591,592],{"class":213,"line":347},[284,593,594],{"class":300},"\u003C!-- trade-off: non-matching sheets are still downloaded, just at low priority\n",[284,596,597],{"class":213,"line":375},[284,598,599],{"class":300},"     and without blocking. This reduces render delay, not bytes — pair it with\n",[284,601,602],{"class":213,"line":408},[284,603,604],{"class":300},"     splitting if the byte count is the problem. -->\n",[15,606,607],{},"Expected outcome: on a phone, only the sheets that apply hold the frame.",[44,609,611],{"id":610},"verification","Verification",[15,613,614],{},"Re-record the load and read the phase breakdown again. Success is render delay dropping while TTFB, load delay and load time stay roughly the same — that is the proof the change did what you intended rather than something incidental.",[15,616,617],{},"Confirm nothing broke visually. Inlining a critical subset risks a flash of unstyled content if the subset is incomplete: load the page with the deferred stylesheet blocked in DevTools and check that the above-the-fold view still looks correct on its own.",[15,619,620],{},"Lock it in with an assertion that fails on blocking bytes rather than on the metric alone:",[275,622,626],{"className":623,"code":624,"language":625,"meta":280,"style":280},"language-json shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","{ \"ci\": { \"assert\": { \"assertions\": {\n  \"render-blocking-resources\": [\"error\", { \"maxNumericValue\": 150 }],\n  \"largest-contentful-paint\": [\"error\", { \"maxNumericValue\": 2500 }],\n  \"unused-css-rules\": [\"warn\", { \"maxNumericValue\": 40000 }]\n} } } }\n","json",[30,627,628,650,676,696,718],{"__ignoreMap":280},[284,629,630,633,636,639,642,644,647],{"class":213,"line":286},[284,631,632],{"class":289},"{ ",[284,634,635],{"class":293},"\"ci\"",[284,637,638],{"class":289},": { ",[284,640,641],{"class":293},"\"assert\"",[284,643,638],{"class":289},[284,645,646],{"class":293},"\"assertions\"",[284,648,649],{"class":289},": {\n",[284,651,652,655,658,661,664,667,670,673],{"class":213,"line":312},[284,653,654],{"class":293},"  \"render-blocking-resources\"",[284,656,657],{"class":289},": [",[284,659,660],{"class":327},"\"error\"",[284,662,663],{"class":289},", { ",[284,665,666],{"class":293},"\"maxNumericValue\"",[284,668,669],{"class":289},": ",[284,671,672],{"class":320},"150",[284,674,675],{"class":289}," }],\n",[284,677,678,681,683,685,687,689,691,694],{"class":213,"line":347},[284,679,680],{"class":293},"  \"largest-contentful-paint\"",[284,682,657],{"class":289},[284,684,660],{"class":327},[284,686,663],{"class":289},[284,688,666],{"class":293},[284,690,669],{"class":289},[284,692,693],{"class":320},"2500",[284,695,675],{"class":289},[284,697,698,701,703,706,708,710,712,715],{"class":213,"line":375},[284,699,700],{"class":293},"  \"unused-css-rules\"",[284,702,657],{"class":289},[284,704,705],{"class":327},"\"warn\"",[284,707,663],{"class":289},[284,709,666],{"class":293},[284,711,669],{"class":289},[284,713,714],{"class":320},"40000",[284,716,717],{"class":289}," }]\n",[284,719,720],{"class":213,"line":408},[284,721,722],{"class":289},"} } } }\n",[15,724,725,726,729],{},"The ",[30,727,728],{},"render-blocking-resources"," audit is the leading indicator: it will fail the moment someone adds a stylesheet back into the head, well before the LCP number drifts far enough to be noticed in the field.",[44,731,733],{"id":732},"faq","FAQ",[735,736,739,743],"details",{"className":737},[738],"faq-item",[740,741,742],"summary",{},"How much CSS should I inline?",[15,744,745],{},"Enough to render the initial viewport correctly and no more — in practice usually 6–14KB after minification. The upper bound matters because inlined CSS is re-sent with every HTML response and cannot be cached independently, so past a certain size you are trading a first-visit win for a repeat-visit loss. If your critical subset is much larger than this, the real problem is component styles leaking into the above-the-fold set.",[735,747,749,752],{"className":748},[738],[740,750,751],{},"Does deferring CSS cause a flash of unstyled content?",[15,753,754],{},"Only if the inlined critical subset is incomplete. The deferred sheet applies when it arrives, so anything styled solely by it will appear unstyled until then. Test by blocking the deferred file entirely and looking at the page: whatever looks wrong is missing from your critical subset. Below-the-fold content appearing unstyled briefly is harmless, since the user has not reached it.",[735,756,758,761],{"className":757},[738],[740,759,760],{},"My LCP element is text, not an image — does this still apply?",[15,762,763,764,768],{},"Yes, and often more strongly. A text LCP element cannot paint until both the CSS and any blocking font are resolved, so render delay is frequently the entire metric. Fix the CSS first, then check whether the font is adding its own block period — the two interact, and the ",[19,765,767],{"href":766},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002F","font loading workflow"," covers the second half.",[735,770,772,775],{"className":771},[738],[740,773,774],{},"How do I generate the critical subset reliably?",[15,776,777],{},"Extract it at build time from the rendered page rather than maintaining it by hand. Tooling that loads each template at a representative viewport and records the rules matched above the fold produces a subset that tracks your CSS automatically. The two things to get right are the viewport list — include a phone width, because that is where the metric is decided — and a guard that fails the build if the extracted subset exceeds your size ceiling.",[735,779,781,784],{"className":780},[738],[740,782,783],{},"Does HTTP\u002F2 push or Early Hints remove the need to inline?",[15,785,786,787,790],{},"Early Hints helps meaningfully; server push does not and is no longer supported. Sending the stylesheet's ",[30,788,789],{},"Link"," header during origin think time means the file is already downloading when the parser reaches it, which removes most of the discovery cost — but the sheet still blocks rendering once discovered. Inlining removes the round trip entirely. Use Early Hints for the deferred full stylesheet and inline the critical subset.",[735,792,794,797],{"className":793},[738],[740,795,796],{},"Is a CSS-in-JS setup affected by this?",[15,798,799],{},"Differently, and often worse. Runtime CSS-in-JS moves style generation into JavaScript, so the first paint waits for the bundle to parse and execute rather than for a stylesheet to download — the blocking resource has changed identity, not disappeared. Libraries that extract styles at build time behave like ordinary CSS and can be split and inlined the same way. Check which mode you are in before applying any of the fixes here.",[44,801,803],{"id":802},"related","Related",[49,805,806,811,818],{},[52,807,808,810],{},[19,809,22],{"href":21}," — the phase-by-phase diagnostic this fix depends on.",[52,812,813,817],{},[19,814,816],{"href":815},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fresource-hints-and-early-hints\u002F","Resource Hints & Early Hints"," — start the critical CSS download earlier once it is no longer blocking.",[52,819,820,823],{},[19,821,822],{"href":766},"Font Loading & Text Rendering Performance"," — the other common source of render delay on text-led pages.",[825,826,828],"script",{"type":827},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Fix LCP render delay caused by render-blocking CSS\",\n  \"description\": \"Identify render delay as the dominant LCP phase, inline the critical subset, remove serialised imports, take third-party stylesheets off the critical path, and scope sheets with media queries.\",\n  \"step\": [\n    { \"@type\": \"HowToStep\", \"position\": 1, \"name\": \"Inline critical CSS\", \"text\": \"Inline the above-the-fold rules and load the full stylesheet without blocking the first paint.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"position\": 2, \"name\": \"Remove CSS imports\", \"text\": \"Replace @import with parallel link elements so stylesheet requests are not serialised.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"position\": 3, \"name\": \"Unblock third-party CSS\", \"text\": \"Load font and widget stylesheets asynchronously and preconnect the origins they need.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"position\": 4, \"name\": \"Scope with media\", \"text\": \"Attach media attributes so only stylesheets relevant to the current viewport block rendering.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F#step-by-step-resolution\" }\n  ]\n}\n",[825,830,831],{"type":827},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Fix LCP Render Delay Caused by Render-Blocking CSS\",\n  \"description\": \"When the LCP resource has already downloaded but nothing has painted, the stylesheet is holding the frame. Split it, defer it, and verify the phase shrank.\",\n  \"datePublished\": \"2026-08-01\",\n  \"dateModified\": \"2026-08-01\",\n  \"author\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"publisher\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"mainEntityOfPage\": { \"@type\": \"WebPage\", \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F\" }\n}\n",[825,833,834],{"type":827},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    { \"@type\": \"ListItem\", \"position\": 1, \"name\": \"Home\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 2, \"name\": \"Core Web Vitals & Measurement\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 3, \"name\": \"Measuring LCP with Chrome DevTools\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 4, \"name\": \"Fixing LCP Render Delay from Render-Blocking CSS\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F\" }\n  ]\n}\n",[294,836,837],{},"html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":280,"searchDepth":312,"depth":312,"links":839},[840,841,842,843,844,845],{"id":46,"depth":312,"text":47},{"id":225,"depth":312,"text":226},{"id":263,"depth":312,"text":264},{"id":610,"depth":312,"text":611},{"id":732,"depth":312,"text":733},{"id":802,"depth":312,"text":803},"Diagnose the phase where the image has arrived but nothing is painted yet, and remove the stylesheet that is holding the frame.","md",{"slug":849,"type":850,"breadcrumb":851,"datePublished":859,"dateModified":859},"fixing-lcp-render-delay-from-render-blocking-css","article",[852,855,856,857],{"name":853,"url":854},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":858},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002F","2026-08-01","\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css",{"title":862,"description":863},"Fixing LCP Render Delay Caused by Render-Blocking CSS","When the LCP resource is downloaded but the element still hasn't painted, the stylesheet is the blocker. Split critical CSS, defer the rest, and verify the phase shrank.","core-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-render-delay-from-render-blocking-css\u002Findex","xbV0DMfFedB2aK49ggKQmpkuvXxNdmfcw9j710ChPtQ",[867,870],{"title":22,"path":868,"stem":869,"children":-1},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools","core-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Findex",{"title":871,"path":872,"stem":873,"children":-1},"Fix LCP Over 2.5s on React Apps","\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fhow-to-fix-lcp-over-25-seconds-on-react-apps","core-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fhow-to-fix-lcp-over-25-seconds-on-react-apps\u002Findex",1785622407043]