[{"data":1,"prerenderedAt":1187},["ShallowReactive",2],{"content:\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images":3,"surroundings:\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images":1178},{"id":4,"title":5,"body":6,"description":1157,"extension":1158,"meta":1159,"navigation":1171,"path":1172,"seo":1173,"stem":1176,"__hash__":1177},"content\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002Findex.md","sizes=auto vs Manual sizes for Lazy Images",{"type":7,"value":8,"toc":1148},"minimark",[9,14,34,40,45,96,214,218,312,316,322,330,338,347,351,360,478,481,495,587,599,681,695,699,705,902,908,990,994,1019,1028,1048,1081,1096,1108,1112,1133,1138,1141,1144],[10,11,13],"h1",{"id":12},"sizesauto-vs-manual-sizes-which-for-lazy-loaded-images","sizes=auto vs Manual sizes: Which for Lazy-Loaded Images?",[15,16,17,18,23,24,28,29,33],"p",{},"This comparison sits under ",[19,20,22],"a",{"href":21},"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002F","Responsive Images with srcset and sizes"," inside ",[19,25,27],{"href":26},"\u002Fimage-media-optimization\u002F","Image & Media Optimization",". A hand-written ",[30,31,32],"code",{},"sizes"," attribute is a promise about layout that lives in your HTML while the layout itself lives in your CSS. The two drift, and when they do the browser picks a candidate that is too large — wasted bytes — or too small — a blurry image.",[15,35,36,39],{},[30,37,38],{},"sizes=\"auto\""," removes the promise for lazy-loaded images by letting the browser read the element's actual rendered width. It does not apply to eager images, and that limitation is the whole decision.",[41,42,44],"h2",{"id":43},"rapid-diagnosis-is-your-sizes-attribute-lying","Rapid Diagnosis: Is Your sizes Attribute Lying?",[46,47,48,71,77,86],"ul",{},[49,50,51,55,56,59,60,63,64,67,68,70],"li",{},[52,53,54],"strong",{},"Compare the selected candidate with the rendered box."," In the Elements panel, read ",[30,57,58],{},"currentSrc"," and the element's layout width. A ",[30,61,62],{},"1600w"," candidate in a ",[30,65,66],{},"420px"," box means ",[30,69,32],{}," is overstating.",[49,72,73,76],{},[52,74,75],{},"Test at several viewport widths."," Drift usually appears at one breakpoint — the one that changed most recently.",[49,78,79,82,83,85],{},[52,80,81],{},"Check for a grid or container-driven width."," If the image's width comes from a flexible container rather than the viewport, a viewport-based ",[30,84,32],{}," cannot express it accurately.",[49,87,88,95],{},[52,89,90,91,94],{},"Look for ",[30,92,93],{},"sizes=\"100vw\""," on a sidebar image."," The most common instance of the bug is a copied default that no longer matches where the image sits.",[97,98,105,106,113,114,113,118,113,122,113,131,113,138,113,145,113,154,113,159,113,165,113,170,113,175,113,179,113,186,113,190,113,193,113,196,113,200,113,203,113,206,113,209,113],"svg",{"xmlns":99,"viewBox":100,"width":101,"role":102,"ariaLabel":103,"style":104},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","0 0 760 246","100%","img","A rendered 420 pixel image box compared with a sizes attribute claiming 100vw, causing a 1600 wide candidate to be chosen, versus sizes auto choosing the 800 wide candidate that matches the box","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)","\n  ",[107,108],"rect",{"className":109,"x":111,"y":111,"width":101,"height":101,"fill":112},[110],"svg-canvas","0","#ffffff"," ",[115,116,117],"title",{},"What the browser downloads when sizes is wrong",[119,120,121],"desc",{},"A 420 pixel wide image box with a sizes attribute claiming full viewport width selects a 1600 wide candidate; with sizes auto the browser measures the real box and selects the 800 wide candidate instead.",[107,123],{"x":124,"y":124,"width":125,"height":126,"rx":127,"fill":128,"stroke":129,"style":130},"1","758","244","10","none","currentColor","stroke-opacity:0.18",[132,133,137],"text",{"x":134,"y":135,"fill":129,"style":136},"24","32","font-size:16px;font-weight:700","The box is 420px. What arrives?",[132,139,144],{"x":140,"y":141,"fill":129,"style":142,"textAnchor":143},"190","64","font-size:11.5px;font-weight:700;","middle","sizes=\"100vw\" (wrong)",[107,146],{"x":147,"y":148,"width":149,"height":150,"rx":151,"fill":152,"stroke":152,"style":153},"60","78","120","70","5","#0466c8","fill-opacity:0.16;stroke-opacity:0.5",[132,155,158],{"x":149,"y":156,"fill":129,"style":157,"textAnchor":143},"118","font-size:10.5px;","rendered 420px",[107,160],{"x":161,"y":148,"width":149,"height":150,"rx":151,"fill":162,"stroke":163,"style":164},"200","#ffc300","#b8860b","fill-opacity:0.3",[132,166,169],{"x":167,"y":168,"fill":129,"style":157,"textAnchor":143},"260","110","downloaded",[132,171,174],{"x":167,"y":172,"fill":129,"style":173,"textAnchor":143},"127","font-size:11px;font-weight:700;","1600w · 340KB",[132,176,178],{"x":140,"y":177,"fill":163,"style":142,"textAnchor":143},"176","~4× the pixels needed",[180,181],"line",{"x1":182,"y1":183,"x2":182,"y2":184,"stroke":129,"style":185},"380","50","215","stroke-opacity:0.2",[132,187,189],{"x":188,"y":141,"fill":129,"style":142,"textAnchor":143},"570","sizes=\"auto\" (lazy)",[107,191],{"x":192,"y":148,"width":149,"height":150,"rx":151,"fill":152,"stroke":152,"style":153},"440",[132,194,158],{"x":195,"y":156,"fill":129,"style":157,"textAnchor":143},"500",[107,197],{"x":198,"y":148,"width":149,"height":150,"rx":151,"fill":152,"stroke":152,"style":199},"580","fill-opacity:0.24;stroke-opacity:0.55",[132,201,169],{"x":202,"y":168,"fill":129,"style":157,"textAnchor":143},"640",[132,204,205],{"x":202,"y":172,"fill":129,"style":173,"textAnchor":143},"800w · 96KB",[132,207,208],{"x":188,"y":177,"fill":129,"style":142,"textAnchor":143},"matches the box at 2× DPR",[132,210,213],{"x":134,"y":211,"fill":129,"style":212},"212","font-size:11px;font-style:italic;fill-opacity:0.7","Sizes shown are illustrative — the ratio, not the absolute numbers, is the point.",[41,215,217],{"id":216},"the-comparison","The Comparison",[219,220,221,240],"table",{},[222,223,224],"thead",{},[225,226,227,231,235],"tr",{},[228,229,230],"th",{},"Axis",[228,232,233],{},[30,234,38],{},[228,236,237,238],{},"Manual ",[30,239,32],{},[241,242,243,258,269,280,291,302],"tbody",{},[225,244,245,249,255],{},[246,247,248],"td",{},"Applies to",[246,250,251,254],{},[30,252,253],{},"loading=\"lazy\""," images only",[246,256,257],{},"Any image",[225,259,260,263,266],{},[246,261,262],{},"Accuracy",[246,264,265],{},"Exact — measured layout width",[246,267,268],{},"As accurate as your maintenance",[225,270,271,274,277],{},[246,272,273],{},"Maintenance",[246,275,276],{},"None",[246,278,279],{},"A media-query list per layout change",[225,281,282,285,288],{},[246,283,284],{},"Works with container-driven widths",[246,286,287],{},"Yes",[246,289,290],{},"Only approximately",[225,292,293,296,299],{},[246,294,295],{},"Preload-scanner discovery",[246,297,298],{},"No — measured after layout",[246,300,301],{},"Yes, from the markup",[225,303,304,307,310],{},[246,305,306],{},"Right for the LCP image",[246,308,309],{},"No",[246,311,287],{},[41,313,315],{"id":314},"root-cause-analysis-why-manual-sizes-drifts","Root Cause Analysis: Why Manual sizes Drifts",[15,317,318,321],{},[52,319,320],{},"1. It duplicates layout knowledge."," The same widths are expressed in CSS and again in HTML, in a different syntax, with no mechanism keeping them in sync.",[15,323,324,113,327,329],{},[52,325,326],{},"2. Container queries broke the viewport assumption.",[30,328,32],{}," is expressed against the viewport, but a component's width increasingly depends on its container. There is no viewport-based expression for \"half of whatever my parent is\".",[15,331,332,113,335,337],{},[52,333,334],{},"3. Copy-paste defaults.",[30,336,93],{}," is the value everyone reaches for, and it is correct only for genuinely full-bleed images.",[15,339,340,343,344,346],{},[52,341,342],{},"4. Templates outlive their layouts."," A component built for a full-width hero gets reused in a three-column grid, and the ",[30,345,32],{}," attribute travels with it unchanged.",[41,348,350],{"id":349},"step-by-step-resolution","Step-by-Step Resolution",[15,352,353],{},[52,354,355,356,359],{},"1. Use ",[30,357,358],{},"auto"," for every lazy-loaded image.",[361,362,367],"pre",{"className":363,"code":364,"language":365,"meta":366,"style":366},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Cimg src=\"\u002Fthumb-800.avif\" alt=\"Trail map detail\"\n     srcset=\"\u002Fthumb-400.avif 400w, \u002Fthumb-800.avif 800w, \u002Fthumb-1600.avif 1600w\"\n     sizes=\"auto\" loading=\"lazy\" decoding=\"async\"\n     width=\"800\" height=\"450\">\n\u003C!-- trade-off: `auto` requires loading=\"lazy\", because the browser must lay the\n     element out before it can measure it. On an eager image the attribute is\n     ignored and the browser falls back to 100vw — usually the worst choice. -->\n","html","",[30,368,369,399,410,437,459,466,472],{"__ignoreMap":366},[370,371,373,377,380,384,387,391,394,396],"span",{"class":180,"line":372},1,[370,374,376],{"class":375},"saISM","\u003C",[370,378,102],{"class":379},"sZBmE",[370,381,383],{"class":382},"sPXB4"," src",[370,385,386],{"class":375},"=",[370,388,390],{"class":389},"sZ8jY","\"\u002Fthumb-800.avif\"",[370,392,393],{"class":382}," alt",[370,395,386],{"class":375},[370,397,398],{"class":389},"\"Trail map detail\"\n",[370,400,402,405,407],{"class":180,"line":401},2,[370,403,404],{"class":382},"     srcset",[370,406,386],{"class":375},[370,408,409],{"class":389},"\"\u002Fthumb-400.avif 400w, \u002Fthumb-800.avif 800w, \u002Fthumb-1600.avif 1600w\"\n",[370,411,413,416,418,421,424,426,429,432,434],{"class":180,"line":412},3,[370,414,415],{"class":382},"     sizes",[370,417,386],{"class":375},[370,419,420],{"class":389},"\"auto\"",[370,422,423],{"class":382}," loading",[370,425,386],{"class":375},[370,427,428],{"class":389},"\"lazy\"",[370,430,431],{"class":382}," decoding",[370,433,386],{"class":375},[370,435,436],{"class":389},"\"async\"\n",[370,438,440,443,445,448,451,453,456],{"class":180,"line":439},4,[370,441,442],{"class":382},"     width",[370,444,386],{"class":375},[370,446,447],{"class":389},"\"800\"",[370,449,450],{"class":382}," height",[370,452,386],{"class":375},[370,454,455],{"class":389},"\"450\"",[370,457,458],{"class":375},">\n",[370,460,462],{"class":180,"line":461},5,[370,463,465],{"class":464},"sjfSM","\u003C!-- trade-off: `auto` requires loading=\"lazy\", because the browser must lay the\n",[370,467,469],{"class":180,"line":468},6,[370,470,471],{"class":464},"     element out before it can measure it. On an eager image the attribute is\n",[370,473,475],{"class":180,"line":474},7,[370,476,477],{"class":464},"     ignored and the browser falls back to 100vw — usually the worst choice. -->\n",[15,479,480],{},"Expected outcome: each lazy image downloads the candidate that matches its real box, typically cutting image bytes by 30–60% on grid and sidebar layouts.",[15,482,483,489,490,494],{},[52,484,485,486,488],{},"2. Keep a manual ",[30,487,32],{}," for eager, above-the-fold images."," The ",[19,491,493],{"href":492},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F","LCP"," image must be discoverable by the preload scanner before layout exists, so it needs an explicit promise.",[361,496,498],{"className":363,"code":497,"language":365,"meta":366,"style":366},"\u003Cimg src=\"\u002Fhero-1600.avif\" alt=\"Coastal trail at sunrise\"\n     srcset=\"\u002Fhero-800.avif 800w, \u002Fhero-1600.avif 1600w, \u002Fhero-2400.avif 2400w\"\n     sizes=\"(min-width: 1200px) 1100px, 100vw\"\n     fetchpriority=\"high\" decoding=\"async\" width=\"1600\" height=\"900\">\n\u003C!-- trade-off: this attribute is a maintenance liability by design. Keep the\n     breakpoints identical to the CSS and review both together — for the LCP\n     image the accuracy is worth the upkeep. -->\n",[30,499,500,520,529,538,572,577,582],{"__ignoreMap":366},[370,501,502,504,506,508,510,513,515,517],{"class":180,"line":372},[370,503,376],{"class":375},[370,505,102],{"class":379},[370,507,383],{"class":382},[370,509,386],{"class":375},[370,511,512],{"class":389},"\"\u002Fhero-1600.avif\"",[370,514,393],{"class":382},[370,516,386],{"class":375},[370,518,519],{"class":389},"\"Coastal trail at sunrise\"\n",[370,521,522,524,526],{"class":180,"line":401},[370,523,404],{"class":382},[370,525,386],{"class":375},[370,527,528],{"class":389},"\"\u002Fhero-800.avif 800w, \u002Fhero-1600.avif 1600w, \u002Fhero-2400.avif 2400w\"\n",[370,530,531,533,535],{"class":180,"line":412},[370,532,415],{"class":382},[370,534,386],{"class":375},[370,536,537],{"class":389},"\"(min-width: 1200px) 1100px, 100vw\"\n",[370,539,540,543,545,548,550,552,555,558,560,563,565,567,570],{"class":180,"line":439},[370,541,542],{"class":382},"     fetchpriority",[370,544,386],{"class":375},[370,546,547],{"class":389},"\"high\"",[370,549,431],{"class":382},[370,551,386],{"class":375},[370,553,554],{"class":389},"\"async\"",[370,556,557],{"class":382}," width",[370,559,386],{"class":375},[370,561,562],{"class":389},"\"1600\"",[370,564,450],{"class":382},[370,566,386],{"class":375},[370,568,569],{"class":389},"\"900\"",[370,571,458],{"class":375},[370,573,574],{"class":180,"line":461},[370,575,576],{"class":464},"\u003C!-- trade-off: this attribute is a maintenance liability by design. Keep the\n",[370,578,579],{"class":180,"line":468},[370,580,581],{"class":464},"     breakpoints identical to the CSS and review both together — for the LCP\n",[370,583,584],{"class":180,"line":474},[370,585,586],{"class":464},"     image the accuracy is worth the upkeep. -->\n",[15,588,589,595,596,598],{},[52,590,591,592,594],{},"3. Provide a fallback for browsers without ",[30,593,358],{},"."," Support is broad but not universal; a sensible manual value in front of ",[30,597,358],{}," degrades gracefully.",[361,600,602],{"className":363,"code":601,"language":365,"meta":366,"style":366},"\u003Cimg sizes=\"auto, (min-width: 900px) 33vw, 100vw\" loading=\"lazy\"\n     srcset=\"\u002Fcard-400.avif 400w, \u002Fcard-800.avif 800w\" src=\"\u002Fcard-800.avif\"\n     alt=\"Route card\" width=\"800\" height=\"600\">\n\u003C!-- trade-off: the comma-separated form is parsed as a sizes list, so\n     unsupporting browsers skip the unknown `auto` and take the next entry.\n     Keep the fallback honest — it is what older clients actually get. -->\n",[30,603,604,625,641,666,671,676],{"__ignoreMap":366},[370,605,606,608,610,613,615,618,620,622],{"class":180,"line":372},[370,607,376],{"class":375},[370,609,102],{"class":379},[370,611,612],{"class":382}," sizes",[370,614,386],{"class":375},[370,616,617],{"class":389},"\"auto, (min-width: 900px) 33vw, 100vw\"",[370,619,423],{"class":382},[370,621,386],{"class":375},[370,623,624],{"class":389},"\"lazy\"\n",[370,626,627,629,631,634,636,638],{"class":180,"line":401},[370,628,404],{"class":382},[370,630,386],{"class":375},[370,632,633],{"class":389},"\"\u002Fcard-400.avif 400w, \u002Fcard-800.avif 800w\"",[370,635,383],{"class":382},[370,637,386],{"class":375},[370,639,640],{"class":389},"\"\u002Fcard-800.avif\"\n",[370,642,643,646,648,651,653,655,657,659,661,664],{"class":180,"line":412},[370,644,645],{"class":382},"     alt",[370,647,386],{"class":375},[370,649,650],{"class":389},"\"Route card\"",[370,652,557],{"class":382},[370,654,386],{"class":375},[370,656,447],{"class":389},[370,658,450],{"class":382},[370,660,386],{"class":375},[370,662,663],{"class":389},"\"600\"",[370,665,458],{"class":375},[370,667,668],{"class":180,"line":439},[370,669,670],{"class":464},"\u003C!-- trade-off: the comma-separated form is parsed as a sizes list, so\n",[370,672,673],{"class":180,"line":461},[370,674,675],{"class":464},"     unsupporting browsers skip the unknown `auto` and take the next entry.\n",[370,677,678],{"class":180,"line":468},[370,679,680],{"class":464},"     Keep the fallback honest — it is what older clients actually get. -->\n",[15,682,683,686,687,690,691,594],{},[52,684,685],{},"4. Generate the ladder from real layout widths."," Whichever attribute you use, the ",[30,688,689],{},"srcset"," candidates should bracket the widths your layout actually produces, not a generic set — and the transformation is usually a CDN parameter, as covered in ",[19,692,694],{"href":693},"\u002Fimage-media-optimization\u002Fimage-cdns-and-fetchpriority\u002F","image CDNs and fetchpriority",[41,696,698],{"id":697},"verification","Verification",[15,700,701,702,704],{},"Check ",[30,703,58],{}," against the rendered width at several viewport sizes. The selected candidate should be the smallest one at or above the box width multiplied by the device pixel ratio; anything larger is waste, anything smaller will look soft.",[361,706,710],{"className":707,"code":708,"language":709,"meta":366,"style":366},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F Audit every image on the page in one pass.\nfor (const img of document.images) {\n  const need = Math.round(img.getBoundingClientRect().width * devicePixelRatio);\n  const got = Number(img.currentSrc.match(\u002F(\\d+)(?=\\D*$)\u002F)?.[1] ?? 0);\n  if (got > need * 1.5) console.warn('oversized', img.currentSrc, `${got} vs ~${need}`);\n}\n\u002F\u002F trade-off: parsing the width out of the filename only works if your naming\n\u002F\u002F encodes it. Otherwise read naturalWidth after load, which is exact but only\n\u002F\u002F available once the image has arrived.\n","javascript",[30,711,712,717,738,771,830,880,885,890,896],{"__ignoreMap":366},[370,713,714],{"class":180,"line":372},[370,715,716],{"class":464},"\u002F\u002F Audit every image on the page in one pass.\n",[370,718,719,723,726,729,732,735],{"class":180,"line":401},[370,720,722],{"class":721},"sPARh","for",[370,724,725],{"class":375}," (",[370,727,728],{"class":721},"const",[370,730,731],{"class":382}," img",[370,733,734],{"class":721}," of",[370,736,737],{"class":375}," document.images) {\n",[370,739,740,743,746,749,752,756,759,762,765,768],{"class":180,"line":412},[370,741,742],{"class":721},"  const",[370,744,745],{"class":382}," need",[370,747,748],{"class":721}," =",[370,750,751],{"class":375}," Math.",[370,753,755],{"class":754},"smZ65","round",[370,757,758],{"class":375},"(img.",[370,760,761],{"class":754},"getBoundingClientRect",[370,763,764],{"class":375},"().width ",[370,766,767],{"class":721},"*",[370,769,770],{"class":375}," devicePixelRatio);\n",[370,772,773,775,778,780,783,786,789,792,795,798,801,804,807,810,813,816,818,821,824,827],{"class":180,"line":439},[370,774,742],{"class":721},[370,776,777],{"class":382}," got",[370,779,748],{"class":721},[370,781,782],{"class":754}," Number",[370,784,785],{"class":375},"(img.currentSrc.",[370,787,788],{"class":754},"match",[370,790,791],{"class":375},"(",[370,793,794],{"class":389},"\u002F(",[370,796,797],{"class":382},"\\d",[370,799,800],{"class":721},"+",[370,802,803],{"class":389},")(?=",[370,805,806],{"class":382},"\\D",[370,808,809],{"class":721},"*$",[370,811,812],{"class":389},")\u002F",[370,814,815],{"class":375},")?.[",[370,817,124],{"class":382},[370,819,820],{"class":375},"] ",[370,822,823],{"class":721},"??",[370,825,826],{"class":382}," 0",[370,828,829],{"class":375},");\n",[370,831,832,835,838,841,844,846,849,852,855,857,860,863,866,869,872,875,878],{"class":180,"line":461},[370,833,834],{"class":721},"  if",[370,836,837],{"class":375}," (got ",[370,839,840],{"class":721},">",[370,842,843],{"class":375}," need ",[370,845,767],{"class":721},[370,847,848],{"class":382}," 1.5",[370,850,851],{"class":375},") console.",[370,853,854],{"class":754},"warn",[370,856,791],{"class":375},[370,858,859],{"class":389},"'oversized'",[370,861,862],{"class":375},", img.currentSrc, ",[370,864,865],{"class":389},"`${",[370,867,868],{"class":375},"got",[370,870,871],{"class":389},"} vs ~${",[370,873,874],{"class":375},"need",[370,876,877],{"class":389},"}`",[370,879,829],{"class":375},[370,881,882],{"class":180,"line":468},[370,883,884],{"class":375},"}\n",[370,886,887],{"class":180,"line":474},[370,888,889],{"class":464},"\u002F\u002F trade-off: parsing the width out of the filename only works if your naming\n",[370,891,893],{"class":180,"line":892},8,[370,894,895],{"class":464},"\u002F\u002F encodes it. Otherwise read naturalWidth after load, which is exact but only\n",[370,897,899],{"class":180,"line":898},9,[370,900,901],{"class":464},"\u002F\u002F available once the image has arrived.\n",[15,903,904,905,907],{},"Then confirm the byte saving is real, and that the LCP image was not affected — ",[30,906,358],{}," on an eager image would have quietly downgraded it. Assert both in CI:",[361,909,913],{"className":910,"code":911,"language":912,"meta":366,"style":366},"language-json shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","{ \"ci\": { \"assert\": { \"assertions\": {\n  \"uses-responsive-images\": [\"error\", { \"minScore\": 0.9 }],\n  \"largest-contentful-paint\": [\"error\", { \"maxNumericValue\": 2500 }]\n} } } }\n","json",[30,914,915,937,963,985],{"__ignoreMap":366},[370,916,917,920,923,926,929,931,934],{"class":180,"line":372},[370,918,919],{"class":375},"{ ",[370,921,922],{"class":379},"\"ci\"",[370,924,925],{"class":375},": { ",[370,927,928],{"class":379},"\"assert\"",[370,930,925],{"class":375},[370,932,933],{"class":379},"\"assertions\"",[370,935,936],{"class":375},": {\n",[370,938,939,942,945,948,951,954,957,960],{"class":180,"line":401},[370,940,941],{"class":379},"  \"uses-responsive-images\"",[370,943,944],{"class":375},": [",[370,946,947],{"class":389},"\"error\"",[370,949,950],{"class":375},", { ",[370,952,953],{"class":379},"\"minScore\"",[370,955,956],{"class":375},": ",[370,958,959],{"class":382},"0.9",[370,961,962],{"class":375}," }],\n",[370,964,965,968,970,972,974,977,979,982],{"class":180,"line":412},[370,966,967],{"class":379},"  \"largest-contentful-paint\"",[370,969,944],{"class":375},[370,971,947],{"class":389},[370,973,950],{"class":375},[370,975,976],{"class":379},"\"maxNumericValue\"",[370,978,956],{"class":375},[370,980,981],{"class":382},"2500",[370,983,984],{"class":375}," }]\n",[370,986,987],{"class":180,"line":439},[370,988,989],{"class":375},"} } } }\n",[41,991,993],{"id":992},"faq","FAQ",[995,996,999,1003],"details",{"className":997},[998],"faq-item",[1000,1001,1002],"summary",{},"Can I use sizes=\"auto\" on my hero image?",[15,1004,1005,1006,1008,1009,1011,1012,1015,1016,1018],{},"No — it requires ",[30,1007,253],{},", and lazy-loading the LCP image is one of the most reliable ways to make LCP worse. The hero needs to be discoverable by the preload scanner before layout, which means an explicit ",[30,1010,32],{}," value and ",[30,1013,1014],{},"fetchpriority=\"high\"",". Reserve ",[30,1017,358],{}," for everything below the fold.",[995,1020,1022,1025],{"className":1021},[998],[1000,1023,1024],{},"Does sizes=\"auto\" delay the image request?",[15,1026,1027],{},"Slightly, and by design: the browser must lay the element out before it knows its width. For a lazy image that is irrelevant, because the request was already waiting for the element to approach the viewport. For an eager image it would be a real delay, which is exactly why the attribute is restricted to lazy loading.",[995,1029,1031,1034],{"className":1030},[998],[1000,1032,1033],{},"What happens in browsers that do not support auto?",[15,1035,1036,1037,1039,1040,1043,1044,1047],{},"They ignore the unknown value. If ",[30,1038,358],{}," is the only entry, they fall back to the default ",[30,1041,1042],{},"100vw",", which usually over-fetches. Writing ",[30,1045,1046],{},"sizes=\"auto, (min-width: 900px) 33vw, 100vw\""," gives those browsers a reasonable manual value while supporting ones use the measured width — the best of both with one extra attribute.",[995,1049,1051,1054],{"className":1050},[998],[1000,1052,1053],{},"Does sizes affect which format is served?",[15,1055,1056,1057,1059,1060,1062,1063,1066,1067,1070,1071,1073,1074,1077,1078,1080],{},"No — ",[30,1058,32],{}," participates only in candidate selection within a ",[30,1061,689],{},", choosing between widths. Format negotiation happens separately, either through ",[30,1064,1065],{},"\u003Csource type>"," entries in a ",[30,1068,1069],{},"\u003Cpicture>"," element or through content negotiation at an image CDN. The two interact only in that a ",[30,1072,1069],{}," with several ",[30,1075,1076],{},"\u003Csource>"," elements needs the ",[30,1079,32],{}," value repeated on each one, which is another place a hand-written value can drift out of sync.",[995,1082,1084,1087],{"className":1083},[998],[1000,1085,1086],{},"What about images inside a container query layout?",[15,1088,1089,1090,1092,1093,1095],{},"This is the case ",[30,1091,358],{}," was designed for. A component whose width comes from its container has no viewport-based expression at all — you would have to encode the container's own responsive behaviour into the image's ",[30,1094,32],{}," attribute and keep the two synchronised forever. Measured sizing sidesteps it entirely: the browser reads the box after layout, whatever decided that box. For eager images in container-driven layouts, pick the value that matches the largest plausible container and accept some over-fetch.",[995,1097,1099,1102],{"className":1098},[998],[1000,1100,1101],{},"Should I audit sizes attributes in CI?",[15,1103,1104,1105,1107],{},"A light check is worth having. Render the key templates at two or three viewport widths in a headless browser and compare each image's ",[30,1106,58],{}," width against its rendered box times the device pixel ratio, failing when the ratio exceeds about 1.5. That catches the common regression — a component reused in a narrower slot — without needing anyone to remember the relationship between the CSS and the attribute.",[41,1109,1111],{"id":1110},"related","Related",[46,1113,1114,1119,1126],{},[49,1115,1116,1118],{},[19,1117,22],{"href":21}," — building the candidate ladder these attributes select from.",[49,1120,1121,1125],{},[19,1122,1124],{"href":1123},"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Ffixing-blurry-images-on-high-dpi-displays\u002F","Fixing blurry images on high-DPI displays"," — the failure mode when the selected candidate is too small.",[49,1127,1128,1132],{},[19,1129,1131],{"href":1130},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002F","Lazy loading images without hurting LCP"," — which images may be lazy in the first place.",[1134,1135,1137],"script",{"type":1136},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Choose between sizes=auto and a manual sizes attribute\",\n  \"description\": \"Use measured sizing for lazy images, keep an explicit sizes value for the eager LCP image, provide a fallback list for older browsers, and generate the candidate ladder from real layout widths.\",\n  \"step\": [\n    { \"@type\": \"HowToStep\", \"position\": 1, \"name\": \"Use auto for lazy images\", \"text\": \"Add sizes=auto to every loading=lazy image so the browser selects from the measured layout width.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"position\": 2, \"name\": \"Keep manual sizes for the LCP image\", \"text\": \"Give the eager above-the-fold image an explicit sizes value plus fetchpriority high.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"position\": 3, \"name\": \"Add a fallback entry\", \"text\": \"Write a sizes list beginning with auto so unsupporting browsers take a sensible manual value.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"position\": 4, \"name\": \"Verify the selection\", \"text\": \"Compare currentSrc against rendered width times device pixel ratio at several viewports.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F#verification\" }\n  ]\n}\n",[1134,1139,1140],{"type":1136},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"sizes=auto vs Manual sizes: Which for Lazy-Loaded Images?\",\n  \"description\": \"Measured sizing removes the drift between a hand-written sizes attribute and the CSS that actually decides layout — for lazy images only.\",\n  \"datePublished\": \"2026-08-01\",\n  \"dateModified\": \"2026-08-01\",\n  \"author\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"publisher\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"mainEntityOfPage\": { \"@type\": \"WebPage\", \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F\" }\n}\n",[1134,1142,1143],{"type":1136},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    { \"@type\": \"ListItem\", \"position\": 1, \"name\": \"Home\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 2, \"name\": \"Image & Media Optimization\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 3, \"name\": \"Responsive Images with srcset and sizes\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 4, \"name\": \"sizes=auto vs Manual sizes for Lazy Images\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F\" }\n  ]\n}\n",[1145,1146,1147],"style",{},"html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}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}",{"title":366,"searchDepth":401,"depth":401,"links":1149},[1150,1151,1152,1153,1154,1155,1156],{"id":43,"depth":401,"text":44},{"id":216,"depth":401,"text":217},{"id":314,"depth":401,"text":315},{"id":349,"depth":401,"text":350},{"id":697,"depth":401,"text":698},{"id":992,"depth":401,"text":993},{"id":1110,"depth":401,"text":1111},"Hand-written sizes drift from the CSS the moment layout changes. auto fixes that for lazy images only — here is where each belongs.","md",{"slug":1160,"type":1161,"breadcrumb":1162,"datePublished":1170,"dateModified":1170},"sizes-auto-vs-manual-sizes-for-lazy-images","article",[1163,1166,1167,1168],{"name":1164,"url":1165},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1169},"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002F","2026-08-01",true,"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images",{"title":1174,"description":1175},"sizes=auto vs Manual sizes for Lazy-Loaded Images","sizes=auto lets the browser use the real layout width for lazy images, removing hand-maintained media queries — but only for loading=lazy. When each one wins.","image-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fsizes-auto-vs-manual-sizes-for-lazy-images\u002Findex","svFjsJB6h3iFKmG1ND7xVRKsDKq3K-NapcIxD5ScbBE",[1179,1183],{"title":1180,"path":1181,"stem":1182},"Fixing Blurry Images on High-DPI Displays","\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Ffixing-blurry-images-on-high-dpi-displays","image-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Ffixing-blurry-images-on-high-dpi-displays\u002Findex",{"title":1184,"path":1185,"stem":1186},"Serving AVIF and WebP with Fallbacks","\u002Fimage-media-optimization\u002Fserving-avif-and-webp-with-fallbacks","image-media-optimization\u002Fserving-avif-and-webp-with-fallbacks\u002Findex",1785622407200]