[{"data":1,"prerenderedAt":1248},["ShallowReactive",2],{"content:\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images":3,"surroundings:\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images":1239},{"id":4,"title":5,"body":6,"description":1217,"extension":1218,"meta":1219,"navigation":1232,"path":1233,"seo":1234,"stem":1237,"__hash__":1238},"content\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images\u002Findex.md","Lazy-Loading CSS Background Images",{"type":7,"value":8,"toc":1200},"minimark",[9,14,46,49,206,211,252,256,262,271,277,286,290,295,406,547,551,557,606,610,620,699,703,713,851,954,958,965,969,982,986,1003,1007,1036,1040,1053,1059,1065,1071,1075,1097,1106,1126,1135,1144,1156,1160,1185,1190,1193,1196],[10,11,13],"h1",{"id":12},"how-to-lazy-load-css-background-images","How to Lazy-Load CSS Background Images",[15,16,17,18,23,24,28,29,33,34,37,38,41,42,45],"p",{},"This guide extends ",[19,20,22],"a",{"href":21},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002F","Lazy-Loading Images Without Hurting LCP",", part of ",[19,25,27],{"href":26},"\u002Fimage-media-optimization\u002F","Image & Media Optimization",". The native ",[30,31,32],"code",{},"loading=\"lazy\""," attribute only applies to ",[30,35,36],{},"\u003Cimg>"," and ",[30,39,40],{},"\u003Ciframe>"," elements. Images set with ",[30,43,44],{},"background-image"," in CSS follow different rules: the browser fetches a background image when an element that matches the rule is rendered (has a computed style and a box), regardless of whether it is on screen. A long landing page with a dozen decorative section backgrounds therefore downloads all of them during the initial load, competing with the LCP image and fonts for bandwidth.",[15,47,48],{},"There is also the opposite problem. Hero banners are often CSS backgrounds, and a background image can be the LCP element. Because the browser discovers it only after the CSS has downloaded and the style has been computed, a background hero is already late; lazy-loading it with JavaScript makes it later still. The right approach is to defer the backgrounds below the fold and make the one above the fold discoverable early.",[15,50,51],{},[52,53,59,60,59,67,59,71,59,74,59,83,59,89,59,100,59,104,59,109,59,117,59,124,59,129,59,133,59,137,59,140,59,143,59,148,59,152,59,158,59,162,59,167,59,173,59,177,59,181,59,185,59,189,59,193,59,197,59,203,59],"svg",{"viewBox":54,"width":55,"role":56,"ariaLabel":57,"style":58},"0 0 760 200","100%","img","Timeline comparing eager CSS background downloads with deferred ones, showing the LCP image competing for bandwidth in the eager case.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[61,62],"rect",{"className":63,"x":65,"y":65,"width":55,"height":55,"fill":66},[64],"svg-canvas","0","#ffffff",[68,69,70],"title",{},"When background images start downloading",[72,73,57],"desc",{},[61,75],{"x":76,"y":76,"width":77,"height":78,"rx":79,"fill":80,"stroke":81,"style":82},"1","758","198","10","none","currentColor","stroke-opacity:0.18",[84,85,70],"text",{"x":86,"y":87,"fill":81,"style":88},"28.0","34.0","font-size:16px;font-weight:700",[90,91],"line",{"x1":92,"y1":93,"x2":92,"y2":94,"stroke":95,"strokeWidth":96,"strokeDashArray":97,"style":99},"470.9","72.0","156.0","#b8860b","1.5",[98,98],"4","stroke-opacity:0.9",[90,101],{"x1":102,"y1":93,"x2":102,"y2":94,"stroke":95,"strokeWidth":96,"strokeDashArray":103,"style":99},"656.4",[98,98],[84,105,108],{"x":86,"y":106,"fill":81,"style":107},"96.0","font-size:12.5px;font-weight:700","Eager backgrounds",[61,110],{"x":111,"y":112,"width":113,"height":114,"rx":115,"fill":81,"stroke":81,"style":116},"239.8","78.0","91.3","26.0","3","fill-opacity:0.06;stroke-opacity:0.4",[84,118,123],{"x":119,"y":120,"fill":81,"style":121,"textAnchor":122},"285.4","95.5","font-size:11.5px","middle","CSS",[61,125],{"x":126,"y":112,"width":127,"height":114,"rx":115,"fill":80,"stroke":81,"style":128},"332.5","323.1","stroke-opacity:0.35",[84,130,132],{"x":131,"y":120,"fill":81,"style":121,"textAnchor":122},"494.1","8 section bgs + hero",[84,134,136],{"x":86,"y":135,"fill":81,"style":107},"134.0","Deferred backgrounds",[61,138],{"x":111,"y":139,"width":113,"height":114,"rx":115,"fill":81,"stroke":81,"style":116},"116.0",[84,141,123],{"x":119,"y":142,"fill":81,"style":121,"textAnchor":122},"133.5",[61,144],{"x":126,"y":139,"width":145,"height":114,"rx":115,"fill":146,"stroke":95,"style":147},"137.6","#ffc300","fill-opacity:0.24;stroke-opacity:0.9",[84,149,151],{"x":150,"y":142,"fill":81,"style":121,"textAnchor":122},"401.4","hero only",[61,153],{"x":154,"y":139,"width":155,"height":114,"rx":115,"fill":156,"stroke":156,"style":157},"471.7","230.4","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[84,159,161],{"x":160,"y":142,"fill":81,"style":121,"textAnchor":122},"586.9","bgs on scroll",[90,163],{"x1":164,"y1":94,"x2":165,"y2":94,"stroke":81,"style":166},"169.5","726.0","stroke-opacity:0.4",[84,168,172],{"x":169,"y":170,"fill":171,"style":121,"textAnchor":122},"180.2","173.0","#51617a","0ms",[84,174,176],{"x":175,"y":170,"fill":171,"style":121,"textAnchor":122},"262.2","400ms",[84,178,180],{"x":179,"y":170,"fill":171,"style":121,"textAnchor":122},"355.0","800ms",[84,182,184],{"x":183,"y":170,"fill":171,"style":121,"textAnchor":122},"447.7","1200ms",[84,186,188],{"x":187,"y":170,"fill":171,"style":121,"textAnchor":122},"540.5","1600ms",[84,190,192],{"x":191,"y":170,"fill":171,"style":121,"textAnchor":122},"633.2","2000ms",[84,194,196],{"x":195,"y":170,"fill":171,"style":121,"textAnchor":122},"712.3","2400ms",[84,198,202],{"x":102,"y":199,"fill":200,"style":201,"textAnchor":122},"68.0","#8a6608","font-size:12px;font-weight:700","LCP eager",[84,204,205],{"x":92,"y":199,"fill":200,"style":201,"textAnchor":122},"LCP deferred",[207,208,210],"h2",{"id":209},"rapid-diagnosis","Rapid Diagnosis",[212,213,214,222,236,242],"ul",{},[215,216,217,221],"li",{},[218,219,220],"strong",{},"Filter the Network panel by Img"," and reload: CSS-initiated images show the stylesheet as the initiator. Count how many download before any scrolling.",[215,223,224,227,228,231,232,235],{},[218,225,226],{},"Check the LCP element"," in the Performance panel. If it is a ",[30,229,230],{},"div"," or ",[30,233,234],{},"section",", the LCP resource is a background image.",[215,237,238,241],{},[218,239,240],{},"Look at request start times."," Background images cannot start until the stylesheet that references them has arrived and layout is under way.",[215,243,244,247,248,251],{},[218,245,246],{},"Check element visibility rules."," Elements hidden with ",[30,249,250],{},"display: none"," do not load their backgrounds; elements merely off-screen do.",[207,253,255],{"id":254},"root-cause-analysis","Root Cause Analysis",[15,257,258,261],{},[218,259,260],{},"1. Backgrounds load when styled, not when visible."," Any rendered element matching the rule triggers the fetch, regardless of scroll position.",[15,263,264,267,268,270],{},[218,265,266],{},"2. No native lazy attribute."," CSS has no equivalent to ",[30,269,32],{},", so deferral needs a class toggle or a rendering trick.",[15,272,273,276],{},[218,274,275],{},"3. Late discovery for heroes."," The preload scanner reads HTML, not CSS rules, so a background hero is found only after the CSS is parsed.",[15,278,279,282,283,285],{},[218,280,281],{},"4. Responsive backgrounds via media queries."," Several ",[30,284,44],{}," declarations across breakpoints are fine — only the matching one loads — but authors sometimes stack them in ways that load two.",[207,287,289],{"id":288},"step-by-step-resolution","Step-by-Step Resolution",[291,292,294],"h3",{"id":293},"_1-gate-below-the-fold-backgrounds-behind-a-class","1. Gate below-the-fold backgrounds behind a class",[296,297,302],"pre",{"className":298,"code":299,"language":300,"meta":301,"style":301},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F* Backgrounds are only applied once the section is near the viewport. *\u002F\n.promo { background-color: #e8eef6; }               \u002F* placeholder colour *\u002F\n.promo.is-visible { background-image: image-set(url(\u002Fimg\u002Fpromo.avif) type(\"image\u002Favif\"), url(\u002Fimg\u002Fpromo.jpg) type(\"image\u002Fjpeg\")); }\n\u002F* trade-off: without JavaScript the class never appears; keep the placeholder\n   colour attractive, or add a noscript style that applies the image. *\u002F\n","css","",[30,303,304,312,338,394,400],{"__ignoreMap":301},[305,306,308],"span",{"class":90,"line":307},1,[305,309,311],{"class":310},"sjfSM","\u002F* Backgrounds are only applied once the section is near the viewport. *\u002F\n",[305,313,315,319,323,326,329,332,335],{"class":90,"line":314},2,[305,316,318],{"class":317},"sPXB4",".promo",[305,320,322],{"class":321},"saISM"," { ",[305,324,325],{"class":317},"background-color",[305,327,328],{"class":321},": ",[305,330,331],{"class":317},"#e8eef6",[305,333,334],{"class":321},"; }               ",[305,336,337],{"class":310},"\u002F* placeholder colour *\u002F\n",[305,339,341,344,346,348,350,353,356,359,361,365,368,371,375,378,380,382,385,388,391],{"class":90,"line":340},3,[305,342,343],{"class":317},".promo.is-visible",[305,345,322],{"class":321},[305,347,44],{"class":317},[305,349,328],{"class":321},[305,351,352],{"class":317},"image-set",[305,354,355],{"class":321},"(",[305,357,358],{"class":317},"url",[305,360,355],{"class":321},[305,362,364],{"class":363},"sQw3B","\u002Fimg\u002Fpromo.avif",[305,366,367],{"class":321},") ",[305,369,370],{"class":363},"type(",[305,372,374],{"class":373},"sZ8jY","\"image\u002Favif\"",[305,376,377],{"class":321},"), ",[305,379,358],{"class":317},[305,381,355],{"class":321},[305,383,384],{"class":363},"\u002Fimg\u002Fpromo.jpg",[305,386,387],{"class":321},") type(",[305,389,390],{"class":373},"\"image\u002Fjpeg\"",[305,392,393],{"class":321},")); }\n",[305,395,397],{"class":90,"line":396},4,[305,398,399],{"class":310},"\u002F* trade-off: without JavaScript the class never appears; keep the placeholder\n",[305,401,403],{"class":90,"line":402},5,[305,404,405],{"class":310},"   colour attractive, or add a noscript style that applies the image. *\u002F\n",[296,407,411],{"className":408,"code":409,"language":410,"meta":301,"style":301},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","const io = new IntersectionObserver((entries) => {\n  for (const e of entries) if (e.isIntersecting) { e.target.classList.add('is-visible'); io.unobserve(e.target); }\n}, { rootMargin: '400px 0px' });\ndocument.querySelectorAll('.promo, .feature-bg').forEach((el) => io.observe(el));\n\u002F\u002F trade-off: a larger rootMargin hides loading on fast scrolls but loads more\n\u002F\u002F images that may never be seen; 300-600px suits most pages.\n","javascript",[30,412,413,446,488,499,536,541],{"__ignoreMap":301},[305,414,415,419,422,425,428,432,435,438,440,443],{"class":90,"line":307},[305,416,418],{"class":417},"sPARh","const",[305,420,421],{"class":317}," io",[305,423,424],{"class":417}," =",[305,426,427],{"class":417}," new",[305,429,431],{"class":430},"smZ65"," IntersectionObserver",[305,433,434],{"class":321},"((",[305,436,437],{"class":363},"entries",[305,439,367],{"class":321},[305,441,442],{"class":417},"=>",[305,444,445],{"class":321}," {\n",[305,447,448,451,454,456,459,462,465,468,471,474,476,479,482,485],{"class":90,"line":314},[305,449,450],{"class":417},"  for",[305,452,453],{"class":321}," (",[305,455,418],{"class":417},[305,457,458],{"class":317}," e",[305,460,461],{"class":417}," of",[305,463,464],{"class":321}," entries) ",[305,466,467],{"class":417},"if",[305,469,470],{"class":321}," (e.isIntersecting) { e.target.classList.",[305,472,473],{"class":430},"add",[305,475,355],{"class":321},[305,477,478],{"class":373},"'is-visible'",[305,480,481],{"class":321},"); io.",[305,483,484],{"class":430},"unobserve",[305,486,487],{"class":321},"(e.target); }\n",[305,489,490,493,496],{"class":90,"line":340},[305,491,492],{"class":321},"}, { rootMargin: ",[305,494,495],{"class":373},"'400px 0px'",[305,497,498],{"class":321}," });\n",[305,500,501,504,507,509,512,515,518,520,523,525,527,530,533],{"class":90,"line":396},[305,502,503],{"class":321},"document.",[305,505,506],{"class":430},"querySelectorAll",[305,508,355],{"class":321},[305,510,511],{"class":373},"'.promo, .feature-bg'",[305,513,514],{"class":321},").",[305,516,517],{"class":430},"forEach",[305,519,434],{"class":321},[305,521,522],{"class":363},"el",[305,524,367],{"class":321},[305,526,442],{"class":417},[305,528,529],{"class":321}," io.",[305,531,532],{"class":430},"observe",[305,534,535],{"class":321},"(el));\n",[305,537,538],{"class":90,"line":402},[305,539,540],{"class":310},"\u002F\u002F trade-off: a larger rootMargin hides loading on fast scrolls but loads more\n",[305,542,544],{"class":90,"line":543},6,[305,545,546],{"class":310},"\u002F\u002F images that may never be seen; 300-600px suits most pages.\n",[291,548,550],{"id":549},"_2-use-content-visibility-for-whole-sections","2. Use content-visibility for whole sections",[15,552,553,556],{},[30,554,555],{},"content-visibility: auto"," on long sections skips rendering offscreen content, which also delays backgrounds inside it until the section approaches the viewport — without JavaScript.",[296,558,560],{"className":298,"code":559,"language":300,"meta":301,"style":301},".section { content-visibility: auto; contain-intrinsic-size: auto 800px; }\n\u002F* trade-off: browser support and behaviour vary; treat it as a progressive\n   enhancement, and always set contain-intrinsic-size to avoid layout shifts. *\u002F\n",[30,561,562,596,601],{"__ignoreMap":301},[305,563,564,567,569,572,574,577,580,583,585,587,590,593],{"class":90,"line":307},[305,565,566],{"class":317},".section",[305,568,322],{"class":321},[305,570,571],{"class":317},"content-visibility",[305,573,328],{"class":321},[305,575,576],{"class":317},"auto",[305,578,579],{"class":321},"; ",[305,581,582],{"class":317},"contain-intrinsic-size",[305,584,328],{"class":321},[305,586,576],{"class":317},[305,588,589],{"class":317}," 800",[305,591,592],{"class":417},"px",[305,594,595],{"class":321},"; }\n",[305,597,598],{"class":90,"line":314},[305,599,600],{"class":310},"\u002F* trade-off: browser support and behaviour vary; treat it as a progressive\n",[305,602,603],{"class":90,"line":340},[305,604,605],{"class":310},"   enhancement, and always set contain-intrinsic-size to avoid layout shifts. *\u002F\n",[291,607,609],{"id":608},"_3-make-a-background-hero-discoverable-early","3. Make a background hero discoverable early",[15,611,612,613,615,616,619],{},"If the hero must stay a background, preload it with responsive attributes and high priority, or better, convert it to an ",[30,614,36],{}," with ",[30,617,618],{},"object-fit: cover",".",[296,621,625],{"className":622,"code":623,"language":624,"meta":301,"style":301},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Clink rel=\"preload\" as=\"image\" fetchpriority=\"high\"\n      imagesrcset=\"\u002Fimg\u002Fhero-800.avif 800w, \u002Fimg\u002Fhero-1600.avif 1600w\" imagesizes=\"100vw\" type=\"image\u002Favif\">\n\u003C!-- trade-off: the preload must match what CSS selects at each breakpoint, or\n     the browser downloads two images. An \u003Cimg> avoids this duplication. -->\n","html",[30,626,627,661,689,694],{"__ignoreMap":301},[305,628,629,632,636,639,642,645,648,650,653,656,658],{"class":90,"line":307},[305,630,631],{"class":321},"\u003C",[305,633,635],{"class":634},"sZBmE","link",[305,637,638],{"class":317}," rel",[305,640,641],{"class":321},"=",[305,643,644],{"class":373},"\"preload\"",[305,646,647],{"class":317}," as",[305,649,641],{"class":321},[305,651,652],{"class":373},"\"image\"",[305,654,655],{"class":317}," fetchpriority",[305,657,641],{"class":321},[305,659,660],{"class":373},"\"high\"\n",[305,662,663,666,668,671,674,676,679,682,684,686],{"class":90,"line":314},[305,664,665],{"class":317},"      imagesrcset",[305,667,641],{"class":321},[305,669,670],{"class":373},"\"\u002Fimg\u002Fhero-800.avif 800w, \u002Fimg\u002Fhero-1600.avif 1600w\"",[305,672,673],{"class":317}," imagesizes",[305,675,641],{"class":321},[305,677,678],{"class":373},"\"100vw\"",[305,680,681],{"class":317}," type",[305,683,641],{"class":321},[305,685,374],{"class":373},[305,687,688],{"class":321},">\n",[305,690,691],{"class":90,"line":340},[305,692,693],{"class":310},"\u003C!-- trade-off: the preload must match what CSS selects at each breakpoint, or\n",[305,695,696],{"class":90,"line":396},[305,697,698],{"class":310},"     the browser downloads two images. An \u003Cimg> avoids this duplication. -->\n",[291,700,702],{"id":701},"_4-avoid-double-downloads-across-breakpoints","4. Avoid double downloads across breakpoints",[15,704,705,706,37,709,712],{},"Put alternative backgrounds in mutually exclusive media queries (",[30,707,708],{},"min-width",[30,710,711],{},"max-width"," pairs) rather than overriding a default image at a breakpoint, which can load both in some cases.",[15,714,715],{},[52,716,59,719,59,722,59,725,59,727,59,744,59,747,59,749,59,755,59,760,59,763,59,768,59,775,59,781,59,785,59,790,59,793,59,797,59,799,59,802,59,805,59,808,59,811,59,814,59,817,59,821,59,823,59,826,59,829,59,832,59,836,59,839,59,843,59,847,59],{"viewBox":717,"width":55,"role":56,"ariaLabel":718,"style":58},"0 0 760 341","Decision sequence for handling a CSS background image depending on its position and role.",[61,720],{"className":721,"x":65,"y":65,"width":55,"height":55,"fill":66},[64],[68,723,724],{},"Which technique for which background",[72,726,718],{},[728,729,730],"defs",{},[731,732,739],"marker",{"id":733,"viewBox":734,"refX":735,"refY":736,"markerWidth":737,"markerHeight":737,"orient":738},"faa5472d42","0 0 10 10","9","5","7","auto-start-reverse",[740,741],"path",{"d":742,"fill":81,"style":743},"M0 0 L10 5 L0 10 z","fill-opacity:0.7",[61,745],{"x":76,"y":76,"width":77,"height":746,"rx":79,"fill":80,"stroke":81,"style":82},"339",[84,748,724],{"x":86,"y":87,"fill":81,"style":88},[61,750],{"x":86,"y":751,"width":752,"height":753,"rx":754,"fill":81,"stroke":81,"style":116},"56.0","320.0","35.0","6",[84,756,759],{"x":757,"y":112,"fill":81,"style":758,"textAnchor":122},"188.0","font-size:13px;font-weight:700","Is the background the LCP element?",[61,761],{"x":762,"y":751,"width":752,"height":753,"rx":754,"fill":80,"stroke":81,"style":128},"412.0",[84,764,767],{"x":765,"y":112,"fill":81,"style":766,"textAnchor":122},"572.0","font-size:12.5px","Convert to img or preload with fetchpriority high",[90,769],{"x1":770,"y1":771,"x2":772,"y2":771,"stroke":81,"strokeWidth":96,"style":773,"markerEnd":774},"348.0","73.5","410.0","stroke-opacity:0.6","url(#faa5472d42)",[84,776,780],{"x":777,"y":778,"fill":156,"style":779,"textAnchor":122},"380.0","66.5","font-size:11.5px;font-weight:700","yes",[90,782],{"x1":757,"y1":783,"x2":757,"y2":784,"stroke":81,"strokeWidth":96,"style":773,"markerEnd":774},"91.0","125.0",[84,786,789],{"x":787,"y":788,"fill":171,"style":779},"196.0","113.0","no",[61,791],{"x":86,"y":792,"width":752,"height":753,"rx":754,"fill":81,"stroke":81,"style":116},"127.0",[84,794,796],{"x":757,"y":795,"fill":81,"style":758,"textAnchor":122},"149.0","Is it above the fold but decorative?",[61,798],{"x":762,"y":792,"width":752,"height":753,"rx":754,"fill":156,"stroke":156,"style":157},[84,800,801],{"x":765,"y":795,"fill":81,"style":766,"textAnchor":122},"Load normally; keep it small",[90,803],{"x1":770,"y1":804,"x2":772,"y2":804,"stroke":81,"strokeWidth":96,"style":773,"markerEnd":774},"144.5",[84,806,780],{"x":777,"y":807,"fill":156,"style":779,"textAnchor":122},"137.5",[90,809],{"x1":757,"y1":810,"x2":757,"y2":787,"stroke":81,"strokeWidth":96,"style":773,"markerEnd":774},"162.0",[84,812,789],{"x":787,"y":813,"fill":171,"style":779},"184.0",[61,815],{"x":86,"y":816,"width":752,"height":753,"rx":754,"fill":81,"stroke":81,"style":116},"198.0",[84,818,820],{"x":757,"y":819,"fill":81,"style":758,"textAnchor":122},"220.0","Is it inside a long offscreen section?",[61,822],{"x":762,"y":816,"width":752,"height":753,"rx":754,"fill":156,"stroke":156,"style":157},[84,824,825],{"x":765,"y":819,"fill":81,"style":766,"textAnchor":122},"content-visibility auto or IntersectionObserver class",[90,827],{"x1":770,"y1":828,"x2":772,"y2":828,"stroke":81,"strokeWidth":96,"style":773,"markerEnd":774},"215.5",[84,830,780],{"x":777,"y":831,"fill":156,"style":779,"textAnchor":122},"208.5",[90,833],{"x1":757,"y1":834,"x2":757,"y2":835,"stroke":81,"strokeWidth":96,"style":773,"markerEnd":774},"233.0","267.0",[84,837,789],{"x":787,"y":838,"fill":171,"style":779},"255.0",[61,840],{"x":86,"y":841,"width":752,"height":842,"rx":754,"fill":146,"stroke":95,"style":147},"269.0","50.0",[84,844,846],{"x":757,"y":845,"fill":81,"style":766,"textAnchor":122},"290.5","Leave as is — small icons and patterns are not worth",[84,848,850],{"x":757,"y":849,"fill":81,"style":766,"textAnchor":122},"306.5","deferring",[15,852,853],{},[52,854,59,857,59,860,59,863,59,865,59,868,59,870,59,874,59,880,59,885,59,888,59,892,59,896,59,899,59,903,59,906,59,909,59,913,59,917,59,922,59,926,59,930,59,935,59,937,59,939,59,942,59,945,59,948,59,951,59],{"viewBox":855,"width":55,"role":56,"ariaLabel":856,"style":58},"0 0 760 318","Four checks for every CSS background image on a page.",[61,858],{"className":859,"x":65,"y":65,"width":55,"height":55,"fill":66},[64],[68,861,862],{},"Background image audit checklist",[72,864,856],{},[61,866],{"x":76,"y":76,"width":77,"height":867,"rx":79,"fill":80,"stroke":81,"style":82},"316",[84,869,862],{"x":86,"y":87,"fill":81,"style":88},[61,871],{"x":93,"y":751,"width":872,"height":873,"rx":754,"fill":156,"stroke":156,"style":157},"660.0","51.0",[84,875,879],{"x":876,"y":877,"fill":81,"style":758,"textAnchor":878},"86.0","77.0","start","Is it the LCP element?",[84,881,884],{"x":876,"y":882,"fill":81,"style":883,"textAnchor":878},"94.0","font-size:12px","Make it an img or preload it with high priority",[61,886],{"x":93,"y":887,"width":872,"height":873,"rx":754,"fill":156,"stroke":156,"style":157},"119.0",[84,889,891],{"x":876,"y":890,"fill":81,"style":758,"textAnchor":878},"140.0","Is it below the fold?",[84,893,895],{"x":876,"y":894,"fill":81,"style":883,"textAnchor":878},"157.0","Gate it behind a visibility class",[61,897],{"x":93,"y":898,"width":872,"height":873,"rx":754,"fill":156,"stroke":156,"style":157},"182.0",[84,900,902],{"x":876,"y":901,"fill":81,"style":758,"textAnchor":878},"203.0","Does it have a placeholder colour?",[84,904,905],{"x":876,"y":819,"fill":81,"style":883,"textAnchor":878},"Avoid white flashes while it loads",[61,907],{"x":93,"y":908,"width":872,"height":873,"rx":754,"fill":156,"stroke":156,"style":157},"245.0",[84,910,912],{"x":876,"y":911,"fill":81,"style":758,"textAnchor":878},"266.0","Do breakpoints exclude each other?",[84,914,916],{"x":876,"y":915,"fill":81,"style":883,"textAnchor":878},"283.0","Prevent two downloads of one slot",[90,918],{"x1":919,"y1":120,"x2":919,"y2":920,"stroke":81,"strokeWidth":96,"style":921},"43.0","130.5","stroke-opacity:0.3",[90,923],{"x1":919,"y1":924,"x2":919,"y2":925,"stroke":81,"strokeWidth":96,"style":921},"158.5","193.5",[90,927],{"x1":919,"y1":928,"x2":919,"y2":929,"stroke":81,"strokeWidth":96,"style":921},"221.5","256.5",[931,932],"circle",{"cx":919,"cy":933,"r":934,"fill":156},"81.5","13",[84,936,76],{"x":919,"y":876,"fill":66,"style":758,"textAnchor":122},[931,938],{"cx":919,"cy":804,"r":934,"fill":156},[84,940,941],{"x":919,"y":795,"fill":66,"style":758,"textAnchor":122},"2",[931,943],{"cx":919,"cy":944,"r":934,"fill":156},"207.5",[84,946,115],{"x":919,"y":947,"fill":66,"style":758,"textAnchor":122},"212.0",[931,949],{"cx":919,"cy":950,"r":934,"fill":156},"270.5",[84,952,98],{"x":919,"y":953,"fill":66,"style":758,"textAnchor":122},"275.0",[207,955,957],{"id":956},"verification","Verification",[15,959,960,961,964],{},"Reload with the cache disabled and confirm only above-the-fold backgrounds download before interaction; scroll and watch the deferred ones appear in the Network panel shortly before their sections reach the viewport. In the Performance panel, the LCP resource should start earlier and finish without competing downloads. In RUM, compare LCP ",[30,962,963],{},"resourceLoadDelay"," for pages with background heroes before and after.",[207,966,968],{"id":967},"worked-example-a-saas-landing-page","Worked Example: A SaaS Landing Page",[15,970,971,972,615,975,977,978,981],{},"A SaaS landing page had nine full-width sections, each with a decorative AVIF background (60–180KB each), and a hero set as a CSS background. On a mid-range phone over 4G, all ten images started downloading within 100ms of the stylesheet arriving, and the hero (the LCP element) finished at 2.9s. The team converted the hero to an ",[30,973,974],{},"\u003Cimg fetchpriority=\"high\">",[30,976,618],{},", and gated the nine section backgrounds behind an ",[30,979,980],{},"is-visible"," class with a 500px root margin. Initial image bytes fell from 1.2MB to 140KB, and LCP p75 on mobile improved from 2.9s to 1.7s. The sections still looked complete on normal scrolling because their backgrounds arrived before they entered the viewport.",[207,983,985],{"id":984},"backgrounds-vs-inline-images","Backgrounds vs Inline Images",[15,987,988,989,991,992,37,995,998,999,1002],{},"Many problems with CSS backgrounds disappear when the image is content rather than decoration. An ",[30,990,36],{}," gets responsive selection with ",[30,993,994],{},"srcset",[30,996,997],{},"sizes",", native lazy loading, ",[30,1000,1001],{},"fetchpriority",", alt text, early discovery by the preload scanner, and accurate LCP attribution. CSS backgrounds are best kept for genuinely decorative textures, patterns and gradients. A useful rule: if removing the image would change the meaning of the section, or if it is larger than a few kilobytes and above the fold, it probably belongs in the markup.",[207,1004,1006],{"id":1005},"common-mistakes","Common Mistakes",[212,1008,1009,1015,1024,1030],{},[215,1010,1011,1014],{},[218,1012,1013],{},"Lazy-loading a background hero."," Delays the LCP further.",[215,1016,1017,1023],{},[218,1018,1019,1020,1022],{},"Using ",[30,1021,250],{}," to defer."," It works but also removes the element from layout and accessibility; it is not a deferral strategy for visible content.",[215,1025,1026,1029],{},[218,1027,1028],{},"Forgetting a placeholder colour."," Sections flash white as backgrounds arrive.",[215,1031,1032,1035],{},[218,1033,1034],{},"Preloads that do not match CSS."," Two downloads of the same image in different sizes.",[207,1037,1039],{"id":1038},"edge-cases","Edge Cases",[15,1041,1042,1045,1046,37,1049,1052],{},[218,1043,1044],{},"Pseudo-elements."," Backgrounds on ",[30,1047,1048],{},"::before",[30,1050,1051],{},"::after"," follow the same rules; toggle a class on the parent.",[15,1054,1055,1058],{},[218,1056,1057],{},"Print styles."," Background images are usually not printed by default; no deferral concerns there.",[15,1060,1061,1064],{},[218,1062,1063],{},"SPA route changes."," Re-run observer setup after client-side navigations, or use a framework directive.",[15,1066,1067,1070],{},[218,1068,1069],{},"Very small images."," Icons and patterns under a few kilobytes are better inlined or left alone; deferral overhead outweighs the savings.",[207,1072,1074],{"id":1073},"faq","FAQ",[1076,1077,1080,1084],"details",{"className":1078},[1079],"faq-item",[1081,1082,1083],"summary",{},"Does loading=\"lazy\" work on divs?",[15,1085,1086,1087,37,1089,1091,1092,1094,1095,619],{},"No. The attribute only applies to ",[30,1088,36],{},[30,1090,40],{},". Background images need a class toggle, ",[30,1093,571],{},", or conversion to an ",[30,1096,36],{},[1076,1098,1100,1103],{"className":1099},[1079],[1081,1101,1102],{},"Can a CSS background image be the LCP element?",[15,1104,1105],{},"Yes. Browsers report background images as LCP candidates. They are often slow because they are discovered only after the CSS has loaded.",[1076,1107,1109,1112],{"className":1108},[1079],[1081,1110,1111],{},"Is image-set() supported?",[15,1113,1114,1115,615,1118,1121,1122,1125],{},"Modern browsers support ",[30,1116,1117],{},"image-set()",[30,1119,1120],{},"type()"," for format selection. Keep a plain ",[30,1123,1124],{},"url()"," fallback declaration before it for older browsers.",[1076,1127,1129,1132],{"className":1128},[1079],[1081,1130,1131],{},"Does content-visibility delay background images?",[15,1133,1134],{},"Skipped content is not rendered, so its backgrounds are not fetched until the section is about to be rendered. Behaviour can vary, so verify in the Network panel.",[1076,1136,1138,1141],{"className":1137},[1079],[1081,1139,1140],{},"What root margin should I use?",[15,1142,1143],{},"Between 300 and 600px works for most pages. Use larger margins for fast-scrolling feeds and smaller ones for long pages with heavy images that many users never reach.",[1076,1145,1147,1150],{"className":1146},[1079],[1081,1148,1149],{},"Will search engines see deferred background images?",[15,1151,1152,1153,1155],{},"Decorative backgrounds are generally not indexed as content anyway. Images that matter for search should be ",[30,1154,36],{}," elements with alt text.",[207,1157,1159],{"id":1158},"related","Related",[212,1161,1162,1171,1178],{},[215,1163,1164,1168,1169,619],{},[19,1165,1167],{"href":1166},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Ffixing-lazy-loaded-images-that-delay-lcp\u002F","Fixing lazy-loaded images that delay LCP"," — the same mistake with ",[30,1170,36],{},[215,1172,1173,1177],{},[19,1174,1176],{"href":1175},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Fnative-lazy-loading-vs-intersection-observer\u002F","Native lazy loading vs IntersectionObserver"," — choosing the deferral mechanism.",[215,1179,1180,1184],{},[19,1181,1183],{"href":1182},"\u002Fimage-media-optimization\u002Fimage-cdns-and-fetchpriority\u002Fusing-fetchpriority-to-prioritize-the-lcp-image\u002F","Using fetchpriority to prioritize the LCP image"," — making the hero fast.",[1186,1187,1189],"script",{"type":1188},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Lazy-Load CSS Background Images\",\n  \"description\": \"Techniques for deferring offscreen CSS background images, and how to avoid lazy-loading a background that is actually the LCP element.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Gate below-the-fold backgrounds behind a class\",\n      \"text\": \"Gate below-the-fold backgrounds behind a class\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Use content-visibility for whole sections\",\n      \"text\": \"content-visibility: auto on long sections skips rendering offscreen content, which also delays backgrounds inside it until the section approaches the viewport — without JavaScript.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Make a background hero discoverable early\",\n      \"text\": \"If the hero must stay a background, preload it with responsive attributes and high priority, or better, convert it to an with object-fit: cover.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Avoid double downloads across breakpoints\",\n      \"text\": \"Put alternative backgrounds in mutually exclusive media queries (min-width and max-width pairs) rather than overriding a default image at a breakpoint, which can load both in some cases.\"\n    }\n  ]\n}\n",[1186,1191,1192],{"type":1188},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Lazy-Load CSS Background Images\",\n  \"description\": \"Techniques for deferring offscreen CSS background images, and how to avoid lazy-loading a background that is actually the LCP element.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images\u002F\"\n  }\n}\n",[1186,1194,1195],{"type":1188},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Image & Media Optimization\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Lazy Loading Images Without Hurting LCP\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Lazy-Loading CSS Background Images\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images\u002F\"\n    }\n  ]\n}\n",[1197,1198,1199],"style",{},"html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}",{"title":301,"searchDepth":314,"depth":314,"links":1201},[1202,1203,1204,1210,1211,1212,1213,1214,1215,1216],{"id":209,"depth":314,"text":210},{"id":254,"depth":314,"text":255},{"id":288,"depth":314,"text":289,"children":1205},[1206,1207,1208,1209],{"id":293,"depth":340,"text":294},{"id":549,"depth":340,"text":550},{"id":608,"depth":340,"text":609},{"id":701,"depth":340,"text":702},{"id":956,"depth":314,"text":957},{"id":967,"depth":314,"text":968},{"id":984,"depth":314,"text":985},{"id":1005,"depth":314,"text":1006},{"id":1038,"depth":314,"text":1039},{"id":1073,"depth":314,"text":1074},{"id":1158,"depth":314,"text":1159},"Techniques for deferring offscreen CSS background images, and how to avoid lazy-loading a background that is actually the LCP element.","md",{"slug":1220,"type":1221,"breadcrumb":1222,"datePublished":1231,"dateModified":1231},"lazy-loading-css-background-images","article",[1223,1226,1227,1229],{"name":1224,"url":1225},"Home","\u002F",{"name":27,"url":26},{"name":1228,"url":21},"Lazy Loading Images Without Hurting LCP",{"name":5,"url":1230},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images\u002F","2026-10-06",true,"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images",{"title":1235,"description":1236},"How to Lazy-Load CSS Background Images Correctly","CSS background images ignore loading=\"lazy\". Defer them with IntersectionObserver class toggles, content-visibility or image-set, without delaying a background LCP.","image-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-css-background-images\u002Findex","q-j8ByXOavlK02mAGRwbsi5jJeK-bRtLkg8n2dnDdQg",[1240,1244],{"title":1241,"path":1242,"stem":1243,"children":-1},"Fixing Lazy-Loaded Images That Delay LCP","\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Ffixing-lazy-loaded-images-that-delay-lcp","image-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Ffixing-lazy-loaded-images-that-delay-lcp\u002Findex",{"title":1245,"path":1246,"stem":1247,"children":-1},"Lazy-Loading iframes","\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-iframes","image-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-iframes\u002Findex",1791308075670]