[{"data":1,"prerenderedAt":1370},["ShallowReactive",2],{"content:\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp":3,"surroundings:\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp":1361},{"id":4,"title":5,"body":6,"description":1342,"extension":1343,"meta":1344,"navigation":1355,"path":1356,"seo":1357,"stem":1359,"__hash__":1360},"content\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp\u002Findex.md","Lazy-Loading Video Without Hurting LCP",{"type":7,"value":8,"toc":1324},"minimark",[9,14,54,57,200,205,251,255,264,273,279,285,348,352,357,546,550,638,642,907,910,914,926,1061,1065,1068,1072,1083,1087,1101,1105,1123,1127,1157,1161,1173,1181,1191,1197,1201,1221,1233,1242,1251,1264,1273,1282,1286,1309,1314,1317,1320],[10,11,13],"h1",{"id":12},"how-to-lazy-load-video-without-hurting-lcp","How to Lazy-Load Video Without Hurting LCP",[15,16,17,18,23,24,28,29,33,34,37,38,41,42,45,46,49,50,53],"p",{},"This guide is part of ",[19,20,22],"a",{"href":21},"\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002F","Video Performance Optimization"," within ",[19,25,27],{"href":26},"\u002Fimage-media-optimization\u002F","Image & Media Optimization",". Unlike images, ",[30,31,32],"code",{},"\u003Cvideo>"," has no ",[30,35,36],{},"loading=\"lazy\""," attribute. Instead, the ",[30,39,40],{},"preload"," attribute and the presence of ",[30,43,44],{},"src","\u002F",[30,47,48],{},"\u003Csource>"," elements decide what downloads, and browser defaults vary: with ",[30,51,52],{},"preload=\"auto\""," (or the default in some browsers), a video below the fold can start downloading megabytes as soon as the HTML is parsed, competing with the LCP image and CSS on the critical path.",[15,55,56],{},"Lazy loading video means two things: telling the browser not to fetch video data until needed, and loading or playing videos as they approach the viewport. Done correctly, below-the-fold videos cost nothing during load. Done incorrectly — lazy-loading the hero, or removing the poster — it makes LCP worse.",[15,58,59],{},[60,61,67,68,67,75,67,79,67,82,67,91,67,97,67,103,67,110,67,114,67,119,67,122,67,126,67,130,67,134,67,139,67,143,67,145,67,148,67,151,67,155,67,157,67,160,67,162,67,165,67,168,67,171,67,175,67,178,67,180,67,183,67,186,67,190,67,192,67,195,67,197,67],"svg",{"viewBox":62,"width":63,"role":64,"ariaLabel":65,"style":66},"0 0 760 228","100%","img","Comparison of the video preload attribute values by what data the browser fetches before playback.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[69,70],"rect",{"className":71,"x":73,"y":73,"width":63,"height":63,"fill":74},[72],"svg-canvas","0","#ffffff",[76,77,78],"title",{},"What each preload value downloads",[80,81,65],"desc",{},[69,83],{"x":84,"y":84,"width":85,"height":86,"rx":87,"fill":88,"stroke":89,"style":90},"1","758","226","10","none","currentColor","stroke-opacity:0.18",[92,93,78],"text",{"x":94,"y":95,"fill":89,"style":96},"28.0","34.0","font-size:16px;font-weight:700",[69,98],{"x":94,"y":99,"width":100,"height":101,"rx":73,"fill":89,"stroke":89,"style":102},"56.0","133.3","30.0","fill-opacity:0.06;stroke-opacity:0.4",[92,104,109],{"x":105,"y":106,"fill":89,"style":107,"textAnchor":108},"38.0","75.5","font-size:12.5px;font-weight:700","start","preload value",[69,111],{"x":112,"y":99,"width":113,"height":101,"rx":73,"fill":89,"stroke":89,"style":102},"161.3","285.4",[92,115,118],{"x":116,"y":106,"fill":89,"style":107,"textAnchor":117},"304.0","middle","Downloads before play",[69,120],{"x":121,"y":99,"width":113,"height":101,"rx":73,"fill":89,"stroke":89,"style":102},"446.7",[92,123,125],{"x":124,"y":106,"fill":89,"style":107,"textAnchor":117},"589.3","Use for",[69,127],{"x":94,"y":128,"width":100,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},"86.0","stroke-opacity:0.35",[92,131,133],{"x":105,"y":132,"fill":89,"style":107,"textAnchor":108},"105.5","auto",[69,135],{"x":112,"y":128,"width":113,"height":101,"rx":73,"fill":136,"stroke":137,"style":138},"#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[92,140,142],{"x":116,"y":132,"fill":89,"style":141,"textAnchor":117},"font-size:12px","potentially the whole file",[69,144],{"x":121,"y":128,"width":113,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},[92,146,147],{"x":124,"y":132,"fill":89,"style":141,"textAnchor":117},"hero video that plays immediately",[69,149],{"x":94,"y":150,"width":100,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},"116.0",[92,152,154],{"x":105,"y":153,"fill":89,"style":107,"textAnchor":108},"135.5","metadata",[69,156],{"x":112,"y":150,"width":113,"height":101,"rx":73,"fill":89,"stroke":89,"style":102},[92,158,159],{"x":116,"y":153,"fill":89,"style":141,"textAnchor":117},"headers, duration, first frame",[69,161],{"x":121,"y":150,"width":113,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},[92,163,164],{"x":124,"y":153,"fill":89,"style":141,"textAnchor":117},"inline video likely to be played",[69,166],{"x":94,"y":167,"width":100,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},"146.0",[92,169,88],{"x":105,"y":170,"fill":89,"style":107,"textAnchor":108},"165.5",[69,172],{"x":112,"y":167,"width":113,"height":101,"rx":73,"fill":173,"stroke":173,"style":174},"#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[92,176,177],{"x":116,"y":170,"fill":89,"style":141,"textAnchor":117},"nothing",[69,179],{"x":121,"y":167,"width":113,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},[92,181,182],{"x":124,"y":170,"fill":89,"style":141,"textAnchor":117},"below-the-fold and click-to-play",[69,184],{"x":94,"y":185,"width":100,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},"176.0",[92,187,189],{"x":105,"y":188,"fill":89,"style":107,"textAnchor":108},"195.5","(no src until visible)",[69,191],{"x":112,"y":185,"width":113,"height":101,"rx":73,"fill":173,"stroke":173,"style":174},[92,193,194],{"x":116,"y":188,"fill":89,"style":141,"textAnchor":117},"nothing at all",[69,196],{"x":121,"y":185,"width":113,"height":101,"rx":73,"fill":88,"stroke":89,"style":129},[92,198,199],{"x":124,"y":188,"fill":89,"style":141,"textAnchor":117},"autoplay loops further down the page",[201,202,204],"h2",{"id":203},"rapid-diagnosis","Rapid Diagnosis",[206,207,208,216,228,234],"ul",{},[209,210,211,215],"li",{},[212,213,214],"strong",{},"Filter the Network panel by Media"," and reload: any video requests before LCP on templates where video is below the fold are wasted critical-path bytes.",[209,217,218,224,225,227],{},[212,219,220,221,223],{},"Check ",[30,222,40],{}," attributes"," on every ",[30,226,32],{}," (and defaults set by video components).",[209,229,230,233],{},[212,231,232],{},"Check posters."," Videos without posters show empty boxes or rely on the first frame.",[209,235,236,239,240,45,243,246,247,250],{},[212,237,238],{},"Check dimensions."," Videos and their containers need ",[30,241,242],{},"width",[30,244,245],{},"height"," or ",[30,248,249],{},"aspect-ratio"," to avoid layout shift when metadata loads.",[201,252,254],{"id":253},"root-cause-analysis","Root Cause Analysis",[15,256,257,263],{},[212,258,259,260,262],{},"1. Default or ",[30,261,133],{}," preload below the fold."," The browser treats the video as likely to play and fetches data early.",[15,265,266,272],{},[212,267,268,269,271],{},"2. Autoplay loops with ",[30,270,44],{}," set at load."," Autoplay videos must download to play, so every autoplay loop on the page downloads immediately.",[15,274,275,278],{},[212,276,277],{},"3. Lazy-loading the hero."," Deferring the above-the-fold video delays its poster or first frame, harming LCP.",[15,280,281,284],{},[212,282,283],{},"4. No reserved space."," Without dimensions, the video element's size is unknown until metadata loads, causing a shift.",[15,286,287],{},[60,288,67,291,67,294,67,297,67,299,67,302,67,304,67,311,67,318,67,323,67,327,67,332,67,336,67,340,67,344,67],{"viewBox":289,"width":63,"role":64,"ariaLabel":290,"style":66},"0 0 760 163","Bar chart of video bytes downloaded before LCP on an article page with three below-the-fold videos under different loading strategies.",[69,292],{"className":293,"x":73,"y":73,"width":63,"height":63,"fill":74},[72],[76,295,296],{},"Bytes downloaded before LCP on an article with three videos",[80,298,290],{},[69,300],{"x":84,"y":84,"width":85,"height":301,"rx":87,"fill":88,"stroke":89,"style":90},"161",[92,303,296],{"x":94,"y":95,"fill":89,"style":96},[92,305,310],{"x":306,"y":307,"fill":89,"style":308,"textAnchor":309},"185.7","70.0","font-size:13px","end","Default preload",[69,312],{"x":313,"y":99,"width":314,"height":315,"rx":316,"fill":136,"stroke":137,"style":317},"197.7","470.3","19","3","fill-opacity:0.7;stroke-opacity:0.9",[92,319,322],{"x":320,"y":307,"fill":89,"style":321},"674.0","font-size:12px;font-weight:600","3900KB",[92,324,326],{"x":306,"y":325,"fill":89,"style":308,"textAnchor":309},"101.0","preload=metadata",[69,328],{"x":313,"y":329,"width":330,"height":315,"rx":316,"fill":173,"stroke":173,"style":331},"87.0","50.7","fill-opacity:0.55;stroke-opacity:0.9",[92,333,335],{"x":334,"y":325,"fill":89,"style":321},"254.3","420KB",[92,337,339],{"x":306,"y":338,"fill":89,"style":308,"textAnchor":309},"132.0","preload=none + visible-load",[69,341],{"x":313,"y":342,"width":343,"height":315,"rx":316,"fill":173,"stroke":173,"style":331},"118.0","2.0",[92,345,347],{"x":346,"y":338,"fill":89,"style":321},"205.7","0KB",[201,349,351],{"id":350},"step-by-step-resolution","Step-by-Step Resolution",[353,354,356],"h3",{"id":355},"_1-keep-the-hero-eager-with-a-preloaded-poster","1. Keep the hero eager, with a preloaded poster",[358,359,364],"pre",{"className":360,"code":361,"language":362,"meta":363,"style":363},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Cvideo autoplay muted loop playsinline width=\"1280\" height=\"720\"\n       poster=\"\u002Fmedia\u002Fhero-poster-1280.avif\" preload=\"metadata\">\n  \u003Csource src=\"\u002Fmedia\u002Fhero-720.webm\" type=\"video\u002Fwebm\">\n  \u003Csource src=\"\u002Fmedia\u002Fhero-720.mp4\" type=\"video\u002Fmp4\">\n\u003C\u002Fvideo>\n\u003Clink rel=\"preload\" as=\"image\" href=\"\u002Fmedia\u002Fhero-poster-1280.avif\" fetchpriority=\"high\">\n\u003C!-- trade-off: preload=\"metadata\" on an autoplay video still lets it start\n     promptly once the page is ready; \"auto\" would compete with the poster. -->\n","html","",[30,365,366,410,432,459,482,492,533,540],{"__ignoreMap":363},[367,368,371,375,379,383,386,389,392,395,398,402,405,407],"span",{"class":369,"line":370},"line",1,[367,372,374],{"class":373},"saISM","\u003C",[367,376,378],{"class":377},"sZBmE","video",[367,380,382],{"class":381},"sPXB4"," autoplay",[367,384,385],{"class":381}," muted",[367,387,388],{"class":381}," loop",[367,390,391],{"class":381}," playsinline",[367,393,394],{"class":381}," width",[367,396,397],{"class":373},"=",[367,399,401],{"class":400},"sZ8jY","\"1280\"",[367,403,404],{"class":381}," height",[367,406,397],{"class":373},[367,408,409],{"class":400},"\"720\"\n",[367,411,413,416,418,421,424,426,429],{"class":369,"line":412},2,[367,414,415],{"class":381},"       poster",[367,417,397],{"class":373},[367,419,420],{"class":400},"\"\u002Fmedia\u002Fhero-poster-1280.avif\"",[367,422,423],{"class":381}," preload",[367,425,397],{"class":373},[367,427,428],{"class":400},"\"metadata\"",[367,430,431],{"class":373},">\n",[367,433,435,438,441,444,446,449,452,454,457],{"class":369,"line":434},3,[367,436,437],{"class":373},"  \u003C",[367,439,440],{"class":377},"source",[367,442,443],{"class":381}," src",[367,445,397],{"class":373},[367,447,448],{"class":400},"\"\u002Fmedia\u002Fhero-720.webm\"",[367,450,451],{"class":381}," type",[367,453,397],{"class":373},[367,455,456],{"class":400},"\"video\u002Fwebm\"",[367,458,431],{"class":373},[367,460,462,464,466,468,470,473,475,477,480],{"class":369,"line":461},4,[367,463,437],{"class":373},[367,465,440],{"class":377},[367,467,443],{"class":381},[367,469,397],{"class":373},[367,471,472],{"class":400},"\"\u002Fmedia\u002Fhero-720.mp4\"",[367,474,451],{"class":381},[367,476,397],{"class":373},[367,478,479],{"class":400},"\"video\u002Fmp4\"",[367,481,431],{"class":373},[367,483,485,488,490],{"class":369,"line":484},5,[367,486,487],{"class":373},"\u003C\u002F",[367,489,378],{"class":377},[367,491,431],{"class":373},[367,493,495,497,500,503,505,508,511,513,516,519,521,523,526,528,531],{"class":369,"line":494},6,[367,496,374],{"class":373},[367,498,499],{"class":377},"link",[367,501,502],{"class":381}," rel",[367,504,397],{"class":373},[367,506,507],{"class":400},"\"preload\"",[367,509,510],{"class":381}," as",[367,512,397],{"class":373},[367,514,515],{"class":400},"\"image\"",[367,517,518],{"class":381}," href",[367,520,397],{"class":373},[367,522,420],{"class":400},[367,524,525],{"class":381}," fetchpriority",[367,527,397],{"class":373},[367,529,530],{"class":400},"\"high\"",[367,532,431],{"class":373},[367,534,536],{"class":369,"line":535},7,[367,537,539],{"class":538},"sjfSM","\u003C!-- trade-off: preload=\"metadata\" on an autoplay video still lets it start\n",[367,541,543],{"class":369,"line":542},8,[367,544,545],{"class":538},"     promptly once the page is ready; \"auto\" would compete with the poster. -->\n",[353,547,549],{"id":548},"_2-use-preloadnone-for-click-to-play-video-below-the-fold","2. Use preload=\"none\" for click-to-play video below the fold",[358,551,553],{"className":360,"code":552,"language":362,"meta":363,"style":363},"\u003Cvideo controls preload=\"none\" width=\"1280\" height=\"720\" poster=\"\u002Fmedia\u002Fdemo-poster.avif\">\n  \u003Csource src=\"\u002Fmedia\u002Fdemo.mp4\" type=\"video\u002Fmp4\">\n\u003C\u002Fvideo>\n\u003C!-- trade-off: playback starts a little later after the user presses play,\n     because nothing was buffered. For short demos users nearly always watch,\n     preload=\"metadata\" is a reasonable compromise. -->\n",[30,554,555,594,615,623,628,633],{"__ignoreMap":363},[367,556,557,559,561,564,566,568,571,573,575,577,579,581,584,587,589,592],{"class":369,"line":370},[367,558,374],{"class":373},[367,560,378],{"class":377},[367,562,563],{"class":381}," controls",[367,565,423],{"class":381},[367,567,397],{"class":373},[367,569,570],{"class":400},"\"none\"",[367,572,394],{"class":381},[367,574,397],{"class":373},[367,576,401],{"class":400},[367,578,404],{"class":381},[367,580,397],{"class":373},[367,582,583],{"class":400},"\"720\"",[367,585,586],{"class":381}," poster",[367,588,397],{"class":373},[367,590,591],{"class":400},"\"\u002Fmedia\u002Fdemo-poster.avif\"",[367,593,431],{"class":373},[367,595,596,598,600,602,604,607,609,611,613],{"class":369,"line":412},[367,597,437],{"class":373},[367,599,440],{"class":377},[367,601,443],{"class":381},[367,603,397],{"class":373},[367,605,606],{"class":400},"\"\u002Fmedia\u002Fdemo.mp4\"",[367,608,451],{"class":381},[367,610,397],{"class":373},[367,612,479],{"class":400},[367,614,431],{"class":373},[367,616,617,619,621],{"class":369,"line":434},[367,618,487],{"class":373},[367,620,378],{"class":377},[367,622,431],{"class":373},[367,624,625],{"class":369,"line":461},[367,626,627],{"class":538},"\u003C!-- trade-off: playback starts a little later after the user presses play,\n",[367,629,630],{"class":369,"line":484},[367,631,632],{"class":538},"     because nothing was buffered. For short demos users nearly always watch,\n",[367,634,635],{"class":369,"line":494},[367,636,637],{"class":538},"     preload=\"metadata\" is a reasonable compromise. -->\n",[353,639,641],{"id":640},"_3-load-autoplay-loops-when-they-approach-the-viewport","3. Load autoplay loops when they approach the viewport",[358,643,647],{"className":644,"code":645,"language":646,"meta":363,"style":363},"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 { target: video, isIntersecting } of entries) {\n    if (isIntersecting) {\n      for (const s of video.querySelectorAll('source[data-src]')) { s.src = s.dataset.src; s.removeAttribute('data-src'); }\n      video.load();\n      video.play().catch(() => {});\n    } else if (!video.paused) {\n      video.pause();\n    }\n  }\n}, { rootMargin: '200px 0px' });\ndocument.querySelectorAll('video[data-lazy]').forEach((v) => io.observe(v));\n\u002F\u002F trade-off: on very fast scrolling the video may still be loading when it\n\u002F\u002F enters view; the poster covers the gap, so always set one.\n","javascript",[30,648,649,684,720,728,774,785,806,825,834,840,846,858,895,901],{"__ignoreMap":363},[367,650,651,655,658,661,664,668,671,675,678,681],{"class":369,"line":370},[367,652,654],{"class":653},"sPARh","const",[367,656,657],{"class":381}," io",[367,659,660],{"class":653}," =",[367,662,663],{"class":653}," new",[367,665,667],{"class":666},"smZ65"," IntersectionObserver",[367,669,670],{"class":373},"((",[367,672,674],{"class":673},"sQw3B","entries",[367,676,677],{"class":373},") ",[367,679,680],{"class":653},"=>",[367,682,683],{"class":373}," {\n",[367,685,686,689,692,694,697,700,703,705,708,711,714,717],{"class":369,"line":412},[367,687,688],{"class":653},"  for",[367,690,691],{"class":373}," (",[367,693,654],{"class":653},[367,695,696],{"class":373}," { ",[367,698,699],{"class":673},"target",[367,701,702],{"class":373},": ",[367,704,378],{"class":381},[367,706,707],{"class":373},", ",[367,709,710],{"class":381},"isIntersecting",[367,712,713],{"class":373}," } ",[367,715,716],{"class":653},"of",[367,718,719],{"class":373}," entries) {\n",[367,721,722,725],{"class":369,"line":434},[367,723,724],{"class":653},"    if",[367,726,727],{"class":373}," (isIntersecting) {\n",[367,729,730,733,735,737,740,743,746,749,752,755,758,760,763,766,768,771],{"class":369,"line":461},[367,731,732],{"class":653},"      for",[367,734,691],{"class":373},[367,736,654],{"class":653},[367,738,739],{"class":381}," s",[367,741,742],{"class":653}," of",[367,744,745],{"class":373}," video.",[367,747,748],{"class":666},"querySelectorAll",[367,750,751],{"class":373},"(",[367,753,754],{"class":400},"'source[data-src]'",[367,756,757],{"class":373},")) { s.src ",[367,759,397],{"class":653},[367,761,762],{"class":373}," s.dataset.src; s.",[367,764,765],{"class":666},"removeAttribute",[367,767,751],{"class":373},[367,769,770],{"class":400},"'data-src'",[367,772,773],{"class":373},"); }\n",[367,775,776,779,782],{"class":369,"line":484},[367,777,778],{"class":373},"      video.",[367,780,781],{"class":666},"load",[367,783,784],{"class":373},"();\n",[367,786,787,789,792,795,798,801,803],{"class":369,"line":494},[367,788,778],{"class":373},[367,790,791],{"class":666},"play",[367,793,794],{"class":373},"().",[367,796,797],{"class":666},"catch",[367,799,800],{"class":373},"(() ",[367,802,680],{"class":653},[367,804,805],{"class":373}," {});\n",[367,807,808,811,814,817,819,822],{"class":369,"line":535},[367,809,810],{"class":373},"    } ",[367,812,813],{"class":653},"else",[367,815,816],{"class":653}," if",[367,818,691],{"class":373},[367,820,821],{"class":653},"!",[367,823,824],{"class":373},"video.paused) {\n",[367,826,827,829,832],{"class":369,"line":542},[367,828,778],{"class":373},[367,830,831],{"class":666},"pause",[367,833,784],{"class":373},[367,835,837],{"class":369,"line":836},9,[367,838,839],{"class":373},"    }\n",[367,841,843],{"class":369,"line":842},10,[367,844,845],{"class":373},"  }\n",[367,847,849,852,855],{"class":369,"line":848},11,[367,850,851],{"class":373},"}, { rootMargin: ",[367,853,854],{"class":400},"'200px 0px'",[367,856,857],{"class":373}," });\n",[367,859,861,864,866,868,871,874,877,879,882,884,886,889,892],{"class":369,"line":860},12,[367,862,863],{"class":373},"document.",[367,865,748],{"class":666},[367,867,751],{"class":373},[367,869,870],{"class":400},"'video[data-lazy]'",[367,872,873],{"class":373},").",[367,875,876],{"class":666},"forEach",[367,878,670],{"class":373},[367,880,881],{"class":673},"v",[367,883,677],{"class":373},[367,885,680],{"class":653},[367,887,888],{"class":373}," io.",[367,890,891],{"class":666},"observe",[367,893,894],{"class":373},"(v));\n",[367,896,898],{"class":369,"line":897},13,[367,899,900],{"class":538},"\u002F\u002F trade-off: on very fast scrolling the video may still be loading when it\n",[367,902,904],{"class":369,"line":903},14,[367,905,906],{"class":538},"\u002F\u002F enters view; the poster covers the gap, so always set one.\n",[15,908,909],{},"Expected outcome: zero video bytes during load for below-the-fold loops; videos start just before they become visible.",[353,911,913],{"id":912},"_4-reserve-space-for-every-video","4. Reserve space for every video",[15,915,916,917,919,920,922,923,925],{},"Set ",[30,918,242],{}," and ",[30,921,245],{}," attributes (or ",[30,924,249],{}," in CSS) on every video and embed container so the layout never depends on metadata arriving.",[15,927,928],{},[60,929,67,932,67,935,67,938,67,940,67,957,67,960,67,962,67,967,67,973,67,976,67,981,67,989,67,995,67,999,67,1005,67,1008,67,1012,67,1014,67,1017,67,1020,67,1023,67,1026,67,1029,67,1032,67,1036,67,1038,67,1041,67,1044,67,1047,67,1051,67,1054,67,1057,67],{"viewBox":930,"width":63,"role":64,"ariaLabel":931,"style":66},"0 0 760 325","Decision sequence for choosing a loading strategy for a video based on position and playback behaviour.",[69,933],{"className":934,"x":73,"y":73,"width":63,"height":63,"fill":74},[72],[76,936,937],{},"How should this video load?",[80,939,931],{},[941,942,943],"defs",{},[944,945,952],"marker",{"id":946,"viewBox":947,"refX":948,"refY":949,"markerWidth":950,"markerHeight":950,"orient":951},"fa57ab3914","0 0 10 10","9","5","7","auto-start-reverse",[953,954],"path",{"d":955,"fill":89,"style":956},"M0 0 L10 5 L0 10 z","fill-opacity:0.7",[69,958],{"x":84,"y":84,"width":85,"height":959,"rx":87,"fill":88,"stroke":89,"style":90},"323",[92,961,937],{"x":94,"y":95,"fill":89,"style":96},[69,963],{"x":94,"y":99,"width":964,"height":965,"rx":966,"fill":89,"stroke":89,"style":102},"320.0","35.0","6",[92,968,972],{"x":969,"y":970,"fill":89,"style":971,"textAnchor":117},"188.0","78.0","font-size:13px;font-weight:700","Above the fold and autoplaying?",[69,974],{"x":975,"y":99,"width":964,"height":965,"rx":966,"fill":173,"stroke":173,"style":174},"412.0",[92,977,980],{"x":978,"y":970,"fill":89,"style":979,"textAnchor":117},"572.0","font-size:12.5px","Eager, preload=metadata, preloaded poster",[369,982],{"x1":983,"y1":984,"x2":985,"y2":984,"stroke":89,"strokeWidth":986,"style":987,"markerEnd":988},"348.0","73.5","410.0","1.5","stroke-opacity:0.6","url(#fa57ab3914)",[92,990,994],{"x":991,"y":992,"fill":173,"style":993,"textAnchor":117},"380.0","66.5","font-size:11.5px;font-weight:700","yes",[369,996],{"x1":969,"y1":997,"x2":969,"y2":998,"stroke":89,"strokeWidth":986,"style":987,"markerEnd":988},"91.0","125.0",[92,1000,1004],{"x":1001,"y":1002,"fill":1003,"style":993},"196.0","113.0","#51617a","no",[69,1006],{"x":94,"y":1007,"width":964,"height":965,"rx":966,"fill":89,"stroke":89,"style":102},"127.0",[92,1009,1011],{"x":969,"y":1010,"fill":89,"style":971,"textAnchor":117},"149.0","Below the fold and autoplaying?",[69,1013],{"x":975,"y":1007,"width":964,"height":965,"rx":966,"fill":173,"stroke":173,"style":174},[92,1015,1016],{"x":978,"y":1010,"fill":89,"style":979,"textAnchor":117},"Sources set on visibility (IntersectionObserver)",[369,1018],{"x1":983,"y1":1019,"x2":985,"y2":1019,"stroke":89,"strokeWidth":986,"style":987,"markerEnd":988},"144.5",[92,1021,994],{"x":991,"y":1022,"fill":173,"style":993,"textAnchor":117},"137.5",[369,1024],{"x1":969,"y1":1025,"x2":969,"y2":1001,"stroke":89,"strokeWidth":986,"style":987,"markerEnd":988},"162.0",[92,1027,1004],{"x":1001,"y":1028,"fill":1003,"style":993},"184.0",[69,1030],{"x":94,"y":1031,"width":964,"height":965,"rx":966,"fill":89,"stroke":89,"style":102},"198.0",[92,1033,1035],{"x":969,"y":1034,"fill":89,"style":971,"textAnchor":117},"220.0","Click-to-play?",[69,1037],{"x":975,"y":1031,"width":964,"height":965,"rx":966,"fill":173,"stroke":173,"style":174},[92,1039,1040],{"x":978,"y":1034,"fill":89,"style":979,"textAnchor":117},"preload=none (or metadata) with poster",[369,1042],{"x1":983,"y1":1043,"x2":985,"y2":1043,"stroke":89,"strokeWidth":986,"style":987,"markerEnd":988},"215.5",[92,1045,994],{"x":991,"y":1046,"fill":173,"style":993,"textAnchor":117},"208.5",[369,1048],{"x1":969,"y1":1049,"x2":969,"y2":1050,"stroke":89,"strokeWidth":986,"style":987,"markerEnd":988},"233.0","267.0",[92,1052,1004],{"x":1001,"y":1053,"fill":1003,"style":993},"255.0",[69,1055],{"x":94,"y":1056,"width":964,"height":95,"rx":966,"fill":136,"stroke":137,"style":138},"269.0",[92,1058,1060],{"x":969,"y":1059,"fill":89,"style":979,"textAnchor":117},"290.5","Third-party embed — use a facade",[201,1062,1064],{"id":1063},"verification","Verification",[15,1066,1067],{},"On a throttled profile, check that no video requests start before LCP on pages where video is below the fold, and that the hero's poster loads early with high priority. Scroll to lazy videos and confirm they load and play shortly before entering view. Layout Shift Regions should not flash when videos load.",[201,1069,1071],{"id":1070},"worked-example-a-recipe-site","Worked Example: A Recipe Site",[15,1073,1074,1075,1078,1079,1082],{},"A recipe site embedded three short cooking loops per article, all ",[30,1076,1077],{},"autoplay muted loop"," with sources set at load. Each article downloaded about 4MB of video before LCP on mobile, and LCP p75 was 3.4s. Switching the loops to visibility-triggered loading with posters, and setting ",[30,1080,1081],{},"preload=\"none\""," on the full-length recipe video, removed all video bytes before LCP; LCP p75 dropped to 2.2s and mobile data usage per article view fell by 60%, since many readers never scrolled to the second and third loops.",[201,1084,1086],{"id":1085},"lazy-loading-in-frameworks-and-components","Lazy Loading in Frameworks and Components",[15,1088,1089,1090,1092,1093,1096,1097,1100],{},"Many video components set ",[30,1091,52],{}," or attach sources eagerly for convenience. Audit them once: a shared ",[30,1094,1095],{},"\u003CLazyVideo>"," component that accepts ",[30,1098,1099],{},"priority"," (eager hero) or default (lazy) and handles posters, dimensions and the observer centralises the policy so individual pages cannot regress it. In React and Vue, attach the IntersectionObserver in an effect and clean it up on unmount; in SPAs, also pause and unload videos when their route is left, so a video from the previous view does not keep downloading.",[201,1102,1104],{"id":1103},"measuring-video-loading-in-the-field","Measuring Video Loading in the Field",[15,1106,1107,1108,1111,1112,1114,1115,1118,1119,1122],{},"Add two signals to RUM for pages with video: bytes of media downloaded before LCP (from Resource Timing entries whose ",[30,1109,1110],{},"initiatorType"," is ",[30,1113,378],{}," or whose URLs match your media paths), and time to first frame for videos that play (from the ",[30,1116,1117],{},"playing"," event relative to when the video entered the viewport). The first confirms that lazy loading keeps video off the critical path for real users; the second confirms you have not overcorrected — if videos routinely start playing a second after becoming visible, widen the observer's margin or switch to ",[30,1120,1121],{},"preload=\"metadata\""," for that template.",[201,1124,1126],{"id":1125},"common-mistakes","Common Mistakes",[206,1128,1129,1135,1141,1151],{},[209,1130,1131,1134],{},[212,1132,1133],{},"Removing the poster to \"save bytes\"."," The poster is what users see first and often the LCP element.",[209,1136,1137,1140],{},[212,1138,1139],{},"Lazy-loading the hero."," LCP waits for the observer and the download.",[209,1142,1143,1150],{},[212,1144,1145,1146,1149],{},"Forgetting ",[30,1147,1148],{},"playsinline","."," On iOS, autoplaying videos without it may open fullscreen or not play.",[209,1152,1153,1156],{},[212,1154,1155],{},"Leaving videos playing offscreen."," They keep consuming bandwidth and CPU.",[201,1158,1160],{"id":1159},"edge-cases","Edge Cases",[15,1162,1163,1166,1167,1169,1170,1172],{},[212,1164,1165],{},"Safari and preload."," Safari has historically treated ",[30,1168,40],{}," as a hint with its own defaults (often ",[30,1171,154],{},"); test actual behaviour.",[15,1174,1175,1180],{},[212,1176,1177,1179],{},[30,1178,36],{}," on iframes."," Video embeds in iframes can use native lazy loading, but a facade saves more by not creating the iframe at all.",[15,1182,1183,1186,1187,1190],{},[212,1184,1185],{},"Low Power Mode."," iOS may block autoplay; lazy-loading logic must handle a rejected ",[30,1188,1189],{},"play()"," promise gracefully.",[15,1192,1193,1196],{},[212,1194,1195],{},"Background tabs."," Browsers pause video in background tabs; there is no need to manage that yourself.",[201,1198,1200],{"id":1199},"faq","FAQ",[1202,1203,1206,1210],"details",{"className":1204},[1205],"faq-item",[1207,1208,1209],"summary",{},"Is there a native loading=\"lazy\" for video?",[15,1211,1212,1213,1215,1216,1218,1219,1149],{},"Not for ",[30,1214,32],{}," at the time of writing. Use ",[30,1217,1081],{}," and set sources on visibility. Iframes (for embeds) support ",[30,1220,36],{},[1202,1222,1224,1227],{"className":1223},[1205],[1207,1225,1226],{},"Does preload=\"none\" prevent the poster from loading?",[15,1228,1229,1230,1232],{},"No. The poster is fetched as an image regardless of ",[30,1231,40],{},". Only video data is deferred.",[1202,1234,1236,1239],{"className":1235},[1205],[1207,1237,1238],{},"What rootMargin should I use?",[15,1240,1241],{},"One to two viewport heights on mobile (where scrolling is fast) and less on desktop. The goal is for the first frames to be ready when the video becomes visible.",[1202,1243,1245,1248],{"className":1244},[1205],[1207,1246,1247],{},"Should autoplay loops ever be eager?",[15,1249,1250],{},"Only when they are above the fold and essential to the first impression. Even then, a poster should paint first and serve as the LCP element.",[1202,1252,1254,1257],{"className":1253},[1205],[1207,1255,1256],{},"Does lazy-loaded video affect SEO?",[15,1258,1259,1260,1263],{},"Search engines discover videos through markup and structured data, not playback. Keep sources discoverable (in ",[30,1261,1262],{},"data-src"," or via a VideoObject schema) and provide posters and descriptions.",[1202,1265,1267,1270],{"className":1266},[1205],[1207,1268,1269],{},"How do I measure the effect?",[15,1271,1272],{},"Track bytes downloaded before LCP (from Resource Timing filtered to media) and LCP p75 on video templates before and after. Add a time-to-first-frame metric for lazy videos to confirm playback still starts promptly.",[1202,1274,1276,1279],{"className":1275},[1205],[1207,1277,1278],{},"What about video in modals and lightboxes?",[15,1280,1281],{},"Do not create the video element (or set its sources) until the modal opens. Preload the poster on hover of the trigger if the modal opens with a visible frame, and prefetch the first video segment or file only when the user signals intent.",[201,1283,1285],{"id":1284},"related","Related",[206,1287,1288,1295,1302],{},[209,1289,1290,1294],{},[19,1291,1293],{"href":1292},"\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Fvideo-poster-images-and-lcp\u002F","Video poster images and LCP"," — making the poster fast.",[209,1296,1297,1301],{},[19,1298,1300],{"href":1299},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Fnative-lazy-loading-vs-intersection-observer\u002F","Native lazy loading vs IntersectionObserver"," — the same trade-offs for images.",[209,1303,1304,1308],{},[19,1305,1307],{"href":1306},"\u002Fimage-media-optimization\u002Flazy-loading-images-without-hurting-lcp\u002Flazy-loading-iframes\u002F","Lazy-loading iframes"," — for embedded players.",[1310,1311,1313],"script",{"type":1312},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Lazy-Load Video Without Hurting LCP\",\n  \"description\": \"Patterns for deferring video downloads until they are needed while keeping hero videos and their posters fast.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Keep the hero eager, with a preloaded poster\",\n      \"text\": \"Keep the hero eager, with a preloaded poster\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Use preload=\\\"none\\\" for click-to-play video below the fold\",\n      \"text\": \"Use preload=\\\"none\\\" for click-to-play video below the fold\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Load autoplay loops when they approach the viewport\",\n      \"text\": \"Expected outcome: zero video bytes during load for below-the-fold loops; videos start just before they become visible.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Reserve space for every video\",\n      \"text\": \"Set width and height attributes (or aspect-ratio in CSS) on every video and embed container so the layout never depends on metadata arriving.\"\n    }\n  ]\n}\n",[1310,1315,1316],{"type":1312},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Lazy-Load Video Without Hurting LCP\",\n  \"description\": \"Patterns for deferring video downloads until they are needed while keeping hero videos and their posters fast.\",\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\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp\u002F\"\n  }\n}\n",[1310,1318,1319],{"type":1312},"\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\": \"Video Performance Optimization\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Lazy-Loading Video Without Hurting LCP\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp\u002F\"\n    }\n  ]\n}\n",[1321,1322,1323],"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}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}",{"title":363,"searchDepth":412,"depth":412,"links":1325},[1326,1327,1328,1334,1335,1336,1337,1338,1339,1340,1341],{"id":203,"depth":412,"text":204},{"id":253,"depth":412,"text":254},{"id":350,"depth":412,"text":351,"children":1329},[1330,1331,1332,1333],{"id":355,"depth":434,"text":356},{"id":548,"depth":434,"text":549},{"id":640,"depth":434,"text":641},{"id":912,"depth":434,"text":913},{"id":1063,"depth":412,"text":1064},{"id":1070,"depth":412,"text":1071},{"id":1085,"depth":412,"text":1086},{"id":1103,"depth":412,"text":1104},{"id":1125,"depth":412,"text":1126},{"id":1159,"depth":412,"text":1160},{"id":1199,"depth":412,"text":1200},{"id":1284,"depth":412,"text":1285},"Patterns for deferring video downloads until they are needed while keeping hero videos and their posters fast.","md",{"slug":1345,"type":1346,"breadcrumb":1347,"datePublished":1354,"dateModified":1354},"lazy-loading-video-without-hurting-lcp","article",[1348,1350,1351,1352],{"name":1349,"url":45},"Home",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1353},"\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp\u002F","2026-10-06",true,"\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp",{"title":5,"description":1358},"Stop below-the-fold videos from downloading megabytes during load: use preload=\"none\", load sources on visibility, keep heroes eager, and avoid layout shift.","image-media-optimization\u002Fvideo-performance-optimization\u002Flazy-loading-video-without-hurting-lcp\u002Findex","8DZt-0oi8pmvQwAvYmXUElkuZH0Hf21OONualhPxxM4",[1362,1366],{"title":1363,"path":1364,"stem":1365},"HLS Streaming vs Progressive MP4","\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Fhls-streaming-vs-progressive-mp4","image-media-optimization\u002Fvideo-performance-optimization\u002Fhls-streaming-vs-progressive-mp4\u002Findex",{"title":1367,"path":1368,"stem":1369},"Replacing Animated GIFs with Video","\u002Fimage-media-optimization\u002Fvideo-performance-optimization\u002Freplacing-animated-gifs-with-video","image-media-optimization\u002Fvideo-performance-optimization\u002Freplacing-animated-gifs-with-video\u002Findex",1791308079726]