[{"data":1,"prerenderedAt":1215},["ShallowReactive",2],{"content:\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads":3,"surroundings:\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads":1206},{"id":4,"title":5,"body":6,"description":1185,"extension":1186,"meta":1187,"navigation":1199,"path":1200,"seo":1201,"stem":1204,"__hash__":1205},"content\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads\u002Findex.md","Why the LCP Element Changes Between Loads",{"type":7,"value":8,"toc":1170},"minimark",[9,14,29,42,179,184,225,229,239,249,255,265,271,403,407,416,419,652,655,659,662,810,813,817,820,877,880,884,887,987,990,1076,1080,1083,1087,1094,1098,1119,1128,1132,1155,1160,1163,1166],[10,11,13],"h1",{"id":12},"why-the-lcp-element-changes-between-loads-and-how-to-make-it-stable","Why the LCP Element Changes Between Loads — and How to Make It Stable",[15,16,17,18,23,24,28],"p",{},"This guide explains a source of persistent confusion in ",[19,20,22],"a",{"href":21},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F","Measuring LCP with Chrome DevTools"," and the wider ",[19,25,27],{"href":26},"\u002Fcore-web-vitals-measurement\u002F","Core Web Vitals & Measurement"," workflow: you optimise the hero image, the lab LCP improves, and field data reports the LCP element is now a paragraph, a logo, or a cookie banner — on some loads but not others.",[15,30,31,32,36,37,41],{},"LCP is not a fixed element; it is the ",[33,34,35],"em",{},"last"," entry in a stream of candidates. As the page renders, every time a larger image or text block paints, the browser emits a new ",[38,39,40],"code",{},"largest-contentful-paint"," entry. The stream stops at the first user input or scroll. The final entry is the page's LCP. Anything that changes which elements paint, how large they render, or in what order they paint can change the winner — and with it, which optimisation actually moves the metric.",[15,43,44],{},[45,46,52,53,52,60,52,64,52,67,52,76,52,82,52,93,52,98,52,106,52,113,52,119,52,123,52,129,52,133,52,138,52,144,52,148,52,152,52,156,52,160,52,164,52,168,52,174,52],"svg",{"viewBox":47,"width":48,"role":49,"ariaLabel":50,"style":51},"0 0 760 188","100%","img","Timeline of successive LCP candidates — a logo, then a heading, then a hero image — with the last candidate before input becoming the reported LCP.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[54,55],"rect",{"className":56,"x":58,"y":58,"width":48,"height":48,"fill":59},[57],"svg-canvas","0","#ffffff",[61,62,63],"title",{},"The LCP candidate stream on one load",[65,66,50],"desc",{},[54,68],{"x":69,"y":69,"width":70,"height":71,"rx":72,"fill":73,"stroke":74,"style":75},"1","758","186","10","none","currentColor","stroke-opacity:0.18",[77,78,63],"text",{"x":79,"y":80,"fill":74,"style":81},"28.0","34.0","font-size:16px;font-weight:700",[83,84],"line",{"x1":85,"y1":86,"x2":85,"y2":87,"stroke":88,"strokeWidth":89,"strokeDashArray":90,"style":92},"643.6","72.0","118.0","#b8860b","1.5",[91,91],"4","stroke-opacity:0.9",[77,94,97],{"x":79,"y":95,"fill":74,"style":96},"96.0","font-size:12.5px;font-weight:700","Candidates",[54,99],{"x":100,"y":101,"width":102,"height":103,"rx":104,"fill":74,"stroke":74,"style":105},"191.1","78.0","101.5","26.0","3","fill-opacity:0.06;stroke-opacity:0.4",[77,107,112],{"x":108,"y":109,"fill":74,"style":110,"textAnchor":111},"241.8","95.5","font-size:11.5px","middle","logo (small)",[54,114],{"x":115,"y":101,"width":116,"height":103,"rx":104,"fill":117,"stroke":117,"style":118},"294.1","163.3","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[77,120,122],{"x":121,"y":109,"fill":74,"style":110,"textAnchor":111},"375.8","h1 text",[54,124],{"x":125,"y":101,"width":126,"height":103,"rx":104,"fill":127,"stroke":88,"style":128},"458.9","183.9","#ffc300","fill-opacity:0.24;stroke-opacity:0.9",[77,130,132],{"x":131,"y":109,"fill":74,"style":110,"textAnchor":111},"550.9","hero image (final)",[83,134],{"x1":135,"y1":87,"x2":136,"y2":87,"stroke":74,"style":137},"107.9","726.0","stroke-opacity:0.4",[77,139,143],{"x":140,"y":141,"fill":142,"style":110,"textAnchor":111},"118.6","135.0","#51617a","0ms",[77,145,147],{"x":146,"y":141,"fill":142,"style":110,"textAnchor":111},"210.9","500ms",[77,149,151],{"x":150,"y":141,"fill":142,"style":110,"textAnchor":111},"313.9","1000ms",[77,153,155],{"x":154,"y":141,"fill":142,"style":110,"textAnchor":111},"417.0","1500ms",[77,157,159],{"x":158,"y":141,"fill":142,"style":110,"textAnchor":111},"520.0","2000ms",[77,161,163],{"x":162,"y":141,"fill":142,"style":110,"textAnchor":111},"623.0","2500ms",[77,165,167],{"x":166,"y":141,"fill":142,"style":110,"textAnchor":111},"712.3","3000ms",[77,169,173],{"x":85,"y":170,"fill":171,"style":172,"textAnchor":111},"68.0","#8a6608","font-size:12px;font-weight:700","first input",[77,175,178],{"x":79,"y":176,"fill":142,"style":177},"166.0","font-size:12.5px","Each larger paint replaces the previous candidate; the stream stops at the first scroll, tap or keypress.",[180,181,183],"h2",{"id":182},"rapid-diagnosis","Rapid Diagnosis",[185,186,187,199,205,219],"ul",{},[188,189,190,194,195,198],"li",{},[191,192,193],"strong",{},"Log every candidate, not just the last."," In the console: ",[38,196,197],{},"new PerformanceObserver(l => l.getEntries().forEach(e => console.log(Math.round(e.startTime), e.size, e.element))).observe({type: 'largest-contentful-paint', buffered: true})",". Reload several times with different throttling.",[188,200,201,204],{},[191,202,203],{},"Compare viewports."," Run the same page at 390px and 1350px wide. Mobile layouts often hide or shrink the hero, promoting a heading or a product grid image.",[188,206,207,210,211,214,215,218],{},[191,208,209],{},"Check field element distribution."," If your RUM collects the LCP element selector (via ",[38,212,213],{},"attribution.element"," in the ",[38,216,217],{},"web-vitals"," attribution build), chart its distribution per template. More than one element with a meaningful share is the signal.",[188,220,221,224],{},[191,222,223],{},"Watch for late, large paints."," Cookie banners, interstitials, newsletter modals and carousels advancing to a larger slide all generate new candidates late in the load.",[180,226,228],{"id":227},"root-cause-analysis","Root Cause Analysis",[15,230,231,234,235,238],{},[191,232,233],{},"1. Viewport-dependent layout."," The size used to rank candidates is the ",[33,236,237],{},"visible"," area in the viewport. A hero that is 1200×600 on desktop might be 390×195 on a phone — smaller than a heading that wraps across three lines at a large font size. Different devices legitimately have different LCP elements.",[15,240,241,244,245,248],{},[191,242,243],{},"2. Paint order races."," If the hero image loads quickly, it paints before the font finishes and wins outright. If the image is slow, the heading paints first as a candidate, then the image replaces it later. In both cases the image is LCP, but with different timing. If the image is ",[33,246,247],{},"very"," slow and the user scrolls first, the heading becomes the final LCP instead.",[15,250,251,254],{},[191,252,253],{},"3. Late overlays and banners."," A consent banner injected by a third-party script at 2.8s can be the largest text block painted on a small screen. It becomes the LCP and its timing — controlled by a vendor — defines your metric.",[15,256,257,260,261,264],{},[191,258,259],{},"4. Hydration or client re-rendering."," When a framework replaces server-rendered markup during hydration (a mismatch, or a component that re-mounts), the element is removed and re-added. Removed elements stop being candidates; the re-inserted one is a ",[33,262,263],{},"new"," candidate with a later timestamp.",[15,266,267,270],{},[191,268,269],{},"5. Carousels and rotating content."," A hero carousel that advances to a slide with a larger image, or swaps in a different image after a timer, generates a new candidate each time until input stops the stream.",[15,272,273],{},[45,274,52,277,52,280,52,283,52,285,52,288,52,290,52,295,52,301,52,305,52,309,52,312,52,316,52,320,52,324,52,326,52,330,52,332,52,335,52,338,52,342,52,344,52,347,52,349,52,352,52,355,52,359,52,361,52,364,52,366,52,369,52,372,52,376,52,378,52,381,52,383,52,386,52,389,52,393,52,395,52,398,52,400,52],{"viewBox":275,"width":48,"role":49,"ariaLabel":276,"style":51},"0 0 760 258","Five causes of LCP element instability with the condition that triggers each and how to stabilise it.",[54,278],{"className":279,"x":58,"y":58,"width":48,"height":48,"fill":59},[57],[61,281,282],{},"What decides the winning LCP candidate",[65,284,276],{},[54,286],{"x":69,"y":69,"width":70,"height":287,"rx":72,"fill":73,"stroke":74,"style":75},"256",[77,289,282],{"x":79,"y":80,"fill":74,"style":81},[54,291],{"x":79,"y":292,"width":293,"height":294,"rx":58,"fill":74,"stroke":74,"style":105},"56.0","132.5","30.0",[77,296,300],{"x":297,"y":298,"fill":74,"style":96,"textAnchor":299},"38.0","75.5","start","Cause",[54,302],{"x":303,"y":292,"width":304,"height":294,"rx":58,"fill":74,"stroke":74,"style":105},"160.5","285.7",[77,306,308],{"x":307,"y":298,"fill":74,"style":96,"textAnchor":111},"303.4","Triggered when",[54,310],{"x":311,"y":292,"width":304,"height":294,"rx":58,"fill":74,"stroke":74,"style":105},"446.3",[77,313,315],{"x":314,"y":298,"fill":74,"style":96,"textAnchor":111},"589.1","Stabilise by",[54,317],{"x":79,"y":318,"width":293,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},"86.0","stroke-opacity:0.35",[77,321,323],{"x":297,"y":322,"fill":74,"style":96,"textAnchor":299},"105.5","Viewport layout",[54,325],{"x":303,"y":318,"width":304,"height":294,"rx":58,"fill":74,"stroke":74,"style":105},[77,327,329],{"x":307,"y":322,"fill":74,"style":328,"textAnchor":111},"font-size:12px","hero small on mobile",[54,331],{"x":311,"y":318,"width":304,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},[77,333,334],{"x":314,"y":322,"fill":74,"style":328,"textAnchor":111},"Design the mobile hero deliberately",[54,336],{"x":79,"y":337,"width":293,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},"116.0",[77,339,341],{"x":297,"y":340,"fill":74,"style":96,"textAnchor":299},"135.5","Paint-order race",[54,343],{"x":303,"y":337,"width":304,"height":294,"rx":58,"fill":74,"stroke":74,"style":105},[77,345,346],{"x":307,"y":340,"fill":74,"style":328,"textAnchor":111},"slow image vs fast text",[54,348],{"x":311,"y":337,"width":304,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},[77,350,351],{"x":314,"y":340,"fill":74,"style":328,"textAnchor":111},"Preload the intended LCP",[54,353],{"x":79,"y":354,"width":293,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},"146.0",[77,356,358],{"x":297,"y":357,"fill":74,"style":96,"textAnchor":299},"165.5","Late overlay",[54,360],{"x":303,"y":354,"width":304,"height":294,"rx":58,"fill":127,"stroke":88,"style":128},[77,362,363],{"x":307,"y":357,"fill":74,"style":328,"textAnchor":111},"banner paints after hero",[54,365],{"x":311,"y":354,"width":304,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},[77,367,368],{"x":314,"y":357,"fill":74,"style":328,"textAnchor":111},"Render overlay small or early",[54,370],{"x":79,"y":371,"width":293,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},"176.0",[77,373,375],{"x":297,"y":374,"fill":74,"style":96,"textAnchor":299},"195.5","Hydration re-render",[54,377],{"x":303,"y":371,"width":304,"height":294,"rx":58,"fill":127,"stroke":88,"style":128},[77,379,380],{"x":307,"y":374,"fill":74,"style":328,"textAnchor":111},"element removed and re-added",[54,382],{"x":311,"y":371,"width":304,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},[77,384,385],{"x":314,"y":374,"fill":74,"style":328,"textAnchor":111},"Fix mismatches",[54,387],{"x":79,"y":388,"width":293,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},"206.0",[77,390,392],{"x":297,"y":391,"fill":74,"style":96,"textAnchor":299},"225.5","Carousel advance",[54,394],{"x":303,"y":388,"width":304,"height":294,"rx":58,"fill":127,"stroke":88,"style":128},[77,396,397],{"x":307,"y":391,"fill":74,"style":328,"textAnchor":111},"larger slide before input",[54,399],{"x":311,"y":388,"width":304,"height":294,"rx":58,"fill":73,"stroke":74,"style":319},[77,401,402],{"x":314,"y":391,"fill":74,"style":328,"textAnchor":111},"No autoplay before input",[180,404,406],{"id":405},"step-by-step-resolution","Step-by-Step Resolution",[408,409,411,412,415],"h3",{"id":410},"_1-decide-what-the-lcp-element-should-be-per-template-and-viewport","1. Decide what the LCP element ",[33,413,414],{},"should"," be, per template and viewport",[15,417,418],{},"Write it down: \"Product page, mobile: main product image. Article, mobile: H1.\" This intent turns a fluctuating metric into a test you can assert against.",[420,421,426],"pre",{"className":422,"code":423,"language":424,"meta":425,"style":425},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F Lab assertion: the final LCP candidate must match the intended selector.\nconst intended = { '\u002Fproduct\u002F': 'img.product-hero', '\u002Fblog\u002F': 'h1.article-title' };\nconst lcp = await page.evaluate(() => new Promise((r) => new PerformanceObserver((l) => {\n  const e = l.getEntries().at(-1); r(e.element?.matches?.('img.product-hero, h1.article-title') ? 'ok' : e.element?.outerHTML.slice(0, 120));\n}).observe({ type: 'largest-contentful-paint', buffered: true })));\n\u002F\u002F trade-off: lab assertions use one viewport and fast hardware. Run them at the\n\u002F\u002F smallest supported viewport, where element swaps are most likely.\n","javascript","",[38,427,428,436,478,539,616,640,646],{"__ignoreMap":425},[429,430,432],"span",{"class":83,"line":431},1,[429,433,435],{"class":434},"sjfSM","\u002F\u002F Lab assertion: the final LCP candidate must match the intended selector.\n",[429,437,439,443,447,450,454,458,461,464,467,470,472,475],{"class":83,"line":438},2,[429,440,442],{"class":441},"sPARh","const",[429,444,446],{"class":445},"sPXB4"," intended",[429,448,449],{"class":441}," =",[429,451,453],{"class":452},"saISM"," { ",[429,455,457],{"class":456},"sZ8jY","'\u002Fproduct\u002F'",[429,459,460],{"class":452},": ",[429,462,463],{"class":456},"'img.product-hero'",[429,465,466],{"class":452},", ",[429,468,469],{"class":456},"'\u002Fblog\u002F'",[429,471,460],{"class":452},[429,473,474],{"class":456},"'h1.article-title'",[429,476,477],{"class":452}," };\n",[429,479,481,483,486,488,491,494,498,501,504,507,510,513,517,520,522,524,527,529,532,534,536],{"class":83,"line":480},3,[429,482,442],{"class":441},[429,484,485],{"class":445}," lcp",[429,487,449],{"class":441},[429,489,490],{"class":441}," await",[429,492,493],{"class":452}," page.",[429,495,497],{"class":496},"smZ65","evaluate",[429,499,500],{"class":452},"(() ",[429,502,503],{"class":441},"=>",[429,505,506],{"class":441}," new",[429,508,509],{"class":445}," Promise",[429,511,512],{"class":452},"((",[429,514,516],{"class":515},"sQw3B","r",[429,518,519],{"class":452},") ",[429,521,503],{"class":441},[429,523,506],{"class":441},[429,525,526],{"class":496}," PerformanceObserver",[429,528,512],{"class":452},[429,530,531],{"class":515},"l",[429,533,519],{"class":452},[429,535,503],{"class":441},[429,537,538],{"class":452}," {\n",[429,540,542,545,548,550,553,556,559,562,565,568,570,573,575,578,581,584,587,589,592,595,598,601,604,606,608,610,613],{"class":83,"line":541},4,[429,543,544],{"class":441},"  const",[429,546,547],{"class":445}," e",[429,549,449],{"class":441},[429,551,552],{"class":452}," l.",[429,554,555],{"class":496},"getEntries",[429,557,558],{"class":452},"().",[429,560,561],{"class":496},"at",[429,563,564],{"class":452},"(",[429,566,567],{"class":441},"-",[429,569,69],{"class":445},[429,571,572],{"class":452},"); ",[429,574,516],{"class":496},[429,576,577],{"class":452},"(e.element?.",[429,579,580],{"class":496},"matches",[429,582,583],{"class":452},"?.(",[429,585,586],{"class":456},"'img.product-hero, h1.article-title'",[429,588,519],{"class":452},[429,590,591],{"class":441},"?",[429,593,594],{"class":456}," 'ok'",[429,596,597],{"class":441}," :",[429,599,600],{"class":452}," e.element?.outerHTML.",[429,602,603],{"class":496},"slice",[429,605,564],{"class":452},[429,607,58],{"class":445},[429,609,466],{"class":452},[429,611,612],{"class":445},"120",[429,614,615],{"class":452},"));\n",[429,617,619,622,625,628,631,634,637],{"class":83,"line":618},5,[429,620,621],{"class":452},"}).",[429,623,624],{"class":496},"observe",[429,626,627],{"class":452},"({ type: ",[429,629,630],{"class":456},"'largest-contentful-paint'",[429,632,633],{"class":452},", buffered: ",[429,635,636],{"class":445},"true",[429,638,639],{"class":452}," })));\n",[429,641,643],{"class":83,"line":642},6,[429,644,645],{"class":434},"\u002F\u002F trade-off: lab assertions use one viewport and fast hardware. Run them at the\n",[429,647,649],{"class":83,"line":648},7,[429,650,651],{"class":434},"\u002F\u002F smallest supported viewport, where element swaps are most likely.\n",[15,653,654],{},"Expected outcome: regressions that change the LCP element are caught in CI rather than discovered in field data a month later.",[408,656,658],{"id":657},"_2-make-the-intended-element-win-early","2. Make the intended element win early",[15,660,661],{},"Preload and prioritise the intended LCP image so it paints before competing text, and give it dimensions that keep it the largest element at mobile widths.",[420,663,667],{"className":664,"code":665,"language":666,"meta":425,"style":425},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Clink rel=\"preload\" as=\"image\" href=\"\u002Fimg\u002Fhero-800.avif\" fetchpriority=\"high\"\n      imagesrcset=\"\u002Fimg\u002Fhero-400.avif 400w, \u002Fimg\u002Fhero-800.avif 800w\" imagesizes=\"100vw\">\n\u003Cimg src=\"\u002Fimg\u002Fhero-800.avif\" srcset=\"\u002Fimg\u002Fhero-400.avif 400w, \u002Fimg\u002Fhero-800.avif 800w\"\n     sizes=\"100vw\" width=\"800\" height=\"600\" fetchpriority=\"high\" alt=\"\">\n\u003C!-- trade-off: forcing an image to be LCP on mobile is only worth it if the\n     image is genuinely the main content. If the heading is what users read\n     first, let the heading be LCP and optimise for text instead. -->\n","html",[38,668,669,711,732,753,795,800,805],{"__ignoreMap":425},[429,670,671,674,678,681,684,687,690,692,695,698,700,703,706,708],{"class":83,"line":431},[429,672,673],{"class":452},"\u003C",[429,675,677],{"class":676},"sZBmE","link",[429,679,680],{"class":445}," rel",[429,682,683],{"class":452},"=",[429,685,686],{"class":456},"\"preload\"",[429,688,689],{"class":445}," as",[429,691,683],{"class":452},[429,693,694],{"class":456},"\"image\"",[429,696,697],{"class":445}," href",[429,699,683],{"class":452},[429,701,702],{"class":456},"\"\u002Fimg\u002Fhero-800.avif\"",[429,704,705],{"class":445}," fetchpriority",[429,707,683],{"class":452},[429,709,710],{"class":456},"\"high\"\n",[429,712,713,716,718,721,724,726,729],{"class":83,"line":438},[429,714,715],{"class":445},"      imagesrcset",[429,717,683],{"class":452},[429,719,720],{"class":456},"\"\u002Fimg\u002Fhero-400.avif 400w, \u002Fimg\u002Fhero-800.avif 800w\"",[429,722,723],{"class":445}," imagesizes",[429,725,683],{"class":452},[429,727,728],{"class":456},"\"100vw\"",[429,730,731],{"class":452},">\n",[429,733,734,736,738,741,743,745,748,750],{"class":83,"line":480},[429,735,673],{"class":452},[429,737,49],{"class":676},[429,739,740],{"class":445}," src",[429,742,683],{"class":452},[429,744,702],{"class":456},[429,746,747],{"class":445}," srcset",[429,749,683],{"class":452},[429,751,752],{"class":456},"\"\u002Fimg\u002Fhero-400.avif 400w, \u002Fimg\u002Fhero-800.avif 800w\"\n",[429,754,755,758,760,762,765,767,770,773,775,778,780,782,785,788,790,793],{"class":83,"line":541},[429,756,757],{"class":445},"     sizes",[429,759,683],{"class":452},[429,761,728],{"class":456},[429,763,764],{"class":445}," width",[429,766,683],{"class":452},[429,768,769],{"class":456},"\"800\"",[429,771,772],{"class":445}," height",[429,774,683],{"class":452},[429,776,777],{"class":456},"\"600\"",[429,779,705],{"class":445},[429,781,683],{"class":452},[429,783,784],{"class":456},"\"high\"",[429,786,787],{"class":445}," alt",[429,789,683],{"class":452},[429,791,792],{"class":456},"\"\"",[429,794,731],{"class":452},[429,796,797],{"class":83,"line":618},[429,798,799],{"class":434},"\u003C!-- trade-off: forcing an image to be LCP on mobile is only worth it if the\n",[429,801,802],{"class":83,"line":642},[429,803,804],{"class":434},"     image is genuinely the main content. If the heading is what users read\n",[429,806,807],{"class":83,"line":648},[429,808,809],{"class":434},"     first, let the heading be LCP and optimise for text instead. -->\n",[15,811,812],{},"Expected outcome: the LCP element distribution in RUM concentrates on one element per template, and timing variance shrinks.",[408,814,816],{"id":815},"_3-keep-late-overlays-from-becoming-lcp","3. Keep late overlays from becoming LCP",[15,818,819],{},"Server-render consent banners and announcement bars with a compact layout so they paint early and small, or render them in a way that does not out-size the main content on small screens.",[420,821,825],{"className":822,"code":823,"language":824,"meta":425,"style":425},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast",".consent-banner { max-height: 30vh; font-size: 0.875rem; }\n\u002F* trade-off: shrinking the banner reduces its candidate size, but if it is\n   still the largest TEXT on a screen with only an image hero, it will not\n   matter — images and text compete on area. Check on the smallest viewport. *\u002F\n","css",[38,826,827,862,867,872],{"__ignoreMap":425},[429,828,829,832,834,837,839,842,845,848,851,853,856,859],{"class":83,"line":431},[429,830,831],{"class":445},".consent-banner",[429,833,453],{"class":452},[429,835,836],{"class":445},"max-height",[429,838,460],{"class":452},[429,840,841],{"class":445},"30",[429,843,844],{"class":441},"vh",[429,846,847],{"class":452},"; ",[429,849,850],{"class":445},"font-size",[429,852,460],{"class":452},[429,854,855],{"class":445},"0.875",[429,857,858],{"class":441},"rem",[429,860,861],{"class":452},"; }\n",[429,863,864],{"class":83,"line":438},[429,865,866],{"class":434},"\u002F* trade-off: shrinking the banner reduces its candidate size, but if it is\n",[429,868,869],{"class":83,"line":480},[429,870,871],{"class":434},"   still the largest TEXT on a screen with only an image hero, it will not\n",[429,873,874],{"class":83,"line":541},[429,875,876],{"class":434},"   matter — images and text compete on area. Check on the smallest viewport. *\u002F\n",[15,878,879],{},"Expected outcome: banners stop appearing in the field LCP element distribution.",[408,881,883],{"id":882},"_4-stop-client-re-rendering-of-the-lcp-element","4. Stop client re-rendering of the LCP element",[15,885,886],{},"Eliminate hydration mismatches on above-the-fold markup and avoid keying hero components on values that differ between server and client. Disable carousel autoplay until after the first user interaction.",[420,888,890],{"className":422,"code":889,"language":424,"meta":425,"style":425},"\u002F\u002F Carousel: do not advance until the user has interacted or the page is idle.\nlet allowAutoplay = false;\naddEventListener('pointerdown', () => { allowAutoplay = true; }, { once: true });\nrequestIdleCallback(() => { setTimeout(() => { allowAutoplay = true; }, 5000); });\n\u002F\u002F trade-off: delaying autoplay changes the product behaviour slightly. Most\n\u002F\u002F teams find a 5s delay invisible to users, but confirm with the design owner.\n",[38,891,892,897,913,944,977,982],{"__ignoreMap":425},[429,893,894],{"class":83,"line":431},[429,895,896],{"class":434},"\u002F\u002F Carousel: do not advance until the user has interacted or the page is idle.\n",[429,898,899,902,905,907,910],{"class":83,"line":438},[429,900,901],{"class":441},"let",[429,903,904],{"class":452}," allowAutoplay ",[429,906,683],{"class":441},[429,908,909],{"class":445}," false",[429,911,912],{"class":452},";\n",[429,914,915,918,920,923,926,928,931,933,936,939,941],{"class":83,"line":480},[429,916,917],{"class":496},"addEventListener",[429,919,564],{"class":452},[429,921,922],{"class":456},"'pointerdown'",[429,924,925],{"class":452},", () ",[429,927,503],{"class":441},[429,929,930],{"class":452}," { allowAutoplay ",[429,932,683],{"class":441},[429,934,935],{"class":445}," true",[429,937,938],{"class":452},"; }, { once: ",[429,940,636],{"class":445},[429,942,943],{"class":452}," });\n",[429,945,946,949,951,953,955,958,960,962,964,966,968,971,974],{"class":83,"line":541},[429,947,948],{"class":496},"requestIdleCallback",[429,950,500],{"class":452},[429,952,503],{"class":441},[429,954,453],{"class":452},[429,956,957],{"class":496},"setTimeout",[429,959,500],{"class":452},[429,961,503],{"class":441},[429,963,930],{"class":452},[429,965,683],{"class":441},[429,967,935],{"class":445},[429,969,970],{"class":452},"; }, ",[429,972,973],{"class":445},"5000",[429,975,976],{"class":452},"); });\n",[429,978,979],{"class":83,"line":618},[429,980,981],{"class":434},"\u002F\u002F trade-off: delaying autoplay changes the product behaviour slightly. Most\n",[429,983,984],{"class":83,"line":642},[429,985,986],{"class":434},"\u002F\u002F teams find a 5s delay invisible to users, but confirm with the design owner.\n",[15,988,989],{},"Expected outcome: the LCP timestamp matches the first paint of the hero rather than a later repaint.",[15,991,992],{},[45,993,52,996,52,999,52,1002,52,1004,52,1007,52,1009,52,1016,52,1022,52,1027,52,1031,52,1036,52,1040,52,1044,52,1048,52,1052,52,1056,52,1060,52,1064,52,1068,52,1072,52],{"viewBox":994,"width":48,"role":49,"ariaLabel":995,"style":51},"0 0 760 225","Bar chart showing the share of page views for which each element was LCP on mobile, before and after the fixes, with the hero image becoming dominant.",[54,997],{"className":998,"x":58,"y":58,"width":48,"height":48,"fill":59},[57],[61,1000,1001],{},"Field LCP element share before and after stabilising",[65,1003,995],{},[54,1005],{"x":69,"y":69,"width":70,"height":1006,"rx":72,"fill":73,"stroke":74,"style":75},"223",[77,1008,1001],{"x":79,"y":80,"fill":74,"style":81},[77,1010,1015],{"x":1011,"y":1012,"fill":74,"style":1013,"textAnchor":1014},"167.5","70.0","font-size:13px","end","Hero image (before)",[54,1017],{"x":1018,"y":292,"width":1019,"height":1020,"rx":104,"fill":117,"stroke":117,"style":1021},"179.5","217.7","19","fill-opacity:0.55;stroke-opacity:0.9",[77,1023,1026],{"x":1024,"y":1012,"fill":74,"style":1025},"403.2","font-size:12px;font-weight:600","41%",[77,1028,1030],{"x":1011,"y":1029,"fill":74,"style":1013,"textAnchor":1014},"101.0","H1 (before)",[54,1032],{"x":1018,"y":1033,"width":1034,"height":1020,"rx":104,"fill":74,"stroke":74,"style":1035},"87.0","175.2","fill-opacity:0.7;stroke-opacity:0.4",[77,1037,1039],{"x":1038,"y":1029,"fill":74,"style":1025},"360.7","33%",[77,1041,1043],{"x":1011,"y":1042,"fill":74,"style":1013,"textAnchor":1014},"132.0","Consent banner (before)",[54,1045],{"x":1018,"y":87,"width":1046,"height":1020,"rx":104,"fill":127,"stroke":88,"style":1047},"138.1","fill-opacity:0.7;stroke-opacity:0.9",[77,1049,1051],{"x":1050,"y":1042,"fill":74,"style":1025},"323.5","26%",[77,1053,1055],{"x":1011,"y":1054,"fill":74,"style":1013,"textAnchor":1014},"163.0","Hero image (after)",[54,1057],{"x":1018,"y":1058,"width":1059,"height":1020,"rx":104,"fill":117,"stroke":117,"style":1021},"149.0","488.5",[77,1061,1063],{"x":1062,"y":1054,"fill":74,"style":1025},"674.0","92%",[77,1065,1067],{"x":1011,"y":1066,"fill":74,"style":1013,"textAnchor":1014},"194.0","H1 (after)",[54,1069],{"x":1018,"y":1070,"width":1071,"height":1020,"rx":104,"fill":74,"stroke":74,"style":1035},"180.0","42.5",[77,1073,1075],{"x":1074,"y":1066,"fill":74,"style":1025},"227.9","8%",[180,1077,1079],{"id":1078},"verification","Verification",[15,1081,1082],{},"Re-run the candidate logger across five loads at mobile and desktop widths, with and without throttling. The final candidate should be the intended element on every run. In RUM, the element distribution for each template should be dominated by one selector, and the p75 LCP for that selector should match the overall p75 closely. Finally, compare LCP variance: a stable element typically halves the gap between p50 and p95, which makes regressions much easier to detect.",[180,1084,1086],{"id":1085},"when-an-unstable-lcp-element-is-acceptable","When an Unstable LCP Element Is Acceptable",[15,1088,1089,1090,1093],{},"Not every variation needs fixing. On a news homepage where the lead story changes hourly, the LCP element is ",[33,1091,1092],{},"meant"," to change — sometimes a photo, sometimes a headline. What matters is that each candidate type is fast. Group by element type (image vs text) rather than by selector, and set budgets for both. Similarly, desktop and mobile having different LCP elements is a natural consequence of responsive design; treat them as separate experiences with separate p75 values instead of forcing one element to win everywhere.",[180,1095,1097],{"id":1096},"faq","FAQ",[1099,1100,1103,1107],"details",{"className":1101},[1102],"faq-item",[1104,1105,1106],"summary",{},"Does a background image count as an LCP candidate?",[15,1108,1109,1110,1113,1114,1118],{},"Yes — CSS ",[38,1111,1112],{},"background-image"," on an element is a candidate, sized by the visible area of the element. It is usually a poor LCP choice because the preload scanner cannot discover it from HTML; ",[19,1115,1117],{"href":1116},"\u002Fimage-media-optimization\u002Fimage-decoding-and-placeholders\u002Fcss-background-images-as-lcp-elements\u002F","CSS background images as LCP elements"," covers how to fix that.",[1099,1120,1122,1125],{"className":1121},[1102],[1104,1123,1124],{},"Why do elements removed from the DOM not count?",[15,1126,1127],{},"Since Chrome 88, if an LCP candidate is removed from the DOM, the browser does not report it as the final LCP — it considers the next-largest remaining element. This is why a skeleton or placeholder that is replaced by real content stops being a candidate, and why a hydration re-mount produces a new, later candidate rather than keeping the original timing.",[180,1129,1131],{"id":1130},"related","Related",[185,1133,1134,1141,1148],{},[188,1135,1136,1140],{},[19,1137,1139],{"href":1138},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Ffixing-lcp-when-the-h1-is-the-lcp-element\u002F","Fixing LCP when the H1 is the LCP element"," — optimising for a text winner.",[188,1142,1143,1147],{},[19,1144,1146],{"href":1145},"\u002Fcore-web-vitals-measurement\u002Funderstanding-core-web-vitals-thresholds\u002Fwhy-lab-and-field-lcp-disagree\u002F","Why lab and field LCP disagree"," — the broader lab\u002Ffield gap of which element instability is one cause.",[188,1149,1150,1154],{},[19,1151,1153],{"href":1152},"\u002Fcore-web-vitals-measurement\u002Freducing-cumulative-layout-shift-cls\u002Ffixing-cls-from-cookie-consent-banners\u002F","Fixing CLS from cookie consent banners"," — the layout side of late overlays.",[1156,1157,1159],"script",{"type":1158},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Why the LCP Element Changes Between Loads — and How to Make It Stable\",\n  \"description\": \"How the browser picks LCP candidates, why the winning element varies between loads and devices, and how to stabilise it so fixes stick.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Decide what the LCP element should be, per template and viewport\",\n      \"text\": \"Write it down: \\\"Product page, mobile: main product image.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Make the intended element win early\",\n      \"text\": \"Preload and prioritise the intended LCP image so it paints before competing text, and give it dimensions that keep it the largest element at mobile widths.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Keep late overlays from becoming LCP\",\n      \"text\": \"Server-render consent banners and announcement bars with a compact layout so they paint early and small, or render them in a way that does not out-size the main content on small screens.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Stop client re-rendering of the LCP element\",\n      \"text\": \"Eliminate hydration mismatches on above-the-fold markup and avoid keying hero components on values that differ between server and client.\"\n    }\n  ]\n}\n",[1156,1161,1162],{"type":1158},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"Why the LCP Element Changes Between Loads — and How to Make It Stable\",\n  \"description\": \"How the browser picks LCP candidates, why the winning element varies between loads and devices, and how to stabilise it so fixes stick.\",\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\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads\u002F\"\n  }\n}\n",[1156,1164,1165],{"type":1158},"\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\": \"Core Web Vitals & Measurement\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Measuring LCP with Chrome DevTools\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Why the LCP Element Changes Between Loads\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads\u002F\"\n    }\n  ]\n}\n",[1167,1168,1169],"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 .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}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);}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}",{"title":425,"searchDepth":438,"depth":438,"links":1171},[1172,1173,1174,1181,1182,1183,1184],{"id":182,"depth":438,"text":183},{"id":227,"depth":438,"text":228},{"id":405,"depth":438,"text":406,"children":1175},[1176,1178,1179,1180],{"id":410,"depth":480,"text":1177},"1. Decide what the LCP element should be, per template and viewport",{"id":657,"depth":480,"text":658},{"id":815,"depth":480,"text":816},{"id":882,"depth":480,"text":883},{"id":1078,"depth":438,"text":1079},{"id":1085,"depth":438,"text":1086},{"id":1096,"depth":438,"text":1097},{"id":1130,"depth":438,"text":1131},"How the browser picks LCP candidates, why the winning element varies between loads and devices, and how to stabilise it so fixes stick.","md",{"slug":1188,"type":1189,"breadcrumb":1190,"datePublished":1198,"dateModified":1198},"why-the-lcp-element-changes-between-loads","article",[1191,1194,1195,1196],{"name":1192,"url":1193},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1197},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads\u002F","2026-10-06",true,"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads",{"title":1202,"description":1203},"Why the LCP Element Changes Between Page Loads","The LCP element can differ by viewport, font timing, carousel state or hydration. Learn how candidates are chosen and how to make LCP stable and fixable.","core-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fwhy-the-lcp-element-changes-between-loads\u002Findex","hAkvkNhyMc9fLwWhZ65gBw3seZMzwSG9HFkf-hzBFS0",[1207,1211],{"title":1208,"path":1209,"stem":1210,"children":-1},"Fix LCP Over 2.5s on React Apps","\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fhow-to-fix-lcp-over-25-seconds-on-react-apps","core-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002Fhow-to-fix-lcp-over-25-seconds-on-react-apps\u002Findex",{"title":1212,"path":1213,"stem":1214,"children":-1},"Offloading Work to Web Workers with Comlink","\u002Fcore-web-vitals-measurement\u002Foffloading-work-to-web-workers-with-comlink","core-web-vitals-measurement\u002Foffloading-work-to-web-workers-with-comlink\u002Findex",1791308073843]