[{"data":1,"prerenderedAt":1619},["ShallowReactive",2],{"content:\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time":3,"surroundings:\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time":1610},{"id":4,"title":5,"body":6,"description":1591,"extension":1592,"meta":1593,"navigation":1604,"path":1605,"seo":1606,"stem":1608,"__hash__":1609},"content\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time\u002Findex.md","Generating Responsive Images at Build Time",{"type":7,"value":8,"toc":1574},"minimark",[9,14,34,53,209,214,246,250,256,270,276,282,356,360,365,368,372,903,906,910,1217,1221,1228,1360,1364,1371,1375,1382,1386,1394,1398,1429,1433,1439,1445,1451,1457,1461,1473,1482,1491,1500,1512,1523,1532,1536,1559,1564,1567,1570],[10,11,13],"h1",{"id":12},"how-to-generate-responsive-images-at-build-time","How to Generate Responsive Images at Build Time",[15,16,17,18,23,24,28,29,33],"p",{},"This guide automates ",[19,20,22],"a",{"href":21},"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002F","Responsive Images with srcset and sizes",", part of ",[19,25,27],{"href":26},"\u002Fimage-media-optimization\u002F","Image & Media Optimization",". Hand-written ",[30,31,32],"code",{},"srcset"," attributes do not scale: someone has to export five widths in three formats for every image, keep filenames consistent, record dimensions, and update everything when an image changes. In practice teams skip it, and pages ship one large JPEG to every device.",[15,35,36,37,40,41,44,45,48,49,52],{},"A build-time pipeline removes the manual work. Source images live in the repository (or a CMS export) at high resolution; the build generates a fixed set of widths in AVIF, WebP and a JPEG fallback, records intrinsic dimensions, optionally produces placeholders, and gives templates a helper that emits the right ",[30,38,39],{},"\u003Cpicture>"," or ",[30,42,43],{},"\u003Cimg srcset>",". Static-site generators and frameworks often provide this (Astro's ",[30,46,47],{},"\u003CImage>",", Nuxt Image's static provider, Eleventy Image, Next.js image optimisation), and a small ",[30,50,51],{},"sharp"," script can do it for anything else.",[15,54,55],{},[56,57,63,64,63,71,63,75,63,78,63,96,63,104,63,110,63,118,63,125,63,130,63,133,63,137,63,140,63,144,63,147,63,151,63,154,63,157,63,163,63,167,63,171,63,175,63,178,63,182,63,185,63,188,63,197,63,201,63,205,63],"svg",{"viewBox":58,"width":59,"role":60,"ariaLabel":61,"style":62},"0 0 760 150","100%","img","Pipeline from source images through resizing and format conversion to hashed outputs and template markup.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[65,66],"rect",{"className":67,"x":69,"y":69,"width":59,"height":59,"fill":70},[68],"svg-canvas","0","#ffffff",[72,73,74],"title",{},"Build-time responsive image pipeline",[76,77,61],"desc",{},[79,80,81],"defs",{},[82,83,90],"marker",{"id":84,"viewBox":85,"refX":86,"refY":87,"markerWidth":88,"markerHeight":88,"orient":89},"fadbaf9e94","0 0 10 10","9","5","7","auto-start-reverse",[91,92],"path",{"d":93,"fill":94,"style":95},"M0 0 L10 5 L0 10 z","currentColor","fill-opacity:0.7",[65,97],{"x":98,"y":98,"width":99,"height":100,"rx":101,"fill":102,"stroke":94,"style":103},"1","758","148","10","none","stroke-opacity:0.18",[105,106,74],"text",{"x":107,"y":108,"fill":94,"style":109},"28.0","34.0","font-size:16px;font-weight:700",[65,111],{"x":107,"y":112,"width":113,"height":114,"rx":115,"fill":116,"stroke":116,"style":117},"56.0","108.8","72.0","6","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[105,119,124],{"x":120,"y":121,"fill":94,"style":122,"textAnchor":123},"82.4","78.0","font-size:13px;font-weight:700","middle","Source image",[105,126,129],{"x":120,"y":127,"fill":94,"style":128,"textAnchor":123},"96.0","font-size:12px","high-res master",[65,131],{"x":132,"y":112,"width":113,"height":114,"rx":115,"fill":116,"stroke":116,"style":117},"176.8",[105,134,136],{"x":135,"y":121,"fill":94,"style":122,"textAnchor":123},"231.2","Resize",[105,138,139],{"x":135,"y":127,"fill":94,"style":128,"textAnchor":123},"480\u002F800\u002F1200\u002F160",[105,141,143],{"x":135,"y":142,"fill":94,"style":128,"textAnchor":123},"112.0","0\u002F2000",[65,145],{"x":146,"y":112,"width":113,"height":114,"rx":115,"fill":116,"stroke":116,"style":117},"325.6",[105,148,150],{"x":149,"y":121,"fill":94,"style":122,"textAnchor":123},"380.0","Encode",[105,152,153],{"x":149,"y":127,"fill":94,"style":128,"textAnchor":123},"AVIF + WebP +",[105,155,156],{"x":149,"y":142,"fill":94,"style":128,"textAnchor":123},"JPEG",[65,158],{"x":159,"y":112,"width":113,"height":114,"rx":115,"fill":160,"stroke":161,"style":162},"474.4","#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[105,164,166],{"x":165,"y":121,"fill":94,"style":122,"textAnchor":123},"528.8","Hash +",[105,168,170],{"x":165,"y":169,"fill":94,"style":122,"textAnchor":123},"95.0","manifest",[105,172,174],{"x":165,"y":173,"fill":94,"style":128,"textAnchor":123},"113.0","dims, URLs",[65,176],{"x":177,"y":112,"width":113,"height":114,"rx":115,"fill":116,"stroke":116,"style":117},"623.2",[105,179,181],{"x":180,"y":121,"fill":94,"style":122,"textAnchor":123},"677.6","Template",[105,183,184],{"x":180,"y":169,"fill":94,"style":122,"textAnchor":123},"helper",[105,186,187],{"x":180,"y":173,"fill":94,"style":128,"textAnchor":123},"srcset markup",[189,190],"line",{"x1":191,"y1":192,"x2":193,"y2":192,"stroke":94,"strokeWidth":194,"style":195,"markerEnd":196},"136.8","92.0","174.8","1.5","stroke-opacity:0.6","url(#fadbaf9e94)",[189,198],{"x1":199,"y1":192,"x2":200,"y2":192,"stroke":94,"strokeWidth":194,"style":195,"markerEnd":196},"285.6","323.6",[189,202],{"x1":203,"y1":192,"x2":204,"y2":192,"stroke":94,"strokeWidth":194,"style":195,"markerEnd":196},"434.4","472.4",[189,206],{"x1":207,"y1":192,"x2":208,"y2":192,"stroke":94,"strokeWidth":194,"style":195,"markerEnd":196},"583.2","621.2",[210,211,213],"h2",{"id":212},"rapid-diagnosis","Rapid Diagnosis",[215,216,217,225,234,240],"ul",{},[218,219,220,224],"li",{},[221,222,223],"strong",{},"Count image variants in the build output."," One file per image means no responsive images.",[218,226,227,230,231,233],{},[221,228,229],{},"Check templates for srcset."," Missing or hand-written ",[30,232,32],{}," on content images indicates no pipeline.",[218,235,236,239],{},[221,237,238],{},"Compare natural and rendered sizes."," Images much larger than their rendered width times DPR are wasted bytes and decode time.",[218,241,242,245],{},[221,243,244],{},"Check build times."," Pipelines that re-encode every image on every build slow CI; caching matters.",[210,247,249],{"id":248},"root-cause-analysis","Root Cause Analysis",[15,251,252,255],{},[221,253,254],{},"1. Manual exports."," Variants are produced by hand and inevitably drift or are skipped.",[15,257,258,261,262,265,266,269],{},[221,259,260],{},"2. No dimension metadata."," Templates cannot emit ",[30,263,264],{},"width","\u002F",[30,267,268],{},"height",", causing CLS.",[15,271,272,275],{},[221,273,274],{},"3. Too many or too few widths."," Generating every 100px wastes build time and storage; generating two widths leaves big gaps.",[15,277,278,281],{},[221,279,280],{},"4. No caching."," Encoding AVIF is slow; re-encoding unchanged images on every build makes the pipeline painful and likely to be disabled.",[15,283,284],{},[56,285,63,288,63,291,63,294,63,296,63,299,63,301,63,308,63,315,63,320,63,324,63,329,63,333,63,337,63,340,63,344,63,348,63,352,63],{"viewBox":286,"width":59,"role":60,"ariaLabel":287,"style":62},"0 0 760 194","Bar chart of bytes downloaded for a product card image with no pipeline versus build-generated responsive variants.",[65,289],{"className":290,"x":69,"y":69,"width":59,"height":59,"fill":70},[68],[72,292,293],{},"Bytes for a 400px-wide product card image on a DPR 2 phone",[76,295,287],{},[65,297],{"x":98,"y":98,"width":99,"height":298,"rx":101,"fill":102,"stroke":94,"style":103},"192",[105,300,293],{"x":107,"y":108,"fill":94,"style":109},[105,302,307],{"x":303,"y":304,"fill":94,"style":305,"textAnchor":306},"172.4","70.0","font-size:13px","end","Single 2400px JPEG",[65,309],{"x":310,"y":112,"width":311,"height":312,"rx":313,"fill":160,"stroke":161,"style":314},"184.4","483.6","19","3","fill-opacity:0.7;stroke-opacity:0.9",[105,316,319],{"x":317,"y":304,"fill":94,"style":318},"674.0","font-size:12px;font-weight:600","410KB",[105,321,323],{"x":303,"y":322,"fill":94,"style":305,"textAnchor":306},"101.0","800w JPEG from pipeline",[65,325],{"x":310,"y":326,"width":327,"height":312,"rx":313,"fill":116,"stroke":116,"style":328},"87.0","108.5","fill-opacity:0.55;stroke-opacity:0.9",[105,330,332],{"x":331,"y":322,"fill":94,"style":318},"298.9","92KB",[105,334,336],{"x":303,"y":335,"fill":94,"style":305,"textAnchor":306},"132.0","800w WebP",[65,338],{"x":310,"y":339,"width":114,"height":312,"rx":313,"fill":116,"stroke":116,"style":328},"118.0",[105,341,343],{"x":342,"y":335,"fill":94,"style":318},"262.4","61KB",[105,345,347],{"x":303,"y":346,"fill":94,"style":305,"textAnchor":306},"163.0","800w AVIF",[65,349],{"x":310,"y":350,"width":351,"height":312,"rx":313,"fill":116,"stroke":116,"style":328},"149.0","46.0",[105,353,355],{"x":354,"y":346,"fill":94,"style":318},"236.4","39KB",[210,357,359],{"id":358},"step-by-step-resolution","Step-by-Step Resolution",[361,362,364],"h3",{"id":363},"_1-choose-a-width-ladder","1. Choose a width ladder",[15,366,367],{},"Pick widths that cover your layouts at common DPRs with modest gaps — for example 320, 480, 640, 800, 1200, 1600, 2000. More widths mean closer matches but more build time and storage; five to seven is typical.",[361,369,371],{"id":370},"_2-generate-variants-with-sharp-and-cache-by-content-hash","2. Generate variants with sharp and cache by content hash",[373,374,379],"pre",{"className":375,"code":376,"language":377,"meta":378,"style":378},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F scripts\u002Fimages.mjs\nimport sharp from 'sharp';\nimport { createHash } from 'node:crypto';\nimport { readFile, writeFile, mkdir, access } from 'node:fs\u002Fpromises';\nconst WIDTHS = [480, 800, 1200, 1600, 2000];\nexport async function processImage(src) {\n  const buf = await readFile(src);\n  const hash = createHash('sha256').update(buf).digest('hex').slice(0, 10);\n  const { width, height } = await sharp(buf).metadata();\n  const variants = [];\n  for (const w of WIDTHS.filter((w) => w \u003C= width)) {\n    for (const [fmt, opts] of [['avif', { quality: 50 }], ['webp', { quality: 75 }], ['jpeg', { quality: 78, mozjpeg: true }]]) {\n      const out = `dist\u002Fimg\u002F${hash}-${w}.${fmt === 'jpeg' ? 'jpg' : fmt}`;\n      try { await access(out); } catch { await sharp(buf).resize(w).toFormat(fmt, opts).toFile(out); }\n      variants.push({ w, fmt, url: out.replace('dist', '') });\n    }\n  }\n  return { width, height, variants };\n}\n\u002F\u002F trade-off: AVIF encoding is CPU-heavy; the existence check caches by content\n\u002F\u002F hash across builds. Persist dist\u002Fimg between CI runs or the cache is useless.\n","javascript","",[30,380,381,389,410,425,440,483,509,529,580,613,626,672,740,790,836,864,870,876,885,891,897],{"__ignoreMap":378},[382,383,385],"span",{"class":189,"line":384},1,[382,386,388],{"class":387},"sjfSM","\u002F\u002F scripts\u002Fimages.mjs\n",[382,390,392,396,400,403,407],{"class":189,"line":391},2,[382,393,395],{"class":394},"sPARh","import",[382,397,399],{"class":398},"saISM"," sharp ",[382,401,402],{"class":394},"from",[382,404,406],{"class":405},"sZ8jY"," 'sharp'",[382,408,409],{"class":398},";\n",[382,411,413,415,418,420,423],{"class":189,"line":412},3,[382,414,395],{"class":394},[382,416,417],{"class":398}," { createHash } ",[382,419,402],{"class":394},[382,421,422],{"class":405}," 'node:crypto'",[382,424,409],{"class":398},[382,426,428,430,433,435,438],{"class":189,"line":427},4,[382,429,395],{"class":394},[382,431,432],{"class":398}," { readFile, writeFile, mkdir, access } ",[382,434,402],{"class":394},[382,436,437],{"class":405}," 'node:fs\u002Fpromises'",[382,439,409],{"class":398},[382,441,443,446,450,453,456,459,462,465,467,470,472,475,477,480],{"class":189,"line":442},5,[382,444,445],{"class":394},"const",[382,447,449],{"class":448},"sPXB4"," WIDTHS",[382,451,452],{"class":394}," =",[382,454,455],{"class":398}," [",[382,457,458],{"class":448},"480",[382,460,461],{"class":398},", ",[382,463,464],{"class":448},"800",[382,466,461],{"class":398},[382,468,469],{"class":448},"1200",[382,471,461],{"class":398},[382,473,474],{"class":448},"1600",[382,476,461],{"class":398},[382,478,479],{"class":448},"2000",[382,481,482],{"class":398},"];\n",[382,484,486,489,492,495,499,502,506],{"class":189,"line":485},6,[382,487,488],{"class":394},"export",[382,490,491],{"class":394}," async",[382,493,494],{"class":394}," function",[382,496,498],{"class":497},"smZ65"," processImage",[382,500,501],{"class":398},"(",[382,503,505],{"class":504},"sQw3B","src",[382,507,508],{"class":398},") {\n",[382,510,512,515,518,520,523,526],{"class":189,"line":511},7,[382,513,514],{"class":394},"  const",[382,516,517],{"class":448}," buf",[382,519,452],{"class":394},[382,521,522],{"class":394}," await",[382,524,525],{"class":497}," readFile",[382,527,528],{"class":398},"(src);\n",[382,530,532,534,537,539,542,544,547,550,553,556,559,561,564,566,569,571,573,575,577],{"class":189,"line":531},8,[382,533,514],{"class":394},[382,535,536],{"class":448}," hash",[382,538,452],{"class":394},[382,540,541],{"class":497}," createHash",[382,543,501],{"class":398},[382,545,546],{"class":405},"'sha256'",[382,548,549],{"class":398},").",[382,551,552],{"class":497},"update",[382,554,555],{"class":398},"(buf).",[382,557,558],{"class":497},"digest",[382,560,501],{"class":398},[382,562,563],{"class":405},"'hex'",[382,565,549],{"class":398},[382,567,568],{"class":497},"slice",[382,570,501],{"class":398},[382,572,69],{"class":448},[382,574,461],{"class":398},[382,576,101],{"class":448},[382,578,579],{"class":398},");\n",[382,581,583,585,588,590,592,594,597,600,602,605,607,610],{"class":189,"line":582},9,[382,584,514],{"class":394},[382,586,587],{"class":398}," { ",[382,589,264],{"class":448},[382,591,461],{"class":398},[382,593,268],{"class":448},[382,595,596],{"class":398}," } ",[382,598,599],{"class":394},"=",[382,601,522],{"class":394},[382,603,604],{"class":497}," sharp",[382,606,555],{"class":398},[382,608,609],{"class":497},"metadata",[382,611,612],{"class":398},"();\n",[382,614,616,618,621,623],{"class":189,"line":615},10,[382,617,514],{"class":394},[382,619,620],{"class":448}," variants",[382,622,452],{"class":394},[382,624,625],{"class":398}," [];\n",[382,627,629,632,635,637,640,643,645,648,651,654,657,660,663,666,669],{"class":189,"line":628},11,[382,630,631],{"class":394},"  for",[382,633,634],{"class":398}," (",[382,636,445],{"class":394},[382,638,639],{"class":448}," w",[382,641,642],{"class":394}," of",[382,644,449],{"class":448},[382,646,647],{"class":398},".",[382,649,650],{"class":497},"filter",[382,652,653],{"class":398},"((",[382,655,656],{"class":504},"w",[382,658,659],{"class":398},") ",[382,661,662],{"class":394},"=>",[382,664,665],{"class":398}," w ",[382,667,668],{"class":394},"\u003C=",[382,670,671],{"class":398}," width)) {\n",[382,673,675,678,680,682,684,687,689,692,695,698,701,704,707,710,713,716,718,721,723,726,728,731,734,737],{"class":189,"line":674},12,[382,676,677],{"class":394},"    for",[382,679,634],{"class":398},[382,681,445],{"class":394},[382,683,455],{"class":398},[382,685,686],{"class":448},"fmt",[382,688,461],{"class":398},[382,690,691],{"class":448},"opts",[382,693,694],{"class":398},"] ",[382,696,697],{"class":394},"of",[382,699,700],{"class":398}," [[",[382,702,703],{"class":405},"'avif'",[382,705,706],{"class":398},", { quality: ",[382,708,709],{"class":448},"50",[382,711,712],{"class":398}," }], [",[382,714,715],{"class":405},"'webp'",[382,717,706],{"class":398},[382,719,720],{"class":448},"75",[382,722,712],{"class":398},[382,724,725],{"class":405},"'jpeg'",[382,727,706],{"class":398},[382,729,730],{"class":448},"78",[382,732,733],{"class":398},", mozjpeg: ",[382,735,736],{"class":448},"true",[382,738,739],{"class":398}," }]]) {\n",[382,741,743,746,749,751,754,757,760,762,765,767,770,773,776,779,782,785,788],{"class":189,"line":742},13,[382,744,745],{"class":394},"      const",[382,747,748],{"class":448}," out",[382,750,452],{"class":394},[382,752,753],{"class":405}," `dist\u002Fimg\u002F${",[382,755,756],{"class":398},"hash",[382,758,759],{"class":405},"}-${",[382,761,656],{"class":398},[382,763,764],{"class":405},"}.${",[382,766,686],{"class":398},[382,768,769],{"class":394}," ===",[382,771,772],{"class":405}," 'jpeg'",[382,774,775],{"class":394}," ?",[382,777,778],{"class":405}," 'jpg'",[382,780,781],{"class":394}," :",[382,783,784],{"class":398}," fmt",[382,786,787],{"class":405},"}`",[382,789,409],{"class":398},[382,791,793,796,798,801,804,807,810,812,814,816,818,821,824,827,830,833],{"class":189,"line":792},14,[382,794,795],{"class":394},"      try",[382,797,587],{"class":398},[382,799,800],{"class":394},"await",[382,802,803],{"class":497}," access",[382,805,806],{"class":398},"(out); } ",[382,808,809],{"class":394},"catch",[382,811,587],{"class":398},[382,813,800],{"class":394},[382,815,604],{"class":497},[382,817,555],{"class":398},[382,819,820],{"class":497},"resize",[382,822,823],{"class":398},"(w).",[382,825,826],{"class":497},"toFormat",[382,828,829],{"class":398},"(fmt, opts).",[382,831,832],{"class":497},"toFile",[382,834,835],{"class":398},"(out); }\n",[382,837,839,842,845,848,851,853,856,858,861],{"class":189,"line":838},15,[382,840,841],{"class":398},"      variants.",[382,843,844],{"class":497},"push",[382,846,847],{"class":398},"({ w, fmt, url: out.",[382,849,850],{"class":497},"replace",[382,852,501],{"class":398},[382,854,855],{"class":405},"'dist'",[382,857,461],{"class":398},[382,859,860],{"class":405},"''",[382,862,863],{"class":398},") });\n",[382,865,867],{"class":189,"line":866},16,[382,868,869],{"class":398},"    }\n",[382,871,873],{"class":189,"line":872},17,[382,874,875],{"class":398},"  }\n",[382,877,879,882],{"class":189,"line":878},18,[382,880,881],{"class":394},"  return",[382,883,884],{"class":398}," { width, height, variants };\n",[382,886,888],{"class":189,"line":887},19,[382,889,890],{"class":398},"}\n",[382,892,894],{"class":189,"line":893},20,[382,895,896],{"class":387},"\u002F\u002F trade-off: AVIF encoding is CPU-heavy; the existence check caches by content\n",[382,898,900],{"class":189,"line":899},21,[382,901,902],{"class":387},"\u002F\u002F hash across builds. Persist dist\u002Fimg between CI runs or the cache is useless.\n",[15,904,905],{},"Expected outcome: every source image has right-sized variants in three formats, named by content hash.",[361,907,909],{"id":908},"_3-emit-markup-from-a-template-helper","3. Emit markup from a template helper",[373,911,913],{"className":375,"code":912,"language":377,"meta":378,"style":378},"export function picture({ width, height, variants }, { alt, sizes, priority = false }) {\n  const set = (fmt) => variants.filter((v) => v.fmt === fmt).map((v) => `${v.url} ${v.w}w`).join(', ');\n  const fallback = variants.filter((v) => v.fmt === 'jpeg').at(-1).url;\n  return `\u003Cpicture>\n  \u003Csource type=\"image\u002Favif\" srcset=\"${set('avif')}\" sizes=\"${sizes}\">\n  \u003Csource type=\"image\u002Fwebp\" srcset=\"${set('webp')}\" sizes=\"${sizes}\">\n  \u003Cimg src=\"${fallback}\" srcset=\"${set('jpeg')}\" sizes=\"${sizes}\" width=\"${width}\" height=\"${height}\"\n       alt=\"${alt}\" ${priority ? 'fetchpriority=\"high\"' : 'loading=\"lazy\" decoding=\"async\"'}>\n\u003C\u002Fpicture>`;\n}\n\u002F\u002F trade-off: the helper needs an accurate sizes value per usage; a wrong sizes\n\u002F\u002F makes the browser choose too large or too small a variant.\n",[30,914,915,962,1047,1089,1096,1119,1138,1174,1196,1203,1207,1212],{"__ignoreMap":378},[382,916,917,919,921,924,927,929,931,933,935,938,941,944,946,949,951,954,956,959],{"class":189,"line":384},[382,918,488],{"class":394},[382,920,494],{"class":394},[382,922,923],{"class":497}," picture",[382,925,926],{"class":398},"({ ",[382,928,264],{"class":504},[382,930,461],{"class":398},[382,932,268],{"class":504},[382,934,461],{"class":398},[382,936,937],{"class":504},"variants",[382,939,940],{"class":398}," }, { ",[382,942,943],{"class":504},"alt",[382,945,461],{"class":398},[382,947,948],{"class":504},"sizes",[382,950,461],{"class":398},[382,952,953],{"class":504},"priority",[382,955,452],{"class":394},[382,957,958],{"class":448}," false",[382,960,961],{"class":398}," }) {\n",[382,963,964,966,969,971,973,975,977,979,982,984,986,989,991,993,996,999,1002,1005,1007,1009,1011,1013,1016,1018,1020,1023,1026,1028,1030,1032,1035,1037,1040,1042,1045],{"class":189,"line":391},[382,965,514],{"class":394},[382,967,968],{"class":497}," set",[382,970,452],{"class":394},[382,972,634],{"class":398},[382,974,686],{"class":504},[382,976,659],{"class":398},[382,978,662],{"class":394},[382,980,981],{"class":398}," variants.",[382,983,650],{"class":497},[382,985,653],{"class":398},[382,987,988],{"class":504},"v",[382,990,659],{"class":398},[382,992,662],{"class":394},[382,994,995],{"class":398}," v.fmt ",[382,997,998],{"class":394},"===",[382,1000,1001],{"class":398}," fmt).",[382,1003,1004],{"class":497},"map",[382,1006,653],{"class":398},[382,1008,988],{"class":504},[382,1010,659],{"class":398},[382,1012,662],{"class":394},[382,1014,1015],{"class":405}," `${",[382,1017,988],{"class":398},[382,1019,647],{"class":405},[382,1021,1022],{"class":398},"url",[382,1024,1025],{"class":405},"} ${",[382,1027,988],{"class":398},[382,1029,647],{"class":405},[382,1031,656],{"class":398},[382,1033,1034],{"class":405},"}w`",[382,1036,549],{"class":398},[382,1038,1039],{"class":497},"join",[382,1041,501],{"class":398},[382,1043,1044],{"class":405},"', '",[382,1046,579],{"class":398},[382,1048,1049,1051,1054,1056,1058,1060,1062,1064,1066,1068,1070,1072,1074,1076,1079,1081,1084,1086],{"class":189,"line":412},[382,1050,514],{"class":394},[382,1052,1053],{"class":448}," fallback",[382,1055,452],{"class":394},[382,1057,981],{"class":398},[382,1059,650],{"class":497},[382,1061,653],{"class":398},[382,1063,988],{"class":504},[382,1065,659],{"class":398},[382,1067,662],{"class":394},[382,1069,995],{"class":398},[382,1071,998],{"class":394},[382,1073,772],{"class":405},[382,1075,549],{"class":398},[382,1077,1078],{"class":497},"at",[382,1080,501],{"class":398},[382,1082,1083],{"class":394},"-",[382,1085,98],{"class":448},[382,1087,1088],{"class":398},").url;\n",[382,1090,1091,1093],{"class":189,"line":427},[382,1092,881],{"class":394},[382,1094,1095],{"class":405}," `\u003Cpicture>\n",[382,1097,1098,1101,1104,1106,1108,1111,1114,1116],{"class":189,"line":442},[382,1099,1100],{"class":405},"  \u003Csource type=\"image\u002Favif\" srcset=\"${",[382,1102,1103],{"class":497},"set",[382,1105,501],{"class":405},[382,1107,703],{"class":405},[382,1109,1110],{"class":405},")",[382,1112,1113],{"class":405},"}\" sizes=\"${",[382,1115,948],{"class":398},[382,1117,1118],{"class":405},"}\">\n",[382,1120,1121,1124,1126,1128,1130,1132,1134,1136],{"class":189,"line":485},[382,1122,1123],{"class":405},"  \u003Csource type=\"image\u002Fwebp\" srcset=\"${",[382,1125,1103],{"class":497},[382,1127,501],{"class":405},[382,1129,715],{"class":405},[382,1131,1110],{"class":405},[382,1133,1113],{"class":405},[382,1135,948],{"class":398},[382,1137,1118],{"class":405},[382,1139,1140,1143,1146,1149,1151,1153,1155,1157,1159,1161,1164,1166,1169,1171],{"class":189,"line":511},[382,1141,1142],{"class":405},"  \u003Cimg src=\"${",[382,1144,1145],{"class":398},"fallback",[382,1147,1148],{"class":405},"}\" srcset=\"${",[382,1150,1103],{"class":497},[382,1152,501],{"class":405},[382,1154,725],{"class":405},[382,1156,1110],{"class":405},[382,1158,1113],{"class":405},[382,1160,948],{"class":398},[382,1162,1163],{"class":405},"}\" width=\"${",[382,1165,264],{"class":398},[382,1167,1168],{"class":405},"}\" height=\"${",[382,1170,268],{"class":398},[382,1172,1173],{"class":405},"}\"\n",[382,1175,1176,1179,1181,1184,1186,1188,1191,1193],{"class":189,"line":531},[382,1177,1178],{"class":405},"       alt=\"${",[382,1180,943],{"class":398},[382,1182,1183],{"class":405},"}\" ${",[382,1185,953],{"class":398},[382,1187,775],{"class":394},[382,1189,1190],{"class":405}," 'fetchpriority=\"high\"'",[382,1192,781],{"class":394},[382,1194,1195],{"class":405}," 'loading=\"lazy\" decoding=\"async\"'}>\n",[382,1197,1198,1201],{"class":189,"line":582},[382,1199,1200],{"class":405},"\u003C\u002Fpicture>`",[382,1202,409],{"class":398},[382,1204,1205],{"class":189,"line":615},[382,1206,890],{"class":398},[382,1208,1209],{"class":189,"line":628},[382,1210,1211],{"class":387},"\u002F\u002F trade-off: the helper needs an accurate sizes value per usage; a wrong sizes\n",[382,1213,1214],{"class":189,"line":674},[382,1215,1216],{"class":387},"\u002F\u002F makes the browser choose too large or too small a variant.\n",[361,1218,1220],{"id":1219},"_4-serve-with-immutable-caching","4. Serve with immutable caching",[15,1222,1223,1224,1227],{},"Hashed filenames can be cached for a year with ",[30,1225,1226],{},"immutable","; changed images get new hashes automatically.",[15,1229,1230],{},[56,1231,63,1234,63,1237,63,1240,63,1242,63,1245,63,1247,63,1252,63,1259,63,1263,63,1267,63,1270,63,1274,63,1278,63,1282,63,1284,63,1287,63,1289,63,1292,63,1295,63,1299,63,1301,63,1304,63,1306,63,1309,63,1312,63,1316,63,1318,63,1321,63,1323,63,1326,63,1329,63,1333,63,1335,63,1338,63,1340,63,1343,63,1346,63,1350,63,1352,63,1355,63,1357,63],{"viewBox":1232,"width":59,"role":60,"ariaLabel":1233,"style":62},"0 0 760 258","Common ways to generate responsive images at build time in different frameworks and tools.",[65,1235],{"className":1236,"x":69,"y":69,"width":59,"height":59,"fill":70},[68],[72,1238,1239],{},"Build-time options by stack",[76,1241,1233],{},[65,1243],{"x":98,"y":98,"width":99,"height":1244,"rx":101,"fill":102,"stroke":94,"style":103},"256",[105,1246,1239],{"x":107,"y":108,"fill":94,"style":109},[65,1248],{"x":107,"y":112,"width":1249,"height":1250,"rx":69,"fill":94,"stroke":94,"style":1251},"106.4","30.0","fill-opacity:0.06;stroke-opacity:0.4",[105,1253,1258],{"x":1254,"y":1255,"fill":94,"style":1256,"textAnchor":1257},"38.0","75.5","font-size:12.5px;font-weight:700","start","Stack",[65,1260],{"x":1261,"y":112,"width":1262,"height":1250,"rx":69,"fill":94,"stroke":94,"style":1251},"134.4","298.8",[105,1264,1266],{"x":1265,"y":1255,"fill":94,"style":1256,"textAnchor":123},"283.8","Tool",[65,1268],{"x":1269,"y":112,"width":1262,"height":1250,"rx":69,"fill":94,"stroke":94,"style":1251},"433.2",[105,1271,1273],{"x":1272,"y":1255,"fill":94,"style":1256,"textAnchor":123},"582.6","Notes",[65,1275],{"x":107,"y":1276,"width":1249,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},"86.0","stroke-opacity:0.35",[105,1279,1281],{"x":1254,"y":1280,"fill":94,"style":1256,"textAnchor":1257},"105.5","Astro",[65,1283],{"x":1261,"y":1276,"width":1262,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},[105,1285,1286],{"x":1265,"y":1280,"fill":94,"style":128,"textAnchor":123},"Image \u002F Picture components",[65,1288],{"x":1269,"y":1276,"width":1262,"height":1250,"rx":69,"fill":116,"stroke":116,"style":117},[105,1290,1291],{"x":1272,"y":1280,"fill":94,"style":128,"textAnchor":123},"built-in, sharp-based",[65,1293],{"x":107,"y":1294,"width":1249,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},"116.0",[105,1296,1298],{"x":1254,"y":1297,"fill":94,"style":1256,"textAnchor":1257},"135.5","Nuxt",[65,1300],{"x":1261,"y":1294,"width":1262,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},[105,1302,1303],{"x":1265,"y":1297,"fill":94,"style":128,"textAnchor":123},"@nuxt\u002Fimage (ipx \u002F static)",[65,1305],{"x":1269,"y":1294,"width":1262,"height":1250,"rx":69,"fill":116,"stroke":116,"style":117},[105,1307,1308],{"x":1272,"y":1297,"fill":94,"style":128,"textAnchor":123},"presets, placeholders",[65,1310],{"x":107,"y":1311,"width":1249,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},"146.0",[105,1313,1315],{"x":1254,"y":1314,"fill":94,"style":1256,"textAnchor":1257},"165.5","Eleventy",[65,1317],{"x":1261,"y":1311,"width":1262,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},[105,1319,1320],{"x":1265,"y":1314,"fill":94,"style":128,"textAnchor":123},"eleventy-img",[65,1322],{"x":1269,"y":1311,"width":1262,"height":1250,"rx":69,"fill":116,"stroke":116,"style":117},[105,1324,1325],{"x":1272,"y":1314,"fill":94,"style":128,"textAnchor":123},"shortcode emits picture",[65,1327],{"x":107,"y":1328,"width":1249,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},"176.0",[105,1330,1332],{"x":1254,"y":1331,"fill":94,"style":1256,"textAnchor":1257},"195.5","Custom \u002F other",[65,1334],{"x":1261,"y":1328,"width":1262,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},[105,1336,1337],{"x":1265,"y":1331,"fill":94,"style":128,"textAnchor":123},"sharp script + helper",[65,1339],{"x":1269,"y":1328,"width":1262,"height":1250,"rx":69,"fill":94,"stroke":94,"style":1251},[105,1341,1342],{"x":1272,"y":1331,"fill":94,"style":128,"textAnchor":123},"full control, own caching",[65,1344],{"x":107,"y":1345,"width":1249,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},"206.0",[105,1347,1349],{"x":1254,"y":1348,"fill":94,"style":1256,"textAnchor":1257},"225.5","Next.js",[65,1351],{"x":1261,"y":1345,"width":1262,"height":1250,"rx":69,"fill":102,"stroke":94,"style":1277},[105,1353,1354],{"x":1265,"y":1348,"fill":94,"style":128,"textAnchor":123},"next\u002Fimage",[65,1356],{"x":1269,"y":1345,"width":1262,"height":1250,"rx":69,"fill":94,"stroke":94,"style":1251},[105,1358,1359],{"x":1272,"y":1348,"fill":94,"style":128,"textAnchor":123},"on-demand at runtime or export loader",[210,1361,1363],{"id":1362},"verification","Verification",[15,1365,1366,1367,1370],{},"Check the build output: each source image has the expected variants. In the browser at several widths and DPRs, confirm the chosen ",[30,1368,1369],{},"currentSrc"," is the smallest variant that covers the rendered size. Run Lighthouse's \"Properly size images\" audit; it should pass. Track total image bytes per page view in RUM before and after.",[210,1372,1374],{"id":1373},"worked-example-a-static-marketing-site","Worked Example: A Static Marketing Site",[15,1376,1377,1378,1381],{},"A static marketing site committed 340 images exported at 2400px as JPEG and referenced them directly. Pages averaged 4.2MB of images on mobile. A sharp pipeline with a five-width ladder, AVIF\u002FWebP\u002FJPEG output, content-hash caching persisted in CI, and a ",[30,1379,1380],{},"picture()"," helper used by all templates reduced average mobile image weight to 680KB. The first full build took 9 minutes; subsequent builds with the cache took 25 seconds. LCP p75 on mobile improved by 700ms.",[210,1383,1385],{"id":1384},"build-time-vs-image-cdn","Build-Time vs Image CDN",[15,1387,1388,1389,1393],{},"Build-time generation suits static and mostly-static sites where images are known at build time: it costs nothing at request time and works with any host. Image CDNs suit dynamic catalogues and user uploads, where generating every variant ahead of time is impractical: they transform on first request and cache the result at the edge. Many teams combine them — build-time variants for site chrome and editorial images, an image CDN for catalogue and user content — with one template helper that hides the difference. The guide on ",[19,1390,1392],{"href":1391},"\u002Fimage-media-optimization\u002Fimage-cdns-and-fetchpriority\u002F","image CDNs and fetchpriority"," covers the CDN side.",[210,1395,1397],{"id":1396},"common-mistakes","Common Mistakes",[215,1399,1400,1406,1412,1418],{},[218,1401,1402,1405],{},[221,1403,1404],{},"Upscaling small sources."," Generate only widths up to the source width.",[218,1407,1408,1411],{},[221,1409,1410],{},"Missing dimensions in markup."," The pipeline should return width and height to the template.",[218,1413,1414,1417],{},[221,1415,1416],{},"No cache in CI."," AVIF encoding makes uncached builds slow; teams then disable the pipeline.",[218,1419,1420,63,1426,1428],{},[221,1421,1422,1423,1425],{},"A fixed ",[30,1424,948],{}," everywhere.",[30,1427,948],{}," depends on layout; pass it per usage.",[210,1430,1432],{"id":1431},"edge-cases","Edge Cases",[15,1434,1435,1438],{},[221,1436,1437],{},"CMS images."," If editors upload images at runtime, a build-time pipeline only covers images present at build; use an image CDN or a webhook-triggered build.",[15,1440,1441,1444],{},[221,1442,1443],{},"Transparent PNGs."," Keep alpha: AVIF and WebP support it; fallback should be PNG, not JPEG.",[15,1446,1447,1450],{},[221,1448,1449],{},"Animated images."," Exclude GIFs and animated sources from the still-image pipeline; convert them to video instead.",[15,1452,1453,1456],{},[221,1454,1455],{},"Colour profiles."," Strip or convert to sRGB to avoid colour shifts and save bytes, unless you serve wide-gamut images deliberately.",[210,1458,1460],{"id":1459},"faq","FAQ",[1462,1463,1466,1470],"details",{"className":1464},[1465],"faq-item",[1467,1468,1469],"summary",{},"How many widths should I generate?",[15,1471,1472],{},"Five to seven covering your smallest and largest rendered sizes at DPR 1–3 is typical. Gaps of roughly 30–50% between widths keep wasted bytes small without exploding build time.",[1462,1474,1476,1479],{"className":1475},[1465],[1467,1477,1478],{},"Is AVIF worth the build time?",[15,1480,1481],{},"Usually yes for images that matter (heroes, product photos). With caching by content hash, the encode cost is paid once per image, not per build.",[1462,1483,1485,1488],{"className":1484},[1465],[1467,1486,1487],{},"Should JPEG fallbacks still be generated?",[15,1489,1490],{},"For broad compatibility and email or social previews, yes, though nearly all browsers now support WebP and most support AVIF. Fallbacks cost storage, not user bytes.",[1462,1492,1494,1497],{"className":1493},[1465],[1467,1495,1496],{},"Can the pipeline generate placeholders too?",[15,1498,1499],{},"Yes — dominant colours or tiny LQIP previews can be computed with sharp in the same pass and passed to the template.",[1462,1501,1503,1506],{"className":1502},[1465],[1467,1504,1505],{},"How do I handle images in Markdown content?",[15,1507,1508,1509,1511],{},"Use a Markdown plugin or post-processing step that replaces image references with the ",[30,1510,1380],{}," helper's output, so authors keep writing simple Markdown.",[1462,1513,1515,1518],{"className":1514},[1465],[1467,1516,1517],{},"Does Next.js need a build-time pipeline?",[15,1519,1520,1522],{},[30,1521,1354],{}," optimises on demand at runtime (or via a custom loader to an image CDN). For static exports, use a loader or a build-time tool, since the default optimiser requires a server.",[1462,1524,1526,1529],{"className":1525},[1465],[1467,1527,1528],{},"How do I keep the pipeline fast as the image library grows?",[15,1530,1531],{},"Cache outputs by content hash (and persist the cache between CI runs), process images in parallel with a concurrency limit matched to CPU cores, and skip widths larger than the source. With those three, adding images costs only their own encoding time, once.",[210,1533,1535],{"id":1534},"related","Related",[215,1537,1538,1545,1552],{},[218,1539,1540,1544],{},[19,1541,1543],{"href":1542},"\u002Fimage-media-optimization\u002Fserving-avif-and-webp-with-fallbacks\u002Fbatch-converting-images-with-sharp\u002F","Batch-converting images with sharp"," — the conversion step in depth.",[218,1546,1547,1551],{},[19,1548,1550],{"href":1549},"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fresponsive-images-with-nuxt-image-and-astro\u002F","Responsive images with Nuxt Image and Astro"," — framework-integrated pipelines.",[218,1553,1554,1558],{},[19,1555,1557],{"href":1556},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fhttp-cache-control-headers-explained\u002Fsetting-up-immutable-cache-headers-for-hashed-assets\u002F","Setting up immutable cache headers for hashed assets"," — caching the outputs.",[1560,1561,1563],"script",{"type":1562},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Generate Responsive Images at Build Time\",\n  \"description\": \"Build a pipeline that turns source images into responsive, modern-format variants with correct dimensions, so templates can emit srcset automatically.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Choose a width ladder\",\n      \"text\": \"Pick widths that cover your layouts at common DPRs with modest gaps — for example 320, 480, 640, 800, 1200, 1600, 2000.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Generate variants with sharp and cache by content hash\",\n      \"text\": \"Expected outcome: every source image has right-sized variants in three formats, named by content hash.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Emit markup from a template helper\",\n      \"text\": \"Emit markup from a template helper\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Serve with immutable caching\",\n      \"text\": \"Hashed filenames can be cached for a year with immutable; changed images get new hashes automatically.\"\n    }\n  ]\n}\n",[1560,1565,1566],{"type":1562},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Generate Responsive Images at Build Time\",\n  \"description\": \"Build a pipeline that turns source images into responsive, modern-format variants with correct dimensions, so templates can emit srcset automatically.\",\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\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time\u002F\"\n  }\n}\n",[1560,1568,1569],{"type":1562},"\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\": \"Responsive Images with srcset and sizes\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Generating Responsive Images at Build Time\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time\u002F\"\n    }\n  ]\n}\n",[1571,1572,1573],"style",{},"html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":378,"searchDepth":391,"depth":391,"links":1575},[1576,1577,1578,1584,1585,1586,1587,1588,1589,1590],{"id":212,"depth":391,"text":213},{"id":248,"depth":391,"text":249},{"id":358,"depth":391,"text":359,"children":1579},[1580,1581,1582,1583],{"id":363,"depth":412,"text":364},{"id":370,"depth":412,"text":371},{"id":908,"depth":412,"text":909},{"id":1219,"depth":412,"text":1220},{"id":1362,"depth":391,"text":1363},{"id":1373,"depth":391,"text":1374},{"id":1384,"depth":391,"text":1385},{"id":1396,"depth":391,"text":1397},{"id":1431,"depth":391,"text":1432},{"id":1459,"depth":391,"text":1460},{"id":1534,"depth":391,"text":1535},"Build a pipeline that turns source images into responsive, modern-format variants with correct dimensions, so templates can emit srcset automatically.","md",{"slug":1594,"type":1595,"breadcrumb":1596,"datePublished":1603,"dateModified":1603},"generating-responsive-images-at-build-time","article",[1597,1599,1600,1601],{"name":1598,"url":265},"Home",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1602},"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time\u002F","2026-10-06",true,"\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time",{"title":5,"description":1607},"Generate srcset widths, AVIF\u002FWebP variants, dimensions and placeholders at build time with sharp or framework plugins, so every image ships right-sized.","image-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fgenerating-responsive-images-at-build-time\u002Findex","5DgH-9n4CkejPtEyUDNULuXdQV32qPordjDp_sA6ggg",[1611,1615],{"title":1612,"path":1613,"stem":1614},"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":1616,"path":1617,"stem":1618},"Responsive Images with Nuxt Image and Astro","\u002Fimage-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fresponsive-images-with-nuxt-image-and-astro","image-media-optimization\u002Fresponsive-images-with-srcset-and-sizes\u002Fresponsive-images-with-nuxt-image-and-astro\u002Findex",1791308079627]