[{"data":1,"prerenderedAt":1300},["ShallowReactive",2],{"page:\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages":3,"all-docs-nav":761},{"id":4,"title":5,"body":6,"breadcrumb":736,"dateModified":746,"datePublished":746,"description":747,"extension":748,"faq":749,"meta":754,"navigation":755,"path":756,"seo":757,"slug":12,"stem":758,"type":759,"__hash__":760},"content\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages\u002Findex.md","Fixing LCP on Text-Heavy Documentation Pages",{"type":7,"value":8,"toc":714},"minimark",[9,13,17,26,31,53,57,60,74,77,207,211,214,262,266,276,312,405,412,416,427,449,456,548,552,555,576,580,583,587,596,600,635,639,642,646,651,654,658,661,665,668,672,675,679],[10,11,5],"h1",{"id":12},"fixing-lcp-on-text-heavy-documentation-pages",[14,15,16],"p",{},"Most LCP advice is about images: preload the hero, compress it, give it high priority. Documentation pages often have no hero at all. Their largest element in the first viewport is the introductory paragraph, the H1 or a code block, and none of the image advice applies. Yet documentation sites regularly fail LCP on mobile, because text has its own set of blockers — and they are easier to fix than most teams expect.",[14,18,19,20,25],{},"This guide shows how to confirm that your LCP element is text, why the timing then depends almost entirely on TTFB and render delay, and how to remove the three usual culprits: slow HTML delivery, render-blocking CSS and web fonts. It is part of ",[21,22,24],"a",{"href":23},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002F","Largest Contentful Paint Optimization for Static Sites",".",[27,28,30],"h2",{"id":29},"prerequisites","Prerequisites",[32,33,34,38,45],"ul",{},[35,36,37],"li",{},"A documentation template with a slow LCP in field data or on a throttled Lighthouse run.",[35,39,40,41,25],{},"Chrome DevTools to confirm the LCP element and its breakdown — see ",[21,42,44],{"href":43},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Fmeasuring-lcp-subparts-with-devtools\u002F","Measuring LCP Subparts with DevTools",[35,46,47,48,52],{},"Access to the layout's ",[49,50,51],"code",{},"\u003Chead>"," and build pipeline.",[27,54,56],{"id":55},"confirm-the-element-is-text","Confirm the Element Is Text",[14,58,59],{},"Record a load in the DevTools Performance panel with a mobile profile and open the LCP insight. It names the element. On documentation pages it is usually one of three things: the first paragraph (often the largest, because paragraphs span the full column and several lines), a code block with a dark background, or the H1 on pages with a short intro.",[14,61,62,63,66,67,69,70,73],{},"In field data, the web-vitals attribution build's ",[49,64,65],{},"attribution.target"," gives the element's selector. Group LCP by selector for the docs template; if ",[49,68,14],{}," or ",[49,71,72],{},"pre"," dominates, the fixes below apply.",[14,75,76],{},"When the element is text, the LCP breakdown collapses to two parts: TTFB and render delay. There is no resource to discover or download, so every millisecond after the first byte is time the browser spent unable to paint the text.",[78,79,80,203],"figure",{},[81,82,89,90,89,94,89,98,89,105],"svg",{"viewBox":83,"role":84,"ariaLabelledBy":85,"xmlns":88},"0 0 760 260","img",[86,87],"ltx-split-title","ltx-split-desc","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[91,92,93],"title",{"id":86},"LCP breakdown for an image element and a text element",[95,96,97],"desc",{"id":87},"An image LCP of 2.4 seconds splits into TTFB, load delay, load duration and render delay. A text LCP of 2.4 seconds on a documentation page has only TTFB of 0.6 seconds and render delay of 1.8 seconds, which is spent waiting for CSS and a web font.",[99,100],"rect",{"x":101,"y":101,"width":102,"height":103,"fill":104},"0","760","260","#ffffff",[106,107,109,110,109,118,109,123,109,131,109,136,109,141,109,145,109,150,109,154,109,159,109,165,109,169,109,174,109,179,109,182,109,185,109,188,109,191,109,194,109,198,89],"g",{"style":108},"font-family:system-ui, sans-serif;font-size:12px","\n    ",[111,112,117],"text",{"x":113,"y":114,"fill":115,"style":116},"380","28","#1f2937","font-size:16px;font-weight:700;text-anchor:middle","Same 2.4 s LCP, different anatomy",[111,119,122],{"x":120,"y":121,"fill":115},"74","78","image element",[99,124],{"x":125,"y":126,"width":127,"height":128,"fill":129,"style":130},"160","62","130","26","#166a9e","fill-opacity:0.4",[99,132],{"x":133,"y":126,"width":134,"height":128,"fill":135,"style":130},"290","80","#d83b41",[99,137],{"x":138,"y":126,"width":139,"height":128,"fill":140,"style":130},"370","250","#3f6410",[99,142],{"x":143,"y":126,"width":134,"height":128,"fill":144,"style":130},"620","#6a4c93",[111,146,149],{"x":147,"y":148,"fill":115},"85","148","text element",[99,151],{"x":125,"y":152,"width":153,"height":128,"fill":129,"style":130},"132","135",[99,155],{"x":156,"y":152,"width":157,"height":128,"fill":144,"style":158},"295","405","fill-opacity:0.5",[111,160,164],{"x":161,"y":162,"fill":115,"style":163},"227","149","text-anchor:middle","TTFB",[111,166,168],{"x":167,"y":162,"fill":115,"style":163},"497","render delay: CSS, font, JS",[99,170],{"x":125,"y":171,"width":172,"height":173,"fill":129,"style":130},"190","14","12",[111,175,164],{"x":176,"y":177,"fill":115,"style":178},"180","200","font-size:11px",[99,180],{"x":181,"y":171,"width":172,"height":173,"fill":135,"style":130},"240",[111,183,184],{"x":103,"y":177,"fill":115,"style":178},"load delay",[99,186],{"x":187,"y":171,"width":172,"height":173,"fill":140,"style":130},"350",[111,189,190],{"x":138,"y":177,"fill":115,"style":178},"load duration",[99,192],{"x":193,"y":171,"width":172,"height":173,"fill":144,"style":158},"470",[111,195,197],{"x":196,"y":177,"fill":115,"style":178},"490","render delay",[111,199,202],{"x":113,"y":181,"fill":200,"style":201},"#556071","font-size:11px;text-anchor:middle","for text, anything after the first byte is time the page could not paint",[204,205,206],"figcaption",{},"Text LCP has no download to optimise; it has only blockers to remove.",[27,208,210],{"id":209},"fix-1-get-the-html-there-fast","Fix 1: Get the HTML There Fast",[14,212,213],{},"TTFB is the floor for text LCP. On a static site it should be low, but three things commonly inflate it:",[32,215,216,242,256],{},[35,217,218,222,223,69,226,229,230,233,234,237,238,25],{},[219,220,221],"strong",{},"HTML not cached at the edge."," Many CDN setups cache assets for a year but send HTML with ",[49,224,225],{},"Cache-Control: no-cache",[49,227,228],{},"max-age=0",", so every request goes to the origin. Cache HTML at the edge with a short ",[49,231,232],{},"s-maxage"," and ",[49,235,236],{},"stale-while-revalidate",", and purge on deploy. See ",[21,239,241],{"href":240},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fstale-while-revalidate-for-static-html\u002F","Stale-While-Revalidate for Static HTML",[35,243,244,247,248,251,252,255],{},[219,245,246],{},"Redirect chains."," A link to ",[49,249,250],{},"\u002Fdocs\u002Finstall"," that redirects to ",[49,253,254],{},"\u002Fdocs\u002Finstall\u002F"," and then to a versioned path costs a round trip each. Link to the final URL everywhere and make the canonical form the one the site generator emits.",[35,257,258,261],{},[219,259,260],{},"Large HTML documents."," Some docs pages ship 500 KB of HTML because of inline SVG sprites or huge navigation trees. The first paragraph cannot paint until the browser has parsed everything before it; move large blocks after the content or trim them.",[27,263,265],{"id":264},"fix-2-stop-css-from-blocking-the-first-paint","Fix 2: Stop CSS From Blocking the First Paint",[14,267,268,269,272,273,275],{},"Every ",[49,270,271],{},"\u003Clink rel=\"stylesheet\">"," in the ",[49,274,51],{}," blocks rendering until it has downloaded and parsed. Documentation themes often load three or four: the theme, a syntax highlighting theme, a search widget's styles and an icon font.",[277,278,279,289,306],"ol",{},[35,280,281,284,285,288],{},[219,282,283],{},"Inline what the first viewport needs."," For documentation layouts, the critical CSS — reset, layout grid, header, typography and code block basics — is usually 8–15 KB uncompressed. Inline it in a ",[49,286,287],{},"\u003Cstyle>"," element. If the whole stylesheet is under about 20 KB compressed, inlining all of it is simpler and fine.",[35,290,291,294,295,298,299,302,303,25],{},[219,292,293],{},"Load the rest without blocking."," Use ",[49,296,297],{},"\u003Clink rel=\"preload\" as=\"style\" onload=\"this.rel='stylesheet'\">"," with a ",[49,300,301],{},"\u003Cnoscript>"," fallback, or ",[49,304,305],{},"media=\"print\" onload=\"this.media='all'\"",[35,307,308,311],{},[219,309,310],{},"Drop styles the page does not use."," Search widget CSS can be loaded when search is opened; syntax highlighting CSS only on pages with code.",[78,313,314,402],{},[81,315,89,320,89,323,89,326,89,328],{"viewBox":316,"role":84,"ariaLabelledBy":317,"xmlns":88},"0 0 760 240",[318,319],"ltx-css-title","ltx-css-desc",[91,321,322],{"id":318},"First paint with blocking stylesheets and with inlined critical CSS",[95,324,325],{"id":319},"With four blocking stylesheets, first paint of the paragraph waits until the last one finishes at 1.6 seconds. With critical CSS inlined and the rest loaded asynchronously, the paragraph paints at 0.8 seconds, right after the HTML arrives.",[99,327],{"x":101,"y":101,"width":102,"height":181,"fill":104},[106,329,109,330,109,333,109,340,109,343,109,348,109,352,109,355,109,359,109,362,109,368,109,372,109,375,109,379,109,382,109,386,109,390,109,394,109,398,89],{"style":108},[111,331,332],{"x":113,"y":128,"fill":115,"style":116},"What the first paint waits for",[111,334,339],{"x":335,"y":336,"fill":337,"style":338},"30","58","#b32b30","font-weight:700","Four blocking stylesheets",[111,341,342],{"x":335,"y":134,"fill":115},"HTML",[99,344],{"x":345,"y":346,"width":347,"height":172,"fill":200,"style":158},"150","70","90",[111,349,351],{"x":335,"y":350,"fill":115},"100","theme.css, prism.css",[99,353],{"x":181,"y":347,"width":176,"height":172,"fill":135,"style":354},"fill-opacity:0.45",[111,356,358],{"x":335,"y":357,"fill":115},"120","search.css, icons.css",[99,360],{"x":181,"y":361,"width":139,"height":172,"fill":135,"style":354},"110",[363,364],"line",{"x1":365,"y1":366,"x2":365,"y2":127,"stroke":337,"style":367},"500","64","stroke-width:1.5px;stroke-dasharray:4 3",[111,369,371],{"x":370,"y":134,"fill":337},"506","paint 1.6 s",[111,373,374],{"x":335,"y":125,"fill":140,"style":338},"Critical CSS inlined",[111,376,378],{"x":335,"y":377,"fill":115},"182","HTML + inline style",[99,380],{"x":345,"y":381,"width":350,"height":172,"fill":200,"style":158},"172",[111,383,385],{"x":335,"y":384,"fill":115},"202","rest, non-blocking",[99,387],{"x":139,"y":388,"width":139,"height":172,"fill":129,"style":389},"192","fill-opacity:0.35",[363,391],{"x1":103,"y1":392,"x2":103,"y2":393,"stroke":140,"style":367},"166","212",[111,395,397],{"x":396,"y":377,"fill":140},"266","paint 0.8 s",[111,399,401],{"x":113,"y":400,"fill":200,"style":201},"232","throttled phone, cold cache; LCP element is the first paragraph",[204,403,404],{},"Inlined CSS arrives with the HTML, so nothing stands between the first byte and the first paint.",[14,406,407,408,25],{},"Details and generator-specific setups are in ",[21,409,411],{"href":410},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Feliminating-render-blocking-css-on-static-sites\u002F","Eliminating Render-Blocking CSS on Static Sites",[27,413,415],{"id":414},"fix-3-do-not-let-fonts-hide-text","Fix 3: Do Not Let Fonts Hide Text",[14,417,418,419,422,423,426],{},"With ",[49,420,421],{},"font-display: block"," or the default ",[49,424,425],{},"auto",", browsers hide text that uses a loading web font for up to three seconds. The LCP paragraph is invisible, so LCP waits for the font. This is the single biggest cause of slow text LCP on documentation sites that use a custom typeface.",[14,428,429,430,69,433,436,437,440,441,445,446,448],{},"Set ",[49,431,432],{},"font-display: swap",[49,434,435],{},"optional"," on every text face. With ",[49,438,439],{},"swap",", the paragraph paints immediately in the fallback, and that paint counts for LCP; the later re-render in the web font is not a new LCP candidate unless the text block grows. Pair it with a metric-matched fallback so the swap does not shift layout; see ",[21,442,444],{"href":443},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fmetric-matched-fallback-fonts-with-size-adjust\u002F","Metric-Matched Fallback Fonts with size-adjust",". With ",[49,447,435],{},", the font is used only if it arrives within about 100 ms, which keeps both LCP and CLS stable.",[14,450,451,452,25],{},"If you self-host fonts, preload the body regular weight so it usually arrives before first paint; see ",[21,453,455],{"href":454},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads\u002F","Preloading Fonts Without Double Downloads",[78,457,458,545],{},[81,459,89,464,89,467,89,470,89,473],{"viewBox":460,"role":84,"ariaLabelledBy":461,"xmlns":88},"0 0 760 270",[462,463],"ltx-fix-title","ltx-fix-desc",[91,465,466],{"id":462},"Text LCP as each fix is applied",[95,468,469],{"id":463},"Lab LCP on a throttled phone for a documentation page. Baseline 3.4 seconds. After caching HTML at the edge, 2.9 seconds. After inlining critical CSS, 2.2 seconds. After switching fonts from block to swap, 1.3 seconds.",[99,471],{"x":101,"y":101,"width":102,"height":472,"fill":104},"270",[106,474,109,475,109,478,109,484,109,487,109,493,109,497,109,502,109,506,109,510,109,513,109,516,109,521,109,526,109,529,109,534,109,539,109,542,89],{"style":108},[111,476,477],{"x":113,"y":114,"fill":115,"style":116},"Lab LCP after each fix, throttled phone (s)",[363,479],{"x1":480,"y1":481,"x2":482,"y2":481,"stroke":200,"style":483},"60","220","700","stroke-width:1.5px",[363,485],{"x1":480,"y1":125,"x2":482,"y2":125,"stroke":140,"style":486},"stroke-width:1px;stroke-dasharray:5 4",[111,488,492],{"x":489,"y":490,"fill":140,"style":491},"696","154","font-size:11px;text-anchor:end","good ≤ 2.5 s",[99,494],{"x":350,"y":495,"width":347,"height":496,"fill":135,"style":354},"56","164",[111,498,501],{"x":499,"y":500,"fill":115,"style":163},"145","50","3.4",[111,503,505],{"x":499,"y":504,"fill":200,"style":163},"238","baseline",[99,507],{"x":139,"y":134,"width":347,"height":508,"fill":509,"style":130},"140","#8a6d0f",[111,511,512],{"x":156,"y":120,"fill":115,"style":163},"2.9",[111,514,515],{"x":156,"y":504,"fill":200,"style":163},"+ edge-cached HTML",[99,517],{"x":518,"y":519,"width":347,"height":520,"fill":129,"style":130},"400","114","106",[111,522,525],{"x":523,"y":524,"fill":115,"style":163},"445","108","2.2",[111,527,528],{"x":523,"y":504,"fill":200,"style":163},"+ inline critical CSS",[99,530],{"x":531,"y":532,"width":347,"height":533,"fill":140,"style":158},"550","157","63",[111,535,538],{"x":536,"y":537,"fill":115,"style":163},"595","151","1.3",[111,540,541],{"x":536,"y":504,"fill":200,"style":163},"+ font-display swap",[111,543,544],{"x":113,"y":103,"fill":200,"style":201},"fixes applied cumulatively; LCP element was the first paragraph throughout",[204,546,547],{},"The font fix gave the largest single gain, and it was a one-word change.",[27,549,551],{"id":550},"fix-4-keep-javascript-out-of-the-way","Fix 4: Keep JavaScript Out of the Way",[14,553,554],{},"Client-rendered documentation — where the article body is fetched as JSON and rendered after hydration — puts the LCP paragraph behind the whole JavaScript bundle. Static site generators render content to HTML at build time, so this should not happen, but it creeps in through versioned-docs selectors, \"tabs for every language\" components that render nothing on the server, and content wrapped in client-only components. Check by disabling JavaScript in DevTools: the first paragraph must still appear.",[14,556,557,558,560,561,564,565,69,568,571,572,25],{},"Synchronous scripts in the ",[49,559,51],{}," are the other source. A theme toggle script that reads ",[49,562,563],{},"localStorage"," to avoid a flash of the wrong theme is fine if it is tiny and inline; an analytics tag or consent manager loaded synchronously is not. Move them to ",[49,566,567],{},"defer",[49,569,570],{},"async",", and consider the patterns in ",[21,573,575],{"href":574},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002F","Third-Party Script Performance on Static Sites",[27,577,579],{"id":578},"watch-the-element-change","Watch the Element Change",[14,581,582],{},"Text LCP has a quirk worth knowing: the largest element can change as the page loads. A cookie banner, a large code block that renders after syntax highlighting, or a callout that appears after hydration may become the new largest element and push LCP later. In DevTools the LCP insight shows the final candidate; in the trace, the timings track shows each candidate as it was recorded. If LCP jumps to a late element, either reserve that element's space in the initial HTML or keep it smaller than the first paragraph.",[27,584,586],{"id":585},"measured-impact","Measured Impact",[14,588,589,590,592,593,595],{},"A 3,500-page API documentation site built with Docusaurus had mobile LCP p75 of 3.3 seconds, with the first paragraph as the LCP element on 81% of views. The team made the HTML cacheable at the edge for five minutes with ",[49,591,236],{},", inlined 11 KB of critical CSS, set ",[49,594,432],{}," with metric-matched fallbacks for the two custom fonts, and deferred the consent manager. Field LCP p75 fell to 1.7 seconds within the 28-day window, CLS stayed at 0.03, and the \"poor LCP\" group in Search Console emptied.",[27,597,599],{"id":598},"pitfalls-rollback","Pitfalls & Rollback",[32,601,602,608,614,623,629],{},[35,603,604,607],{},[219,605,606],{},"Optimising images on a text-LCP page."," Check the element first; image work will not move a paragraph's LCP.",[35,609,610,613],{},[219,611,612],{},"Inlining too much CSS."," Inlined CSS is not cached separately and is re-sent with every page; keep it to what the first viewport needs.",[35,615,616,622],{},[219,617,618,621],{},[49,619,620],{},"font-display: optional"," with no preload."," Text is fast but readers rarely see the brand font on first visit.",[35,624,625,628],{},[219,626,627],{},"Theme scripts that block."," Keep the pre-paint theme script under 1 KB and inline.",[35,630,631,634],{},[219,632,633],{},"Rollback:"," each fix is independent and reversible in the layout template.",[27,636,638],{"id":637},"conclusion","Conclusion",[14,640,641],{},"When the largest element is text, LCP is TTFB plus render delay, and render delay is almost always CSS, fonts or JavaScript standing between the HTML and the first paint. Cache the HTML at the edge, inline the critical CSS, make every text font swap or optional, and keep content rendering off the client. Documentation sites that do all four routinely reach LCP well under two seconds on mobile without touching a single image.",[27,643,645],{"id":644},"faq","FAQ",[647,648,650],"h3",{"id":649},"why-is-my-lcp-element-a-paragraph","Why is my LCP element a paragraph?",[14,652,653],{},"On pages without a large image in the first viewport, the largest visible block of text — often the first paragraph, a code block or the H1 — is the largest contentful element. Its size is the area of the text block, so a long intro paragraph frequently beats a heading.",[647,655,657],{"id":656},"what-slows-down-lcp-when-the-element-is-text","What slows down LCP when the element is text?",[14,659,660],{},"Everything that delays the first paint of that text - slow TTFB, render-blocking stylesheets, a web font with block-period rendering, and client-side JavaScript that renders or moves the content. There is no resource download for the element itself.",[647,662,664],{"id":663},"does-font-display-swap-help-text-lcp","Does font-display swap help text LCP?",[14,666,667],{},"Yes. With swap, text paints immediately in the fallback font and that paint counts for LCP. With block or auto, text is invisible for up to three seconds while the font loads, and LCP waits for it.",[647,669,671],{"id":670},"should-i-inline-critical-css-on-documentation-pages","Should I inline critical CSS on documentation pages?",[14,673,674],{},"For small stylesheets, inlining the whole thing is simplest and removes the render-blocking request. For larger ones, inline the CSS for the layout, header and typography, and load the rest without blocking render.",[27,676,678],{"id":677},"related","Related",[32,680,681,690,695,700,707],{},[35,682,683,686,687,689],{},[219,684,685],{},"Parent:"," ",[21,688,24],{"href":23}," — every LCP fix in one place.",[35,691,692,694],{},[21,693,44],{"href":43}," — confirming the element and breakdown.",[35,696,697,699],{},[21,698,411],{"href":410}," — critical CSS in each generator.",[35,701,702,706],{},[21,703,705],{"href":704},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap\u002F","font-display: optional vs swap"," — choosing the descriptor.",[35,708,709,713],{},[21,710,712],{"href":711},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002F","Docs Frameworks: Docusaurus, Starlight and VitePress"," — how the docs frameworks compare on defaults.",{"title":715,"searchDepth":716,"depth":716,"links":717},"",2,[718,719,720,721,722,723,724,725,726,727,728,735],{"id":29,"depth":716,"text":30},{"id":55,"depth":716,"text":56},{"id":209,"depth":716,"text":210},{"id":264,"depth":716,"text":265},{"id":414,"depth":716,"text":415},{"id":550,"depth":716,"text":551},{"id":578,"depth":716,"text":579},{"id":585,"depth":716,"text":586},{"id":598,"depth":716,"text":599},{"id":637,"depth":716,"text":638},{"id":644,"depth":716,"text":645,"children":729},[730,732,733,734],{"id":649,"depth":731,"text":650},3,{"id":656,"depth":731,"text":657},{"id":663,"depth":731,"text":664},{"id":670,"depth":731,"text":671},{"id":677,"depth":716,"text":678},[737,740,743,744],{"name":738,"item":739},"Home","\u002F",{"name":741,"item":742},"Performance Optimization & Core Web Vitals for SSGs","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002F",{"name":24,"item":23},{"name":5,"item":745},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages\u002F","2026-09-18","When the LCP element is a paragraph or heading, images are not the problem. Fix TTFB, render-blocking CSS and web fonts to speed up text-heavy docs pages.","md",[750,751,752,753],{"q":650,"a":653},{"q":657,"a":660},{"q":664,"a":667},{"q":671,"a":674},{},true,"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages",{"title":5,"description":747},"performance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages\u002Findex","article","ggtGjr9oIBNSmtfI_UZu1j2AR4BOsp-SNTWqqWem6tM",[762,765,768,771,774,777,780,783,786,788,791,794,797,800,803,806,809,812,815,818,821,824,827,830,833,836,839,842,845,848,851,854,857,860,863,866,869,872,875,878,881,884,887,890,893,896,899,902,905,908,911,914,917,920,923,926,929,932,935,938,940,943,946,949,952,955,958,961,963,966,968,970,973,976,979,982,985,988,991,994,997,1000,1003,1006,1009,1012,1015,1018,1020,1021,1023,1025,1028,1031,1034,1037,1040,1043,1046,1049,1052,1055,1058,1061,1064,1067,1070,1073,1075,1078,1081,1084,1087,1090,1093,1096,1099,1102,1105,1108,1111,1114,1117,1120,1123,1126,1129,1132,1135,1138,1141,1144,1147,1150,1153,1156,1159,1162,1165,1168,1171,1174,1177,1180,1183,1186,1189,1192,1195,1198,1201,1204,1207,1210,1213,1216,1219,1222,1225,1228,1231,1234,1237,1240,1243,1246,1249,1252,1255,1258,1261,1264,1267,1270,1273,1276,1279,1282,1285,1288,1291,1294,1297],{"path":763,"title":764},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fastro-vs-eleventy-build-times-at-10000-pages","Astro vs Eleventy Build Times at 10,000 Pages",{"path":766,"title":767},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fchoosing-between-astro-and-eleventy-for-large-docs","Astro vs Eleventy for Large Docs (1000+ Pages)",{"path":769,"title":770},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fcontent-collections-vs-eleventy-data-cascade","Content Collections vs the Eleventy Data Cascade",{"path":772,"title":773},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites","Astro vs Eleventy for Documentation Sites",{"path":775,"title":776},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fshortcodes-vs-components-for-docs-authors","Shortcodes vs Components for Docs Authors",{"path":778,"title":779},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fsidebar-navigation-in-astro-and-eleventy","Sidebar Navigation in Astro and Eleventy",{"path":781,"title":782},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fcustomizing-starlight-without-forking-the-theme","Customizing Starlight Without Forking the Theme",{"path":784,"title":785},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fdocusaurus-vs-starlight-for-product-documentation","Docusaurus vs Starlight for Product Documentation",{"path":787,"title":712},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress",{"path":789,"title":790},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmdx-vs-markdoc-for-docs-content","MDX vs Markdoc for Docs Content",{"path":792,"title":793},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-from-mkdocs-to-starlight","Migrating from MkDocs to Starlight",{"path":795,"title":796},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioned-documentation-with-docusaurus","Versioned Documentation with Docusaurus",{"path":798,"title":799},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-for-library-documentation","VitePress for Library Documentation",{"path":801,"title":802},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhow-to-benchmark-hugo-vs-astro-build-speeds","How to Benchmark Hugo vs Astro Build Speeds",{"path":804,"title":805},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhugo-partialcached-for-faster-builds","Hugo partialCached for Faster Builds",{"path":807,"title":808},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories","Hugo Build Times for Large Repositories",{"path":810,"title":811},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fprofiling-hugo-templates-with-template-metrics","Profiling Hugo Templates With Template Metrics",{"path":813,"title":814},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Freducing-hugo-memory-usage-on-ci-runners","Reducing Hugo Memory Usage on CI Runners",{"path":816,"title":817},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fspeeding-up-hugo-builds-with-render-hooks-and-caching","Speeding Up Hugo Builds with Render Hooks & Caching",{"path":819,"title":820},"\u002Fchoosing-the-right-static-site-generator-for-production","Choosing the Right Static Site Generator for Production",{"path":822,"title":823},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Feleventy-vs-jekyll-for-markdown-heavy-blogs","Eleventy vs Jekyll for Markdown-Heavy Blogs",{"path":825,"title":826},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem","Jekyll Plugin Ecosystem",{"path":828,"title":829},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Freplacing-jekyll-plugins-when-migrating-to-eleventy","Replacing Jekyll Plugins When Migrating to Eleventy",{"path":831,"title":832},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Frunning-jekyll-on-github-pages-without-plugins","Running Jekyll on GitHub Pages Without Plugins",{"path":834,"title":835},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fspeeding-up-slow-jekyll-builds","Speeding Up Slow Jekyll Builds",{"path":837,"title":838},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fupgrading-jekyll-and-ruby-versions-safely","Upgrading Jekyll and Ruby Versions Safely",{"path":840,"title":841},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fconverting-front-matter-at-scale-during-migration","Converting Front Matter at Scale During Migration",{"path":843,"title":844},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators","Migrating Between Static Site Generators",{"path":846,"title":847},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fkeeping-redirects-working-after-an-ssg-migration","Keeping Redirects Working After an SSG Migration",{"path":849,"title":850},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-a-docs-site-from-jekyll-to-hugo","Migrating a Docs Site From Jekyll to Hugo",{"path":852,"title":853},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-gatsby-to-astro","Migrating from Gatsby to Astro",{"path":855,"title":856},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-hugo-to-astro-without-breaking-urls","Migrating From Hugo to Astro Without Breaking URLs",{"path":858,"title":859},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-wordpress-to-a-static-site-generator","Migrating WordPress to a Static Site Generator",{"path":861,"title":862},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fporting-shortcodes-and-includes-between-generators","Porting Shortcodes and Includes Between Generators",{"path":864,"title":865},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fhandling-dynamic-routes-in-nextjs-static-export","Handling Dynamic Routes in Next.js Static Export",{"path":867,"title":868},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites","Next.js Static Export for Content Sites",{"path":870,"title":871},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fmigrating-from-gatsby-to-nextjs-static-export","Migrating from Gatsby to Next.js Static Export",{"path":873,"title":874},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-app-router-static-export-limitations","Next.js App Router Static Export Limitations",{"path":876,"title":877},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-static-export-vs-astro-for-marketing-sites","Next.js Static Export vs Astro for Marketing",{"path":879,"title":880},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Foptimizing-images-in-nextjs-static-export","Optimizing Images in Next.js Static Export",{"path":882,"title":883},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fadding-pagefind-to-an-astro-site","Adding Pagefind to an Astro Site",{"path":885,"title":886},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fbuilding-a-lunr-index-at-build-time-in-eleventy","Building a Lunr Index at Build Time in Eleventy",{"path":888,"title":889},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites","Search for Static Sites",{"path":891,"title":892},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Findexing-hugo-sites-with-pagefind","Indexing Hugo Sites with Pagefind",{"path":894,"title":895},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fmultilingual-search-on-static-sites","Multilingual Search on Static Sites",{"path":897,"title":898},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-algolia-docsearch","Pagefind vs Algolia DocSearch",{"path":900,"title":901},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fsearch-index-size-budgets-for-large-docs","Search Index Size Budgets for Large Docs",{"path":903,"title":904},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fbest-ssg-for-technical-writers-without-coding-experience","Best SSG for Non-Developer Technical Writers",{"path":906,"title":907},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fchoosing-an-ssg-for-api-reference-documentation","Choosing an SSG for API Reference Documentation",{"path":909,"title":910},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fevaluating-ssg-accessibility-defaults","Evaluating SSG Accessibility Defaults",{"path":912,"title":913},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix","SSG Framework Selection Matrix",{"path":915,"title":916},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fpicking-an-ssg-for-a-multi-language-documentation-site","Picking an SSG for a Multi-Language Docs Site",{"path":918,"title":919},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fssg-selection-checklist-for-engineering-teams","SSG Selection Checklist for Engineering Teams",{"path":921,"title":922},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Ftotal-cost-of-ownership-for-static-site-generators","Total Cost of Ownership for Static Site Generators",{"path":924,"title":925},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-busting-with-content-hashed-filenames","Cache Busting with Content-Hashed Filenames",{"path":927,"title":928},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs","CDN Caching Rules for SSGs",{"path":930,"title":931},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fpurging-the-cdn-cache-after-a-static-deploy","Purging the CDN Cache After a Static Deploy",{"path":933,"title":934},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fsetting-cache-control-headers-on-cloudflare-pages","Cache-Control Headers on Cloudflare Pages",{"path":936,"title":937},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fsetting-up-proper-cache-headers-on-netlify","Proper Cache Headers on Netlify for SSGs",{"path":939,"title":241},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fstale-while-revalidate-for-static-html",{"path":941,"title":942},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Feliminating-layout-shift-from-web-fonts","Eliminating Layout Shift From Web Fonts",{"path":944,"title":945},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-cookie-banners","Fixing CLS from Cookie Banners",{"path":947,"title":948},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-late-loading-embeds","Fixing CLS From Late-Loading Embeds",{"path":950,"title":951},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-sticky-headers-and-anchor-links","Fixing CLS from Sticky Headers and Anchor Links",{"path":953,"title":954},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites","Cumulative Layout Shift Fixes for Static Sites",{"path":956,"title":957},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Fmeasuring-cls-in-the-field-with-web-vitals-js","Measuring CLS in the Field With web-vitals.js",{"path":959,"title":960},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Freserving-space-for-images-and-embeds-to-stop-layout-shift","Reserving Space for Images and Embeds",{"path":962,"title":705},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap",{"path":964,"title":965},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites","Font Loading Strategies for Static Sites",{"path":967,"title":444},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fmetric-matched-fallback-fonts-with-size-adjust",{"path":969,"title":455},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads",{"path":971,"title":972},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fself-hosting-google-fonts-to-eliminate-layout-shift","Self-Host Google Fonts to Eliminate Layout Shift",{"path":974,"title":975},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fsubsetting-variable-fonts-for-faster-first-render","Subsetting Variable Fonts for Faster First Render",{"path":977,"title":978},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fbuilding-an-image-cdn-pipeline-for-static-sites","Building an Image CDN Pipeline for Static Sites",{"path":980,"title":981},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fgenerating-open-graph-images-at-build-time","Generating Open Graph Images at Build Time",{"path":983,"title":984},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro","Image Optimization Pipelines in Astro",{"path":986,"title":987},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp","Lazy-Loading Images Without Hurting LCP",{"path":989,"title":990},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Foptimizing-webp-images-in-hugo-without-plugins","Optimizing WebP Images in Hugo Without Plugins",{"path":992,"title":993},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fresponsive-images-with-srcset-in-eleventy","Responsive Images with srcset in Eleventy",{"path":995,"title":996},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fserving-avif-with-fallbacks-on-static-sites","Serving AVIF With Fallbacks on Static Sites",{"path":998,"title":999},"\u002Fperformance-optimization-core-web-vitals-for-ssgs","Core Web Vitals Optimization for SSGs",{"path":1001,"title":1002},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance","Astro Islands vs Full Hydration Performance",{"path":1004,"title":1005},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro","Deferring Hydration with client:visible in Astro",{"path":1007,"title":1008},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fhow-to-reduce-bundle-size-in-eleventy-builds","How to Reduce Bundle Size in Eleventy Builds",{"path":1010,"title":1011},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering","JavaScript Hydration & Partial Rendering",{"path":1013,"title":1014},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fmeasuring-inp-on-static-sites-with-real-user-monitoring","Measuring INP on Static Sites with RUM",{"path":1016,"title":1017},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components","Replacing React Islands with Web Components",{"path":1019,"title":411},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Feliminating-render-blocking-css-on-static-sites",{"path":756,"title":5},{"path":1022,"title":24},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites",{"path":1024,"title":44},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Fmeasuring-lcp-subparts-with-devtools",{"path":1026,"title":1027},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Foptimizing-lcp-on-astro-with-priority-hints","Optimizing LCP on Astro with Priority Hints",{"path":1029,"title":1030},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Freducing-lcp-from-hero-images-on-static-sites","Reducing LCP from Hero Images on Static Sites",{"path":1032,"title":1033},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fcomparing-lab-and-field-data-with-crux","Comparing Lab and Field Data with CrUX",{"path":1035,"title":1036},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci","Performance Budgets and Lighthouse CI",{"path":1038,"title":1039},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Freducing-lighthouse-score-variance-in-ci","Reducing Lighthouse Score Variance in CI",{"path":1041,"title":1042},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Frunning-webpagetest-scripts-against-preview-deploys","Running WebPageTest Scripts Against Preview Deploys",{"path":1044,"title":1045},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fsetting-up-lighthouse-ci-for-a-static-site","Setting Up Lighthouse CI for a Static Site",{"path":1047,"title":1048},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Ftracking-bundle-size-per-pull-request","Tracking Bundle Size per Pull Request",{"path":1050,"title":1051},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fwriting-a-performance-budget-that-fails-builds","Writing a Performance Budget That Fails Builds",{"path":1053,"title":1054},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fauditing-unused-preloads","Auditing Unused Preloads",{"path":1056,"title":1057},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed","Resource Hints and Navigation Speed",{"path":1059,"title":1060},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Finstant-navigation-with-speculation-rules","Instant Navigation with Speculation Rules",{"path":1062,"title":1063},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fpreconnect-vs-dns-prefetch-on-static-sites","Preconnect vs DNS-Prefetch on Static Sites",{"path":1065,"title":1066},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro","Prefetching Links in Astro",{"path":1068,"title":1069},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fview-transitions-on-multi-page-static-sites","View Transitions on Multi-Page Static Sites",{"path":1071,"title":1072},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fauditing-third-party-scripts-with-lighthouse","Auditing Third-Party Scripts With Lighthouse",{"path":1074,"title":575},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites",{"path":1076,"title":1077},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Flazy-loading-youtube-embeds-on-static-sites","Lazy-Loading YouTube Embeds on Static Sites",{"path":1079,"title":1080},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Floading-google-tag-manager-without-hurting-inp","Loading Google Tag Manager Without Hurting INP",{"path":1082,"title":1083},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Frunning-third-party-scripts-in-a-web-worker-with-partytown","Running Third-Party Scripts in a Web Worker with Partytown",{"path":1085,"title":1086},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fself-hosting-analytics-to-cut-third-party-requests","Self-Hosting Analytics to Cut Third-Party Requests",{"path":1088,"title":1089},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fautomating-eleventy-deployments-with-cloudflare-pages","Automating Eleventy Deployments on Cloudflare Pages",{"path":1091,"title":1092},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages","Configuring Redirects on Cloudflare Pages",{"path":1094,"title":1095},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fcustom-domains-and-tls-on-cloudflare-pages","Custom Domains and TLS on Cloudflare Pages",{"path":1097,"title":1098},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fdeploying-hugo-to-cloudflare-pages-and-workers","Deploying Hugo to Cloudflare Pages and Workers",{"path":1100,"title":1101},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup","Cloudflare Pages Edge Caching Setup",{"path":1103,"title":1104},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fmigrating-from-cloudflare-pages-to-workers-static-assets","Migrating from Cloudflare Pages to Workers Static Assets",{"path":1106,"title":1107},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fchecking-links-in-pull-requests","Checking Links in Pull Requests",{"path":1109,"title":1110},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fdocs-as-code-review-workflow-for-writers","Docs-as-Code Review Workflow for Writers",{"path":1112,"title":1113},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Feditorial-checks-with-vale-in-ci","Editorial Checks with Vale in CI",{"path":1115,"title":1116},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams","Content Workflows for Documentation Teams",{"path":1118,"title":1119},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fscheduling-content-publication-with-cron-triggered-builds","Scheduling Content Publication With Cron-Triggered Builds",{"path":1121,"title":1122},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fwiring-a-headless-cms-to-a-static-build","Wiring a Headless CMS to a Static Build",{"path":1124,"title":1125},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fbuilding-astro-sites-with-github-actions","Building Astro Sites with GitHub Actions",{"path":1127,"title":1128},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fcaching-node-modules-in-github-actions-for-faster-ssg-builds","Caching node_modules in GitHub Actions",{"path":1130,"title":1131},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-github-pages-with-actions","Deploying to GitHub Pages with Actions",{"path":1133,"title":1134},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-multiple-environments-from-one-workflow","Deploying to Multiple Environments From One Workflow",{"path":1136,"title":1137},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fhow-to-set-up-github-actions-for-hugo-deployments","GitHub Actions for Hugo Deployments",{"path":1139,"title":1140},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds","GitHub Actions for Automated SSG Builds",{"path":1142,"title":1143},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fmatrix-builds-for-multi-site-monorepos","Matrix Builds for Multi-Site Monorepos",{"path":1145,"title":1146},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fcaching-hugo-builds-in-github-actions","Caching Hugo Builds in GitHub Actions",{"path":1148,"title":1149},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fenabling-incremental-builds-in-eleventy","Enabling Incremental Builds in Eleventy",{"path":1151,"title":1152},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fincremental-builds-in-astro-with-the-content-layer","Incremental Builds in Astro with the Content Layer",{"path":1154,"title":1155},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs","Incremental Builds and Build Caching for SSGs",{"path":1157,"title":1158},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fmeasuring-build-time-regressions-in-ci","Measuring Build-Time Regressions in CI",{"path":1160,"title":1161},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fremote-caching-with-turborepo-for-ssg-monorepos","Remote Caching with Turborepo for SSG Monorepos",{"path":1163,"title":1164},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fsharing-build-cache-across-ci-runners","Sharing Build Cache Across CI Runners",{"path":1166,"title":1167},"\u002Fproduction-ready-deployment-cicd-workflows","Production-Ready Deployment & CI\u002FCD for SSGs",{"path":1169,"title":1170},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops","Alerting on Cache Hit Ratio Drops",{"path":1172,"title":1173},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fbuilding-a-core-web-vitals-dashboard-from-rum-data","Building a Core Web Vitals Dashboard from RUM Data",{"path":1175,"title":1176},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fcrawling-for-broken-links-on-a-schedule","Crawling for Broken Links on a Schedule",{"path":1178,"title":1179},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production","Monitoring Static Sites in Production",{"path":1181,"title":1182},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge","Logging 404s at the Edge",{"path":1184,"title":1185},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fuptime-and-synthetic-checks-for-static-sites","Uptime and Synthetic Checks for Static Sites",{"path":1187,"title":1188},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-vercel-for-hugo-and-eleventy","Configuring Vercel for Hugo and Eleventy",{"path":1190,"title":1191},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies","Netlify vs Vercel Deployment Strategies",{"path":1193,"title":1194},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates","Netlify Build Hooks for Content Updates",{"path":1196,"title":1197},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-redirects-and-rewrites-for-static-sites","Netlify Redirects and Rewrites for Static Sites",{"path":1199,"title":1200},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fsetting-up-deploy-previews-on-netlify-for-every-pull-request","Netlify Deploy Previews for Every Pull Request",{"path":1202,"title":1203},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fvercel-isr-vs-static-generation-for-ssgs","Vercel ISR vs Static Generation for SSGs",{"path":1205,"title":1206},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fautomating-preview-deploy-pipelines-with-github-actions","Automating Preview Deploy Pipelines with GitHub Actions",{"path":1208,"title":1209},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments","Cleaning Up Stale Preview Deployments",{"path":1211,"title":1212},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests","Preview Environments for Pull Requests",{"path":1214,"title":1215},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpassword-protecting-preview-deployments","Password-Protecting Preview Deployments",{"path":1217,"title":1218},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreviewing-headless-cms-drafts","Previewing Headless CMS Drafts",{"path":1220,"title":1221},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fvisual-regression-testing-on-preview-deploys","Visual Regression Testing on Preview Deploys",{"path":1223,"title":1224},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads","Atomic Deploys vs Incremental Uploads",{"path":1226,"title":1227},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fcanary-releases-for-static-sites","Canary Releases for Static Sites",{"path":1229,"title":1230},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Ffeature-flags-on-static-sites","Feature Flags on Static Sites",{"path":1232,"title":1233},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites","Rollbacks and Deploy Safety for Static Sites",{"path":1235,"title":1236},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frolling-back-a-bad-static-deploy-in-under-a-minute","Rolling Back a Bad Static Deploy in Under a Minute",{"path":1238,"title":1239},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frunning-smoke-tests-against-a-preview-url","Running Smoke Tests Against a Preview URL",{"path":1241,"title":1242},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fauditing-npm-dependencies-in-ssg-pipelines","Auditing npm Dependencies in SSG Pipelines",{"path":1244,"title":1245},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fenabling-hsts-and-preload-safely","Enabling HSTS and Preload Safely",{"path":1247,"title":1248},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fhash-based-csp-for-inline-scripts-in-astro","Hash-Based CSP for Inline Scripts in Astro",{"path":1250,"title":1251},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites","Security Headers and Hardening for Static Sites",{"path":1253,"title":1254},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc","Securing Deploy Credentials with GitHub OIDC",{"path":1256,"title":1257},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsubresource-integrity-for-third-party-assets","Subresource Integrity for Third-Party Assets",{"path":1259,"title":1260},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fwriting-a-content-security-policy-for-a-static-site","Writing a Content Security Policy for a Static Site",{"path":1262,"title":1263},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3","Clean URLs and Trailing Slashes on S3",{"path":1265,"title":1266},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects","CloudFront Functions for Redirects",{"path":1268,"title":1269},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fdeploying-a-static-site-to-s3-and-cloudfront","Deploying a Static Site to S3 and CloudFront",{"path":1271,"title":1272},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites","Self-Hosting Static Sites on S3, Nginx and Caddy",{"path":1274,"title":1275},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy","Serving a Static Site with Caddy",{"path":1277,"title":1278},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx","Serving a Static Site with Nginx",{"path":1280,"title":1281},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps","Zero-Downtime Deploys with Symlink Swaps",{"path":1283,"title":1284},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fadding-a-contact-form-with-cloudflare-workers","Adding a Contact Form with Cloudflare Workers",{"path":1286,"title":1287},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fhandling-form-submissions-on-a-static-site","Handling Form Submissions on a Static Site",{"path":1289,"title":1290},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites","Serverless Functions for Static Sites",{"path":1292,"title":1293},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers","Netlify Functions vs Cloudflare Workers",{"path":1295,"title":1296},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication","Protecting a Static Site Behind Authentication",{"path":1298,"title":1299},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fproxying-third-party-apis-from-an-edge-function","Proxying Third-Party APIs from an Edge Function",1789722847972]