[{"data":1,"prerenderedAt":1332},["ShallowReactive",2],{"page:\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp":3,"all-docs-nav":790},{"id":4,"title":5,"body":6,"breadcrumb":765,"dateModified":775,"datePublished":775,"description":776,"extension":777,"faq":778,"meta":783,"navigation":784,"path":785,"seo":786,"slug":12,"stem":787,"type":788,"__hash__":789},"content\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp\u002Findex.md","Lazy-Loading Images Without Hurting LCP",{"type":7,"value":8,"toc":745},"minimark",[9,13,25,34,39,52,56,66,201,204,208,211,245,347,357,361,368,388,410,416,437,457,461,482,555,559,562,568,586,593,597,610,614,620,624,661,665,671,675,680,683,687,690,694,697,701,704,708,741],[10,11,5],"h1",{"id":12},"lazy-loading-images-without-hurting-lcp",[14,15,16,20,21,24],"p",{},[17,18,19],"code",{},"loading=\"lazy\""," is one attribute that can either save a page megabytes or cost it half a second of Largest Contentful Paint. Applied to images far down an article, it stops the browser downloading pictures nobody scrolls to. Applied to the hero image, it tells the browser to wait until layout is done before even requesting the most important file on the page. Because many image components and plugins make ",[17,22,23],{},"lazy"," the default, the second case is common on static sites.",[14,26,27,28,33],{},"This guide shows how lazy loading delays the LCP image, how to decide which images are eager, and how to wire that decision into Astro, Hugo and Eleventy templates so authors do not have to think about it. It is part of ",[29,30,32],"a",{"href":31},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002F","Image Optimization Pipelines in Astro",".",[35,36,38],"h2",{"id":37},"prerequisites","Prerequisites",[40,41,42,46,49],"ul",{},[43,44,45],"li",{},"A page template with a hero or lead image.",[43,47,48],{},"Field LCP data with element attribution, or a Lighthouse report that names the LCP element.",[43,50,51],{},"Access to your image component or shortcode.",[35,53,55],{"id":54},"why-a-lazy-hero-is-slow","Why a Lazy Hero Is Slow",[14,57,58,59,62,63,65],{},"With a normal ",[17,60,61],{},"\u003Cimg>",", the browser's preload scanner sees the tag while the HTML is still streaming and requests the image immediately, often before CSS has finished loading. With ",[17,64,19],{},", the browser must know where the image sits relative to the viewport, which it only knows after the CSS is loaded and layout is complete. The image request is therefore delayed until after render-blocking CSS, and it starts at a lower priority.",[67,68,69,197],"figure",{},[70,71,78,79,78,83,78,87,78,94],"svg",{"viewBox":72,"role":73,"ariaLabelledBy":74,"xmlns":77},"0 0 760 260","img",[75,76],"lzl-wf-title","lzl-wf-desc","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[80,81,82],"title",{"id":75},"Request timing of an eager and a lazy hero image",[84,85,86],"desc",{"id":76},"Two waterfalls. With an eager hero, the image request starts at 180 milliseconds, alongside the CSS, and LCP is at 1.4 seconds. With a lazy hero, the request waits until layout at 620 milliseconds and LCP is at 1.9 seconds.",[88,89],"rect",{"x":90,"y":90,"width":91,"height":92,"fill":93},"0","760","260","#ffffff",[95,96,98,99,98,107,98,114,98,118,98,126,98,130,98,136,98,140,98,145,98,152,98,157,98,162,98,165,98,168,98,171,98,174,98,177,98,182,98,187,98,192,78],"g",{"style":97},"font-family:system-ui, sans-serif;font-size:12px","\n    ",[100,101,106],"text",{"x":102,"y":103,"fill":104,"style":105},"380","28","#1f2937","font-size:16px;font-weight:700;text-anchor:middle","Hero image request timing, mobile, 4G",[100,108,113],{"x":109,"y":110,"fill":111,"style":112},"30","62","#3f6410","font-weight:700","Eager hero",[100,115,117],{"x":109,"y":116,"fill":104},"86","HTML",[88,119],{"x":120,"y":121,"width":122,"height":123,"fill":124,"style":125},"130","76","60","14","#556071","fill-opacity:0.5",[100,127,129],{"x":109,"y":128,"fill":104},"106","CSS",[88,131],{"x":132,"y":133,"width":134,"height":123,"fill":124,"style":135},"190","96","140","fill-opacity:0.35",[100,137,139],{"x":109,"y":138,"fill":104},"126","hero.avif",[88,141],{"x":132,"y":142,"width":143,"height":123,"fill":144,"style":125},"116","250","#166a9e",[146,147],"line",{"x1":148,"y1":149,"x2":148,"y2":150,"stroke":111,"style":151},"450","70","136","stroke-width:1.5px;stroke-dasharray:4 3",[100,153,156],{"x":154,"y":155,"fill":111},"456","84","LCP 1.4 s",[100,158,161],{"x":109,"y":159,"fill":160,"style":112},"164","#b32b30","loading=\"lazy\" hero",[100,163,117],{"x":109,"y":164,"fill":104},"188",[88,166],{"x":120,"y":167,"width":122,"height":123,"fill":124,"style":125},"178",[100,169,129],{"x":109,"y":170,"fill":104},"208",[88,172],{"x":132,"y":173,"width":134,"height":123,"fill":124,"style":135},"198",[100,175,139],{"x":109,"y":176,"fill":104},"228",[88,178],{"x":179,"y":180,"width":143,"height":123,"fill":181,"style":125},"350","218","#d83b41",[146,183],{"x1":184,"y1":185,"x2":184,"y2":186,"stroke":160,"style":151},"610","172","238",[100,188,191],{"x":189,"y":190,"fill":160},"616","186","LCP 1.9 s",[100,193,196],{"x":102,"y":194,"fill":124,"style":195},"252","font-size:11px;text-anchor:middle","the lazy request cannot start until CSS is parsed and layout places the image",[198,199,200],"figcaption",{},"The file is identical; only the request start moves, and LCP moves with it.",[14,202,203],{},"In Chrome's field data, pages that lazy-load their LCP image have a noticeably worse LCP at the 75th percentile than pages that do not. Lighthouse flags it with the audit \"Largest Contentful Paint image was lazily loaded\".",[35,205,207],{"id":206},"deciding-which-images-are-eager","Deciding Which Images Are Eager",[14,209,210],{},"The rule is simple to state: any image that can be in the initial viewport on any supported screen size is eager; everything else is lazy. In practice, templates make it predictable:",[40,212,213,224,230,236],{},[43,214,215,219,220,223],{},[216,217,218],"strong",{},"Article template:"," the hero or lead image is eager with ",[17,221,222],{},"fetchpriority=\"high\"",". Inline content images are lazy.",[43,225,226,229],{},[216,227,228],{},"Listing and index pages:"," the first row of cards is eager, later rows lazy. On a three-column grid that means the first three thumbnails.",[43,231,232,235],{},[216,233,234],{},"Homepage:"," the hero is eager with high priority; logos and feature images further down are lazy.",[43,237,238,241,242,244],{},[216,239,240],{},"Header logo:"," if it is an ",[17,243,61],{},", eager but normal priority. An inline SVG avoids the question entirely.",[67,246,247,344],{},[70,248,78,253,78,256,78,259,78,262],{"viewBox":249,"role":73,"ariaLabelledBy":250,"xmlns":77},"0 0 760 280",[251,252],"lzl-fold-title","lzl-fold-desc",[80,254,255],{"id":251},"Eager and lazy images on a listing page",[84,257,258],{"id":252},"A phone-sized page outline with a header logo, a hero image and a grid of cards. The fold line sits below the hero and the first row of cards. Logo and first row are eager, the hero is eager with high fetch priority, and the rows below the fold are lazy.",[88,260],{"x":90,"y":90,"width":91,"height":261,"fill":93},"280",[95,263,98,264,98,268,98,275,98,280,98,286,98,291,98,297,98,300,98,303,98,308,98,313,98,317,98,319,98,321,98,326,98,330,98,335,98,339,78],{"style":97},[100,265,267],{"x":102,"y":266,"fill":104,"style":105},"26","One template, three loading decisions",[88,269],{"x":270,"y":271,"width":272,"height":273,"rx":274,"fill":93,"stroke":124},"200","42","360","226","8",[88,276],{"x":277,"y":278,"width":122,"height":279,"fill":124,"style":135},"212","52","18",[88,281],{"x":277,"y":282,"width":283,"height":284,"fill":111,"style":285},"78","336","64","fill-opacity:0.3",[100,287,290],{"x":102,"y":288,"fill":104,"style":289},"114","text-anchor:middle","hero",[88,292],{"x":277,"y":293,"width":294,"height":295,"fill":111,"style":296},"150","104","44","fill-opacity:0.18",[88,298],{"x":299,"y":293,"width":294,"height":295,"fill":111,"style":296},"328",[88,301],{"x":302,"y":293,"width":294,"height":295,"fill":111,"style":296},"444",[146,304],{"x1":132,"y1":305,"x2":306,"y2":305,"stroke":181,"style":307},"202","570","stroke-width:1.5px;stroke-dasharray:6 4",[100,309,312],{"x":310,"y":311,"fill":160},"580","206","fold",[88,314],{"x":277,"y":315,"width":294,"height":295,"fill":144,"style":316},"210","fill-opacity:0.15",[88,318],{"x":299,"y":315,"width":294,"height":295,"fill":144,"style":316},[88,320],{"x":302,"y":315,"width":294,"height":295,"fill":144,"style":316},[100,322,325],{"x":323,"y":284,"fill":104,"style":324},"185","text-anchor:end","logo: eager",[100,327,329],{"x":328,"y":294,"fill":111,"style":112},"144","eager +",[100,331,334],{"x":332,"y":333,"fill":111,"style":112},"93","120","fetchpriority high",[100,336,338],{"x":128,"y":337,"fill":111},"176","first row: eager",[100,340,343],{"x":341,"y":342,"fill":144},"105","236","later rows: lazy",[198,345,346],{},"Base the fold on the smallest screen you support, then check it on desktop too.",[14,348,349,350,352,353,33],{},"Use ",[17,351,222],{}," on one image only. It raises that image above other images and non-critical scripts in the browser's queue. Marking several images high makes them compete with each other and with CSS; see ",[29,354,356],{"href":355},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Foptimizing-lcp-on-astro-with-priority-hints\u002F","Optimizing LCP on Astro with Priority Hints",[35,358,360],{"id":359},"wiring-it-into-templates","Wiring It Into Templates",[14,362,363,364,367],{},"The goal is that authors never set ",[17,365,366],{},"loading"," by hand. The template knows which image is the hero and passes the right attributes.",[14,369,370,373,374,377,378,381,382,377,384,387],{},[216,371,372],{},"Astro."," The ",[17,375,376],{},"\u003CImage>"," and ",[17,379,380],{},"\u003CPicture>"," components default to ",[17,383,19],{},[17,385,386],{},"decoding=\"async\"",". Override on the hero:",[389,390,395],"pre",{"className":391,"code":392,"language":393,"meta":394,"style":394},"language-astro shiki shiki-themes github-light github-dark","\u003CImage src={hero} alt={heroAlt} widths={[640, 960, 1280]}\n       sizes=\"100vw\" loading=\"eager\" fetchpriority=\"high\" \u002F>\n","astro","",[17,396,397,404],{"__ignoreMap":394},[398,399,401],"span",{"class":146,"line":400},1,[398,402,403],{},"\u003CImage src={hero} alt={heroAlt} widths={[640, 960, 1280]}\n",[398,405,407],{"class":146,"line":406},2,[398,408,409],{},"       sizes=\"100vw\" loading=\"eager\" fetchpriority=\"high\" \u002F>\n",[14,411,412,413,33],{},"For listing pages, pass the index into the card component and set ",[17,414,415],{},"loading={index \u003C 3 ? 'eager' : 'lazy'}",[14,417,418,421,422,425,426,429,430,433,434,33],{},[216,419,420],{},"Hugo."," In a render hook for Markdown images, ",[17,423,424],{},"layouts\u002F_default\u002F_markup\u002Frender-image.html",", default to lazy. In the single template, render the hero with ",[17,427,428],{},"loading=\"eager\" fetchpriority=\"high\""," explicitly. For list pages, use ",[17,431,432],{},"{{ if lt $index 3 }}eager{{ else }}lazy{{ end }}"," inside ",[17,435,436],{},"range",[14,438,439,442,443,446,447,449,450,452,453,33],{},[216,440,441],{},"Eleventy."," Set ",[17,444,445],{},"loading: 'lazy'"," in the image transform's default attributes, and put ",[17,448,428],{}," directly on the hero ",[17,451,61],{}," in the layout; the transform keeps attributes that are already present. See ",[29,454,456],{"href":455},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fresponsive-images-with-srcset-in-eleventy\u002F","Responsive Images with srcset in Eleventy",[35,458,460],{"id":459},"lazy-loading-and-layout-shift","Lazy Loading and Layout Shift",[14,462,463,464,377,467,470,471,474,475,477,478,33],{},"Lazy images must reserve space, or they cause layout shift when they load in as the reader scrolls. Every image component mentioned here writes ",[17,465,466],{},"width",[17,468,469],{},"height",", which gives the browser the aspect ratio before the file arrives. For CSS background images and iframes, set ",[17,472,473],{},"aspect-ratio"," in CSS. Iframes also accept ",[17,476,19],{},", which is the easiest win for embedded videos and maps; for YouTube, a click-to-load facade is better still — see ",[29,479,481],{"href":480},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Flazy-loading-youtube-embeds-on-static-sites\u002F","Lazy-Loading YouTube Embeds on Static Sites",[67,483,484,552],{},[70,485,78,490,78,493,78,496,78,499],{"viewBox":486,"role":73,"ariaLabelledBy":487,"xmlns":77},"0 0 760 240",[488,489],"lzl-res-title","lzl-res-desc",[80,491,492],{"id":488},"LCP and image bytes before and after correcting lazy loading",[84,494,495],{"id":489},"Two pairs of bars. Mobile LCP p75 fell from 2.8 seconds with a lazy hero to 2.1 seconds with an eager, high-priority hero. Image bytes for an average article view stayed at about 420 kilobytes because below-the-fold images remained lazy.",[88,497],{"x":90,"y":90,"width":91,"height":498,"fill":93},"240",[95,500,98,501,98,504,98,508,98,513,98,518,98,521,98,525,98,528,98,532,98,536,98,539,98,544,98,548,78],{"style":97},[100,502,503],{"x":102,"y":103,"fill":104,"style":105},"Article template, field data, four weeks each",[146,505],{"x1":122,"y1":132,"x2":506,"y2":132,"stroke":124,"style":507},"700","stroke-width:1.5px",[88,509],{"x":333,"y":282,"width":510,"height":511,"fill":181,"style":512},"80","112","fill-opacity:0.45",[100,514,517],{"x":515,"y":516,"fill":104,"style":289},"160","72","2.8 s",[88,519],{"x":520,"y":128,"width":510,"height":155,"fill":111,"style":125},"220",[100,522,524],{"x":92,"y":523,"fill":104,"style":289},"100","2.1 s",[100,526,527],{"x":315,"y":315,"fill":124,"style":289},"LCP p75, mobile",[88,529],{"x":530,"y":128,"width":510,"height":155,"fill":144,"style":531},"460","fill-opacity:0.4",[100,533,535],{"x":534,"y":523,"fill":104,"style":289},"500","418 KB",[88,537],{"x":538,"y":294,"width":510,"height":116,"fill":144,"style":531},"560",[100,540,543],{"x":541,"y":542,"fill":104,"style":289},"600","98","426 KB",[100,545,547],{"x":546,"y":315,"fill":124,"style":289},"550","image bytes per view",[100,549,551],{"x":102,"y":550,"fill":124,"style":195},"232","left bar in each pair: all images lazy; right bar: hero eager, the rest lazy",[198,553,554],{},"Making one image eager cost 8 KB per view and saved 700 ms of LCP.",[35,556,558],{"id":557},"placeholders-and-blur-up-effects","Placeholders and Blur-Up Effects",[14,560,561],{},"Low-quality placeholders — a tiny blurred version of the image shown until the real file loads — are popular, and they interact with lazy loading in two ways worth knowing.",[14,563,564,565,567],{},"First, a placeholder does not count as the LCP element's final paint unless it is the same element at the same size. If the placeholder is a CSS background and the real image is an ",[17,566,61],{}," that fades in, LCP is recorded when the real image paints. A fade-in animation that starts at zero opacity delays LCP further, because an element with zero opacity is not a candidate. Keep fades off the hero, or start them at a visible opacity.",[14,569,570,571,574,575,578,579,582,583,585],{},"Second, placeholder libraries that swap ",[17,572,573],{},"data-src"," into ",[17,576,577],{},"src"," with JavaScript are invisible to the preload scanner, so they behave like the worst possible lazy loading even when the image is above the fold. If you want a placeholder on the hero, use a CSS ",[17,580,581],{},"background-image"," with a small inline data URI on the wrapper and a normal eager ",[17,584,61],{}," inside it.",[14,587,588,589,592],{},"For images below the fold, placeholders are harmless and improve perceived speed on slow connections. The dominant colour of the image as a plain ",[17,590,591],{},"background-color"," is the cheapest version: a few bytes per image, no extra request and no JavaScript.",[35,594,596],{"id":595},"auditing-a-whole-site","Auditing a Whole Site",[14,598,599,600,602,603,605,606,33],{},"Checking templates by eye misses edge cases such as a page type whose first content block is an image. Automate it: run Lighthouse or a Playwright script across one URL per template and fail if the LCP element is an ",[17,601,61],{}," with ",[17,604,19],{},". In field data, the web-vitals attribution build reports the LCP element and its URL; group by template and check whether any template's LCP image has a long \"resource load delay\", which is the signature of lazy loading. The four LCP subparts are explained in ",[29,607,609],{"href":608},"\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,611,613],{"id":612},"measured-impact","Measured Impact",[14,615,616,617,619],{},"A 1,600-page Astro blog used the default ",[17,618,376],{}," component everywhere, so every hero was lazy. Setting the hero to eager with high fetch priority in the article layout — a two-line change — cut mobile LCP p75 from 2.8 to 2.1 seconds and moved the article template from \"needs improvement\" to \"good\" in Search Console. Image bytes per view rose by 8 KB on average because the hero was now fetched even when the reader left instantly.",[35,621,623],{"id":622},"pitfalls-rollback","Pitfalls & Rollback",[40,625,626,635,641,647,655],{},[43,627,628,634],{},[216,629,630,631,633],{},"A global ",[17,632,23],{}," default with no per-template override."," The most common cause; audit the layouts that render heroes.",[43,636,637,640],{},[216,638,639],{},"Lazy loading the logo in a sticky header."," It is always in view; load it eagerly or inline it.",[43,642,643,646],{},[216,644,645],{},"Carousels."," Only the first slide is visible; make it eager and lazy-load the rest.",[43,648,649,654],{},[216,650,651,652,33],{},"JavaScript lazy loaders with ",[17,653,573],{}," They hide the image from the preload scanner entirely; replace them with native loading.",[43,656,657,660],{},[216,658,659],{},"Rollback:"," revert the template change; nothing else depends on the attribute.",[35,662,664],{"id":663},"conclusion","Conclusion",[14,666,667,668,670],{},"Lazy loading is a saving for images below the fold and a delay for images above it. Decide per template, not per author: heroes and first-row images eager, one image with ",[17,669,222],{},", everything else lazy with explicit dimensions. Wire those rules into the Astro, Hugo or Eleventy templates and check the LCP element in CI, and the attribute will save bytes without costing LCP.",[35,672,674],{"id":673},"faq","FAQ",[676,677,679],"h3",{"id":678},"does-loading-lazy-hurt-lcp","Does loading lazy hurt LCP?",[14,681,682],{},"Only when it is applied to the image that becomes the LCP element, or to images above the fold. A lazy image is not requested until layout is complete and the browser knows it is near the viewport, which can add several hundred milliseconds to its load. Images below the fold are safe to lazy-load.",[676,684,686],{"id":685},"how-many-images-should-be-eager-on-a-page","How many images should be eager on a page?",[14,688,689],{},"Usually the first one or two images that can appear in the initial viewport, including the hero and a logo if it is an img element. Everything that starts below the fold on the smallest supported screen can be lazy.",[676,691,693],{"id":692},"should-i-use-fetchpriority-high-as-well-as-eager","Should I use fetchpriority high as well as eager?",[14,695,696],{},"For the single LCP image, yes. fetchpriority high moves it ahead of other images and scripts in the request queue. Use it on one image per page only; marking several images high priority cancels the benefit.",[676,698,700],{"id":699},"is-javascript-lazy-loading-still-needed","Is JavaScript lazy loading still needed?",[14,702,703],{},"Rarely. Native loading lazy is supported in all current browsers for images and iframes. JavaScript libraries are only needed for effects such as blur-up placeholders, and they should never be applied to the LCP image.",[35,705,707],{"id":706},"related","Related",[40,709,710,719,726,731,736],{},[43,711,712,715,716,718],{},[216,713,714],{},"Parent:"," ",[29,717,32],{"href":31}," — the full image pipeline.",[43,720,721,725],{},[29,722,724],{"href":723},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Freducing-lcp-from-hero-images-on-static-sites\u002F","Reducing LCP from Hero Images on Static Sites"," — the rest of the hero checklist.",[43,727,728,730],{},[29,729,356],{"href":355}," — fetchpriority in depth.",[43,732,733,735],{},[29,734,456],{"href":455}," — setting defaults in the transform.",[43,737,738,740],{},[29,739,609],{"href":608}," — spotting load delay.",[742,743,744],"style",{},"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);}",{"title":394,"searchDepth":406,"depth":406,"links":746},[747,748,749,750,751,752,753,754,755,756,757,764],{"id":37,"depth":406,"text":38},{"id":54,"depth":406,"text":55},{"id":206,"depth":406,"text":207},{"id":359,"depth":406,"text":360},{"id":459,"depth":406,"text":460},{"id":557,"depth":406,"text":558},{"id":595,"depth":406,"text":596},{"id":612,"depth":406,"text":613},{"id":622,"depth":406,"text":623},{"id":663,"depth":406,"text":664},{"id":673,"depth":406,"text":674,"children":758},[759,761,762,763],{"id":678,"depth":760,"text":679},3,{"id":685,"depth":760,"text":686},{"id":692,"depth":760,"text":693},{"id":699,"depth":760,"text":700},{"id":706,"depth":406,"text":707},[766,769,772,773],{"name":767,"item":768},"Home","\u002F",{"name":770,"item":771},"Performance Optimization & Core Web Vitals for SSGs","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002F",{"name":32,"item":31},{"name":5,"item":774},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp\u002F","2026-09-18","loading=\"lazy\" saves bytes below the fold but delays the LCP image when applied to it. How to decide per image, per template, in Astro, Hugo and Eleventy.","md",[779,780,781,782],{"q":679,"a":682},{"q":686,"a":689},{"q":693,"a":696},{"q":700,"a":703},{},true,"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp",{"title":5,"description":776},"performance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp\u002Findex","article","6boHIobnRobNCvqmXxC-RT5ywbsk1aan7prPIBBgFNc",[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,941,944,947,950,953,956,959,962,965,968,971,974,977,980,983,986,989,992,995,998,1001,1004,1007,1010,1013,1016,1018,1019,1022,1024,1027,1030,1033,1036,1039,1042,1045,1048,1051,1054,1057,1059,1061,1063,1066,1069,1072,1075,1078,1081,1084,1087,1090,1093,1096,1099,1102,1105,1108,1110,1113,1116,1119,1122,1125,1128,1131,1134,1137,1140,1143,1146,1149,1152,1155,1158,1161,1164,1167,1170,1173,1176,1179,1182,1185,1188,1191,1194,1197,1200,1203,1206,1209,1212,1215,1218,1221,1224,1227,1230,1233,1236,1239,1242,1245,1248,1251,1254,1257,1260,1263,1266,1269,1272,1275,1278,1281,1284,1287,1290,1293,1296,1299,1302,1305,1308,1311,1314,1317,1320,1323,1326,1329],{"path":792,"title":793},"\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":795,"title":796},"\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":798,"title":799},"\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":801,"title":802},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites","Astro vs Eleventy for Documentation Sites",{"path":804,"title":805},"\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":807,"title":808},"\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":810,"title":811},"\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":813,"title":814},"\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":816,"title":817},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress","Docs Frameworks: Docusaurus, Starlight and VitePress",{"path":819,"title":820},"\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":822,"title":823},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-from-mkdocs-to-starlight","Migrating from MkDocs to Starlight",{"path":825,"title":826},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioned-documentation-with-docusaurus","Versioned Documentation with Docusaurus",{"path":828,"title":829},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-for-library-documentation","VitePress for Library Documentation",{"path":831,"title":832},"\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":834,"title":835},"\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":837,"title":838},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories","Hugo Build Times for Large Repositories",{"path":840,"title":841},"\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":843,"title":844},"\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":846,"title":847},"\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":849,"title":850},"\u002Fchoosing-the-right-static-site-generator-for-production","Choosing the Right Static Site Generator for Production",{"path":852,"title":853},"\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":855,"title":856},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem","Jekyll Plugin Ecosystem",{"path":858,"title":859},"\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":861,"title":862},"\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":864,"title":865},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fspeeding-up-slow-jekyll-builds","Speeding Up Slow Jekyll Builds",{"path":867,"title":868},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fupgrading-jekyll-and-ruby-versions-safely","Upgrading Jekyll and Ruby Versions Safely",{"path":870,"title":871},"\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":873,"title":874},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators","Migrating Between Static Site Generators",{"path":876,"title":877},"\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":879,"title":880},"\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":882,"title":883},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-gatsby-to-astro","Migrating from Gatsby to Astro",{"path":885,"title":886},"\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":888,"title":889},"\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":891,"title":892},"\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":894,"title":895},"\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":897,"title":898},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites","Next.js Static Export for Content Sites",{"path":900,"title":901},"\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":903,"title":904},"\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":906,"title":907},"\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":909,"title":910},"\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":912,"title":913},"\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":915,"title":916},"\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":918,"title":919},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites","Search for Static Sites",{"path":921,"title":922},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Findexing-hugo-sites-with-pagefind","Indexing Hugo Sites with Pagefind",{"path":924,"title":925},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fmultilingual-search-on-static-sites","Multilingual Search on Static Sites",{"path":927,"title":928},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-algolia-docsearch","Pagefind vs Algolia DocSearch",{"path":930,"title":931},"\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":933,"title":934},"\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":936,"title":937},"\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":939,"title":940},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fevaluating-ssg-accessibility-defaults","Evaluating SSG Accessibility Defaults",{"path":942,"title":943},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix","SSG Framework Selection Matrix",{"path":945,"title":946},"\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":948,"title":949},"\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":951,"title":952},"\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":954,"title":955},"\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":957,"title":958},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs","CDN Caching Rules for SSGs",{"path":960,"title":961},"\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":963,"title":964},"\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":966,"title":967},"\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":969,"title":970},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fstale-while-revalidate-for-static-html","Stale-While-Revalidate for Static HTML",{"path":972,"title":973},"\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":975,"title":976},"\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":978,"title":979},"\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":981,"title":982},"\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":984,"title":985},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites","Cumulative Layout Shift Fixes for Static Sites",{"path":987,"title":988},"\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":990,"title":991},"\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":993,"title":994},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap","font-display: optional vs swap",{"path":996,"title":997},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites","Font Loading Strategies for Static Sites",{"path":999,"title":1000},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fmetric-matched-fallback-fonts-with-size-adjust","Metric-Matched Fallback Fonts with size-adjust",{"path":1002,"title":1003},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads","Preloading Fonts Without Double Downloads",{"path":1005,"title":1006},"\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":1008,"title":1009},"\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":1011,"title":1012},"\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":1014,"title":1015},"\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":1017,"title":32},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro",{"path":785,"title":5},{"path":1020,"title":1021},"\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":1023,"title":456},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fresponsive-images-with-srcset-in-eleventy",{"path":1025,"title":1026},"\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":1028,"title":1029},"\u002Fperformance-optimization-core-web-vitals-for-ssgs","Core Web Vitals Optimization for SSGs",{"path":1031,"title":1032},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance","Astro Islands vs Full Hydration Performance",{"path":1034,"title":1035},"\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":1037,"title":1038},"\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":1040,"title":1041},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering","JavaScript Hydration & Partial Rendering",{"path":1043,"title":1044},"\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":1046,"title":1047},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components","Replacing React Islands with Web Components",{"path":1049,"title":1050},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Feliminating-render-blocking-css-on-static-sites","Eliminating Render-Blocking CSS on Static Sites",{"path":1052,"title":1053},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages","Fixing LCP on Text-Heavy Documentation Pages",{"path":1055,"title":1056},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites","Largest Contentful Paint Optimization for Static Sites",{"path":1058,"title":609},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Fmeasuring-lcp-subparts-with-devtools",{"path":1060,"title":356},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Foptimizing-lcp-on-astro-with-priority-hints",{"path":1062,"title":724},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Freducing-lcp-from-hero-images-on-static-sites",{"path":1064,"title":1065},"\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":1067,"title":1068},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci","Performance Budgets and Lighthouse CI",{"path":1070,"title":1071},"\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":1073,"title":1074},"\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":1076,"title":1077},"\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":1079,"title":1080},"\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":1082,"title":1083},"\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":1085,"title":1086},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fauditing-unused-preloads","Auditing Unused Preloads",{"path":1088,"title":1089},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed","Resource Hints and Navigation Speed",{"path":1091,"title":1092},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Finstant-navigation-with-speculation-rules","Instant Navigation with Speculation Rules",{"path":1094,"title":1095},"\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":1097,"title":1098},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro","Prefetching Links in Astro",{"path":1100,"title":1101},"\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":1103,"title":1104},"\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":1106,"title":1107},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites","Third-Party Script Performance on Static Sites",{"path":1109,"title":481},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Flazy-loading-youtube-embeds-on-static-sites",{"path":1111,"title":1112},"\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":1114,"title":1115},"\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":1117,"title":1118},"\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":1120,"title":1121},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fautomating-eleventy-deployments-with-cloudflare-pages","Automating Eleventy Deployments on Cloudflare Pages",{"path":1123,"title":1124},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages","Configuring Redirects on Cloudflare Pages",{"path":1126,"title":1127},"\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":1129,"title":1130},"\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":1132,"title":1133},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup","Cloudflare Pages Edge Caching Setup",{"path":1135,"title":1136},"\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":1138,"title":1139},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fchecking-links-in-pull-requests","Checking Links in Pull Requests",{"path":1141,"title":1142},"\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":1144,"title":1145},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Feditorial-checks-with-vale-in-ci","Editorial Checks with Vale in CI",{"path":1147,"title":1148},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams","Content Workflows for Documentation Teams",{"path":1150,"title":1151},"\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":1153,"title":1154},"\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":1156,"title":1157},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fbuilding-astro-sites-with-github-actions","Building Astro Sites with GitHub Actions",{"path":1159,"title":1160},"\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":1162,"title":1163},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-github-pages-with-actions","Deploying to GitHub Pages with Actions",{"path":1165,"title":1166},"\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":1168,"title":1169},"\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":1171,"title":1172},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds","GitHub Actions for Automated SSG Builds",{"path":1174,"title":1175},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fmatrix-builds-for-multi-site-monorepos","Matrix Builds for Multi-Site Monorepos",{"path":1177,"title":1178},"\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":1180,"title":1181},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fenabling-incremental-builds-in-eleventy","Enabling Incremental Builds in Eleventy",{"path":1183,"title":1184},"\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":1186,"title":1187},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs","Incremental Builds and Build Caching for SSGs",{"path":1189,"title":1190},"\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":1192,"title":1193},"\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":1195,"title":1196},"\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":1198,"title":1199},"\u002Fproduction-ready-deployment-cicd-workflows","Production-Ready Deployment & CI\u002FCD for SSGs",{"path":1201,"title":1202},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops","Alerting on Cache Hit Ratio Drops",{"path":1204,"title":1205},"\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":1207,"title":1208},"\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":1210,"title":1211},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production","Monitoring Static Sites in Production",{"path":1213,"title":1214},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge","Logging 404s at the Edge",{"path":1216,"title":1217},"\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":1219,"title":1220},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-vercel-for-hugo-and-eleventy","Configuring Vercel for Hugo and Eleventy",{"path":1222,"title":1223},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies","Netlify vs Vercel Deployment Strategies",{"path":1225,"title":1226},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates","Netlify Build Hooks for Content Updates",{"path":1228,"title":1229},"\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":1231,"title":1232},"\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":1234,"title":1235},"\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":1237,"title":1238},"\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":1240,"title":1241},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments","Cleaning Up Stale Preview Deployments",{"path":1243,"title":1244},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests","Preview Environments for Pull Requests",{"path":1246,"title":1247},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpassword-protecting-preview-deployments","Password-Protecting Preview Deployments",{"path":1249,"title":1250},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreviewing-headless-cms-drafts","Previewing Headless CMS Drafts",{"path":1252,"title":1253},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fvisual-regression-testing-on-preview-deploys","Visual Regression Testing on Preview Deploys",{"path":1255,"title":1256},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads","Atomic Deploys vs Incremental Uploads",{"path":1258,"title":1259},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fcanary-releases-for-static-sites","Canary Releases for Static Sites",{"path":1261,"title":1262},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Ffeature-flags-on-static-sites","Feature Flags on Static Sites",{"path":1264,"title":1265},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites","Rollbacks and Deploy Safety for Static Sites",{"path":1267,"title":1268},"\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":1270,"title":1271},"\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":1273,"title":1274},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fauditing-npm-dependencies-in-ssg-pipelines","Auditing npm Dependencies in SSG Pipelines",{"path":1276,"title":1277},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fenabling-hsts-and-preload-safely","Enabling HSTS and Preload Safely",{"path":1279,"title":1280},"\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":1282,"title":1283},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites","Security Headers and Hardening for Static Sites",{"path":1285,"title":1286},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc","Securing Deploy Credentials with GitHub OIDC",{"path":1288,"title":1289},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsubresource-integrity-for-third-party-assets","Subresource Integrity for Third-Party Assets",{"path":1291,"title":1292},"\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":1294,"title":1295},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3","Clean URLs and Trailing Slashes on S3",{"path":1297,"title":1298},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects","CloudFront Functions for Redirects",{"path":1300,"title":1301},"\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":1303,"title":1304},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites","Self-Hosting Static Sites on S3, Nginx and Caddy",{"path":1306,"title":1307},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy","Serving a Static Site with Caddy",{"path":1309,"title":1310},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx","Serving a Static Site with Nginx",{"path":1312,"title":1313},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps","Zero-Downtime Deploys with Symlink Swaps",{"path":1315,"title":1316},"\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":1318,"title":1319},"\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":1321,"title":1322},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites","Serverless Functions for Static Sites",{"path":1324,"title":1325},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers","Netlify Functions vs Cloudflare Workers",{"path":1327,"title":1328},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication","Protecting a Static Site Behind Authentication",{"path":1330,"title":1331},"\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",1789722848054]