[{"data":1,"prerenderedAt":947},["ShallowReactive",2],{"content:\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F":3,"surroundings:\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F":939},{"id":4,"title":5,"body":6,"description":918,"extension":919,"meta":920,"navigation":932,"path":933,"seo":934,"stem":937,"__hash__":938},"content\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002Findex.md","Finding the Slowest Interaction in the Performance Panel",{"type":7,"value":8,"toc":911},"minimark",[9,13,38,49,149,154,157,208,212,222,228,246,256,274,288,292,301,320,326,543,546,552,569,579,729,732,736,742,858,863,867,896,901,904,907],[10,11,5],"h1",{"id":12},"finding-the-slowest-interaction-in-the-performance-panel",[14,15,16,17,22,23,27,28,32,33,37],"p",{},"This scenario page belongs to ",[18,19,21],"a",{"href":20},"\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002F","profiling event handlers for INP"," under ",[18,24,26],{"href":25},"\u002Fcore-web-vitals-measurement\u002F","Core Web Vitals & Measurement",", and it solves one narrow problem: you have a recording full of clicks, scrolls, and typing, your field INP is over ",[29,30,31],"code",{},"200ms",", and you need to find the ",[34,35,36],"em",{},"one"," interaction that owns that number.",[14,39,40,41,44,45,48],{},"The trap is that a long session contains dozens of interactions and most are fast. INP reports the worst (or near-worst), so eyeballing the flame chart for \"something big\" wastes time — the dominant interaction may be a ",[29,42,43],{},"220ms"," bar surrounded by fast ",[29,46,47],{},"30ms"," ones, easy to miss. This is a search problem first and an optimization problem second.",[14,50,51],{},[52,53,60,61,60,65,60,69,60,79,60,86,60,92,60,97,60,103,60,111,60,116,60,120,60,125,60,131,60,136,60,140,60,145,60],"svg",{"xmlns":54,"viewBox":55,"width":56,"role":57,"ariaLabel":58,"style":59},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","0 0 760 250","100%","img","The DevTools Interactions track with many fast bars and one wide bar over the 200ms boundary highlighted","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:#001d3d"," ",[62,63,64],"title",{},"Spotting the worst bar in the Interactions track",[66,67,68],"desc",{},"Several fast interaction bars under 80ms and one 230ms bar that crosses the INP boundary line.",[70,71],"rect",{"x":72,"y":72,"width":73,"height":74,"rx":75,"fill":76,"stroke":77,"style":78},"1","758","248","10","none","currentColor","stroke-opacity:0.18",[80,81,85],"text",{"x":82,"y":83,"fill":77,"style":84},"24","38","font-size:18px;font-weight:700","Interactions track (sort by width)",[87,88],"line",{"x1":82,"y1":89,"x2":82,"y2":90,"stroke":77,"style":91},"60","210","stroke-opacity:0.3",[87,93],{"x1":94,"y1":89,"x2":94,"y2":90,"stroke":95,"style":96},"520","#b8860b","stroke-width:2",[80,98,102],{"x":99,"y":100,"fill":77,"style":101},"528","76","font-size:13px;font-weight:600","200ms boundary",[70,104],{"x":82,"y":105,"width":106,"height":107,"rx":108,"fill":109,"stroke":109,"style":110},"84","70","22","4","#0466c8","fill-opacity:0.14",[80,112,115],{"x":113,"y":113,"fill":77,"style":114},"100","font-size:13px","click 28ms",[70,117],{"x":82,"y":118,"width":119,"height":107,"rx":108,"fill":109,"stroke":109,"style":110},"114","150",[80,121,124],{"x":122,"y":123,"fill":77,"style":114},"180","130","input 62ms",[70,126],{"x":82,"y":127,"width":128,"height":107,"rx":108,"fill":129,"stroke":95,"style":130},"144","560","#ffc300","fill-opacity:0.30",[80,132,135],{"x":133,"y":134,"fill":77,"style":101},"200","160","click 230ms (the one that fails)",[70,137],{"x":82,"y":138,"width":139,"height":107,"rx":108,"fill":109,"stroke":109,"style":110},"174","95",[80,141,144],{"x":142,"y":143,"fill":77,"style":114},"125","190","tap 40ms",[80,146,148],{"x":82,"y":147,"fill":77,"style":114},"232","Read bar width, not stack height; the widest bar is your INP candidate.",[150,151,153],"h2",{"id":152},"rapid-diagnosis-checklist","Rapid Diagnosis Checklist",[14,155,156],{},"Before recording, confirm the setup that makes the slow bar visible:",[158,159,160,176,182,196,202],"ul",{},[161,162,163,167,168,171,172,175],"li",{},[164,165,166],"strong",{},"CPU throttling is on."," Set ",[29,169,170],{},"4x"," (or ",[29,173,174],{},"6x",") slowdown in the Performance panel gear menu. An unthrottled desktop hides the regression that real mid-tier Android exposes.",[161,177,178,181],{},[164,179,180],{},"The Interactions track is visible."," It sits directly under the main timeline ruler. If it is collapsed, expand it — this track, not the flame chart, is where you find the bar.",[161,183,184,187,188,191,192,195],{},[164,185,186],{},"You reproduced the real interaction."," INP is driven by ",[29,189,190],{},"click",", ",[29,193,194],{},"tap",", and keyboard input, not scroll. If you only scrolled, there is nothing to find.",[161,197,198,201],{},[164,199,200],{},"The recording is short and targeted."," Record the suspect flow only (open the menu, type in the filter, submit), not a five-minute browse. A tight recording makes the widest bar obvious.",[161,203,204,207],{},[164,205,206],{},"You know the field target."," Pull the worst-interaction element selector from RUM first if you have it, so you know which interaction to reproduce.",[150,209,211],{"id":210},"root-cause-analysis-why-the-slow-interaction-hides","Root Cause Analysis: Why the Slow Interaction Hides",[14,213,214,217,218,221],{},[164,215,216],{},"The widest bar is not the busiest flame chart region."," Engineers scan the main thread track for the tallest stack and assume that is the slow interaction. But a tall stack during page load is not an interaction at all, and the slow interaction may have a modest-looking stack whose cost is input delay — time ",[34,219,220],{},"before"," the handler ran — which shows as a gap, not a stack. The Interactions track measures total latency including that gap; the flame chart does not.",[14,223,224,227],{},[164,225,226],{},"Input delay makes the handler look innocent."," When the main thread was busy at click time, the interaction's latency is dominated by the wait before the listener even starts. The handler's own flame-chart block is small, so it gets overlooked, yet the Interactions bar is wide. You must read the bar, not the stack, to see this.",[14,229,230,233,234,237,238,241,242,245],{},[164,231,232],{},"Multiple interactions blur together."," Rapid typing fires an ",[29,235,236],{},"input"," interaction per keystroke. Several ",[29,239,240],{},"60ms"," interactions in a row can look like one long region, hiding the single ",[29,243,244],{},"210ms"," keystroke that actually fails. Sorting by latency, not scanning visually, separates them.",[14,247,248,251,252,255],{},[164,249,250],{},"The worst field interaction never happens in the lab."," If you reproduce the wrong flow, the slow bar simply is not in your recording. The cure is to seed the lab run from the RUM ",[29,253,254],{},"interactionTarget"," selector so you reproduce the exact element that fails in the field.",[14,257,258,261,262,264,265,267,268,270,271,273],{},[164,259,260],{},"Throttling masks or exaggerates the real bottleneck."," Too little CPU throttling and the slow interaction never crosses ",[29,263,31],{}," locally, so it never appears as a standout bar; too much and unrelated work balloons, burying the true culprit under noise. The reliable setting for INP work is ",[29,266,170],{}," slowdown, which approximates the mid-tier Android hardware that dominates the field p75. If a bar looks slow only at ",[29,269,174],{}," but fine at ",[29,272,170],{},", you are chasing a device class your field data does not represent — calibrate the throttle to your RUM device mix, not to whatever makes a bar look dramatic.",[14,275,276,279,280,283,284,287],{},[164,277,278],{},"Self-time versus total time confusion in the stack."," Once you drill into the flame chart, the tallest block is often a framework entry point whose ",[34,281,282],{},"total"," time is large but whose ",[34,285,286],{},"self"," time is trivial — the real cost is a child call. Switching the Summary view to sort by self-time, rather than reading the deepest visible frame, is what points at the function that actually spends the budget. Reading total time here sends you to optimize a wrapper that merely calls the slow code.",[150,289,291],{"id":290},"step-by-step-resolution","Step-by-Step Resolution",[14,293,294,297,298,300],{},[164,295,296],{},"1. Record the targeted flow."," Open the Performance panel, confirm ",[29,299,170],{}," throttling, click record, perform only the suspect interactions, and stop. Keep it under ~15 seconds. Expected outcome: a recording where the Interactions track shows a small, countable set of bars rather than a wall of them.",[14,302,303,306,307,60,310,312,313,315,316,319],{},[164,304,305],{},"2. Read the Interactions track, not the flame chart."," Each interaction is a bar whose width is its measured latency. Hover any bar for a tooltip with the interaction type and total duration. The widest bar is your INP candidate. Expected outcome: you identify a single bar — for example a ",[29,308,309],{},"230ms",[29,311,190],{}," — that exceeds the ",[29,314,31],{}," boundary while the rest sit under ",[29,317,318],{},"80ms",".",[14,321,322,325],{},[164,323,324],{},"3. Confirm the ranking with the Event Timing API."," Visual width can deceive across zoom levels, so confirm numerically. Paste this into the Console before re-running the flow and read the sorted list:",[327,328,333],"pre",{"className":329,"code":330,"language":331,"meta":332,"style":332},"language-javascript shiki shiki-themes github-light-high-contrast github-light-high-contrast github-light-high-contrast","const entries = [];\nnew PerformanceObserver((list) => {\n  for (const e of list.getEntries()) {\n    if (e.interactionId) entries.push({ name: e.name, dur: Math.round(e.duration), id: e.interactionId });\n  }\n  \u002F\u002F sort descending so the worst interaction is always row 0\n  console.table([...entries].sort((a, b) => b.dur - a.dur).slice(0, 5));\n}).observe({ type: 'event', durationThreshold: 16, buffered: true });\n\u002F\u002F trade-off: durationThreshold:16 captures everything for a clean ranking but is noisy\n\u002F\u002F and adds per-event overhead — use it only for this manual hunt, never in production RUM.\n","javascript","",[29,334,335,354,380,406,427,433,440,500,531,537],{"__ignoreMap":332},[336,337,339,343,347,350],"span",{"class":87,"line":338},1,[336,340,342],{"class":341},"sP5qI","const",[336,344,346],{"class":345},"sf6mN"," entries",[336,348,349],{"class":341}," =",[336,351,353],{"class":352},"syybb"," [];\n",[336,355,357,360,364,367,371,374,377],{"class":87,"line":356},2,[336,358,359],{"class":341},"new",[336,361,363],{"class":362},"ssM3C"," PerformanceObserver",[336,365,366],{"class":352},"((",[336,368,370],{"class":369},"seIZK","list",[336,372,373],{"class":352},") ",[336,375,376],{"class":341},"=>",[336,378,379],{"class":352}," {\n",[336,381,383,386,389,391,394,397,400,403],{"class":87,"line":382},3,[336,384,385],{"class":341},"  for",[336,387,388],{"class":352}," (",[336,390,342],{"class":341},[336,392,393],{"class":345}," e",[336,395,396],{"class":341}," of",[336,398,399],{"class":352}," list.",[336,401,402],{"class":362},"getEntries",[336,404,405],{"class":352},"()) {\n",[336,407,409,412,415,418,421,424],{"class":87,"line":408},4,[336,410,411],{"class":341},"    if",[336,413,414],{"class":352}," (e.interactionId) entries.",[336,416,417],{"class":362},"push",[336,419,420],{"class":352},"({ name: e.name, dur: Math.",[336,422,423],{"class":362},"round",[336,425,426],{"class":352},"(e.duration), id: e.interactionId });\n",[336,428,430],{"class":87,"line":429},5,[336,431,432],{"class":352},"  }\n",[336,434,436],{"class":87,"line":435},6,[336,437,439],{"class":438},"sIIH1","  \u002F\u002F sort descending so the worst interaction is always row 0\n",[336,441,443,446,449,452,455,458,461,463,465,467,470,472,474,477,480,483,486,489,492,494,497],{"class":87,"line":442},7,[336,444,445],{"class":352},"  console.",[336,447,448],{"class":362},"table",[336,450,451],{"class":352},"([",[336,453,454],{"class":341},"...",[336,456,457],{"class":352},"entries].",[336,459,460],{"class":362},"sort",[336,462,366],{"class":352},[336,464,18],{"class":369},[336,466,191],{"class":352},[336,468,469],{"class":369},"b",[336,471,373],{"class":352},[336,473,376],{"class":341},[336,475,476],{"class":352}," b.dur ",[336,478,479],{"class":341},"-",[336,481,482],{"class":352}," a.dur).",[336,484,485],{"class":362},"slice",[336,487,488],{"class":352},"(",[336,490,491],{"class":345},"0",[336,493,191],{"class":352},[336,495,496],{"class":345},"5",[336,498,499],{"class":352},"));\n",[336,501,503,506,509,512,516,519,522,525,528],{"class":87,"line":502},8,[336,504,505],{"class":352},"}).",[336,507,508],{"class":362},"observe",[336,510,511],{"class":352},"({ type: ",[336,513,515],{"class":514},"s-_DF","'event'",[336,517,518],{"class":352},", durationThreshold: ",[336,520,521],{"class":345},"16",[336,523,524],{"class":352},", buffered: ",[336,526,527],{"class":345},"true",[336,529,530],{"class":352}," });\n",[336,532,534],{"class":87,"line":533},9,[336,535,536],{"class":438},"\u002F\u002F trade-off: durationThreshold:16 captures everything for a clean ranking but is noisy\n",[336,538,540],{"class":87,"line":539},10,[336,541,542],{"class":438},"\u002F\u002F and adds per-event overhead — use it only for this manual hunt, never in production RUM.\n",[14,544,545],{},"Expected outcome: a table whose top row is the worst interaction's name and duration, matching the widest bar and removing any doubt about which one to chase.",[14,547,548,551],{},[164,549,550],{},"4. Expand the bar into its three phases."," Click the widest bar in the Interactions track. DevTools highlights the input-delay segment (the striped lead-in before processing), the processing block, and the presentation gap before the next frame commits. Expected outcome: you can see at a glance which phase fills the bar — a long striped lead-in means input delay, a fat middle means processing, a trailing gap means presentation delay.",[14,553,554,557,558,561,562,565,566,319],{},[164,555,556],{},"5. Drill from the bar into the responsible stack."," With the bar selected, look at the main-thread flame chart directly beneath it during the processing block. The dominant function in that stack is the handler (or the framework re-render it triggered) that owns the time. Right-click and \"show in summary\" to get the self-time. Expected outcome: a named function and file — for example a ",[29,559,560],{},"filterRows"," call inside an ",[29,563,564],{},"onChange"," handler running for ",[29,567,568],{},"170ms",[14,570,571,574,575,578],{},[164,572,573],{},"6. Cross-check with LoAF for an exact source position."," If the flame chart bundles several callbacks, the ",[18,576,577],{"href":20},"Long Animation Frames API"," attributes the frame down to the source. Run this and re-trigger the interaction:",[327,580,582],{"className":329,"code":581,"language":331,"meta":332,"style":332},"new PerformanceObserver((list) => {\n  for (const f of list.getEntries()) {\n    if (f.blockingDuration === 0) continue;\n    \u002F\u002F invoker names the handler; sourceCharPosition points at the line\n    f.scripts.sort((a, b) => b.duration - a.duration);\n    console.log(f.scripts[0]?.invoker, f.scripts[0]?.sourceURL, f.scripts[0]?.sourceCharPosition);\n  }\n}).observe({ type: 'long-animation-frame', buffered: true });\n\u002F\u002F trade-off: LoAF reports at frame granularity, so a frame with several similar-duration\n\u002F\u002F scripts needs the flame chart to disambiguate — treat invoker as a strong hint, not proof.\n",[29,583,584,600,619,640,645,672,698,702,719,724],{"__ignoreMap":332},[336,585,586,588,590,592,594,596,598],{"class":87,"line":338},[336,587,359],{"class":341},[336,589,363],{"class":362},[336,591,366],{"class":352},[336,593,370],{"class":369},[336,595,373],{"class":352},[336,597,376],{"class":341},[336,599,379],{"class":352},[336,601,602,604,606,608,611,613,615,617],{"class":87,"line":356},[336,603,385],{"class":341},[336,605,388],{"class":352},[336,607,342],{"class":341},[336,609,610],{"class":345}," f",[336,612,396],{"class":341},[336,614,399],{"class":352},[336,616,402],{"class":362},[336,618,405],{"class":352},[336,620,621,623,626,629,632,634,637],{"class":87,"line":382},[336,622,411],{"class":341},[336,624,625],{"class":352}," (f.blockingDuration ",[336,627,628],{"class":341},"===",[336,630,631],{"class":345}," 0",[336,633,373],{"class":352},[336,635,636],{"class":341},"continue",[336,638,639],{"class":352},";\n",[336,641,642],{"class":87,"line":408},[336,643,644],{"class":438},"    \u002F\u002F invoker names the handler; sourceCharPosition points at the line\n",[336,646,647,650,652,654,656,658,660,662,664,667,669],{"class":87,"line":429},[336,648,649],{"class":352},"    f.scripts.",[336,651,460],{"class":362},[336,653,366],{"class":352},[336,655,18],{"class":369},[336,657,191],{"class":352},[336,659,469],{"class":369},[336,661,373],{"class":352},[336,663,376],{"class":341},[336,665,666],{"class":352}," b.duration ",[336,668,479],{"class":341},[336,670,671],{"class":352}," a.duration);\n",[336,673,674,677,680,683,685,688,690,693,695],{"class":87,"line":435},[336,675,676],{"class":352},"    console.",[336,678,679],{"class":362},"log",[336,681,682],{"class":352},"(f.scripts[",[336,684,491],{"class":345},[336,686,687],{"class":352},"]?.invoker, f.scripts[",[336,689,491],{"class":345},[336,691,692],{"class":352},"]?.sourceURL, f.scripts[",[336,694,491],{"class":345},[336,696,697],{"class":352},"]?.sourceCharPosition);\n",[336,699,700],{"class":87,"line":442},[336,701,432],{"class":352},[336,703,704,706,708,710,713,715,717],{"class":87,"line":502},[336,705,505],{"class":352},[336,707,508],{"class":362},[336,709,511],{"class":352},[336,711,712],{"class":514},"'long-animation-frame'",[336,714,524],{"class":352},[336,716,527],{"class":345},[336,718,530],{"class":352},[336,720,721],{"class":87,"line":533},[336,722,723],{"class":438},"\u002F\u002F trade-off: LoAF reports at frame granularity, so a frame with several similar-duration\n",[336,725,726],{"class":87,"line":539},[336,727,728],{"class":438},"\u002F\u002F scripts needs the flame chart to disambiguate — treat invoker as a strong hint, not proof.\n",[14,730,731],{},"Expected outcome: the handler name and exact character position of the slow code, closing the loop from \"worst bar\" to \"this line.\"",[150,733,735],{"id":734},"verification","Verification",[14,737,738,739,741],{},"Confirm you found the right interaction before you spend time fixing it. Re-run the Console ranking from step 3 across a fresh recording of the same flow; the worst interaction should be stable across runs — if a different bar tops the table each time, you are measuring noise and need a quieter machine or heavier throttling. After a fix lands, the before\u002Fafter is unambiguous: the previously widest bar should drop below the ",[29,740,31],{}," line, and the step 3 table's top row should fall under your target. Lock it in CI with a scripted assertion:",[327,743,745],{"className":329,"code":744,"language":331,"meta":332,"style":332},"\u002F\u002F playwright: fail if any long frame during the flow blocks beyond the budget\nconst blocking = await page.evaluate(() => performance\n  .getEntriesByType('long-animation-frame')\n  .reduce((max, f) => Math.max(max, f.blockingDuration), 0));\nexpect(blocking).toBeLessThan(50); \u002F\u002F 50ms long-frame budget\n\u002F\u002F trade-off: this asserts the lab flow only — a slow interaction on a route you did not\n\u002F\u002F script stays invisible, so keep the RUM p75 INP check as the source of truth.\n",[29,746,747,752,778,793,826,848,853],{"__ignoreMap":332},[336,748,749],{"class":87,"line":338},[336,750,751],{"class":438},"\u002F\u002F playwright: fail if any long frame during the flow blocks beyond the budget\n",[336,753,754,756,759,761,764,767,770,773,775],{"class":87,"line":356},[336,755,342],{"class":341},[336,757,758],{"class":345}," blocking",[336,760,349],{"class":341},[336,762,763],{"class":341}," await",[336,765,766],{"class":352}," page.",[336,768,769],{"class":362},"evaluate",[336,771,772],{"class":352},"(() ",[336,774,376],{"class":341},[336,776,777],{"class":352}," performance\n",[336,779,780,783,786,788,790],{"class":87,"line":382},[336,781,782],{"class":352},"  .",[336,784,785],{"class":362},"getEntriesByType",[336,787,488],{"class":352},[336,789,712],{"class":514},[336,791,792],{"class":352},")\n",[336,794,795,797,800,802,805,807,810,812,814,817,819,822,824],{"class":87,"line":408},[336,796,782],{"class":352},[336,798,799],{"class":362},"reduce",[336,801,366],{"class":352},[336,803,804],{"class":369},"max",[336,806,191],{"class":352},[336,808,809],{"class":369},"f",[336,811,373],{"class":352},[336,813,376],{"class":341},[336,815,816],{"class":352}," Math.",[336,818,804],{"class":362},[336,820,821],{"class":352},"(max, f.blockingDuration), ",[336,823,491],{"class":345},[336,825,499],{"class":352},[336,827,828,831,834,837,839,842,845],{"class":87,"line":429},[336,829,830],{"class":362},"expect",[336,832,833],{"class":352},"(blocking).",[336,835,836],{"class":362},"toBeLessThan",[336,838,488],{"class":352},[336,840,841],{"class":345},"50",[336,843,844],{"class":352},"); ",[336,846,847],{"class":438},"\u002F\u002F 50ms long-frame budget\n",[336,849,850],{"class":87,"line":435},[336,851,852],{"class":438},"\u002F\u002F trade-off: this asserts the lab flow only — a slow interaction on a route you did not\n",[336,854,855],{"class":87,"line":442},[336,856,857],{"class":438},"\u002F\u002F script stays invisible, so keep the RUM p75 INP check as the source of truth.\n",[14,859,860,861,319],{},"Finally, confirm the field: the p75 INP for the affected interaction's selector should drop in your RUM dashboard. The lab hunt finds the interaction; the field number proves it was the one that mattered. For the deeper attribution model and the fixes that follow, return to ",[18,862,21],{"href":20},[150,864,866],{"id":865},"related","Related",[158,868,869,875,882,889],{},[161,870,871,874],{},[18,872,873],{"href":20},"Profiling event handlers for INP"," — the full attribution workflow this hunt feeds into.",[161,876,877,881],{},[18,878,880],{"href":879},"\u002Fcore-web-vitals-measurement\u002Foptimizing-inp-with-scheduler-yield\u002F","Optimizing INP with scheduler.yield()"," — split the slow handler once you have located it.",[161,883,884,888],{},[18,885,887],{"href":886},"\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Freducing-input-delay-from-third-party-tags\u002F","Reducing input delay from third-party tags"," — when the slow bar is dominated by its input-delay segment.",[161,890,891,895],{},[18,892,894],{"href":893},"\u002Fcore-web-vitals-measurement\u002Foffloading-work-to-web-workers-with-comlink\u002F","Offloading work to web workers with Comlink"," — when the dominant function is too heavy to keep on the main thread.",[897,898,900],"script",{"type":899},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Finding the Slowest Interaction in the Performance Panel\",\n  \"description\": \"Locate the worst INP interaction in a DevTools Performance recording and attribute its latency to a specific handler.\",\n  \"step\": [\n    { \"@type\": \"HowToStep\", \"name\": \"Record the targeted flow\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Read the Interactions track\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Confirm the ranking with the Event Timing API\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Expand the bar into its three phases\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F#step-by-step-resolution\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Drill into the responsible stack and confirm with LoAF\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F#step-by-step-resolution\" }\n  ]\n}\n",[897,902,903],{"type":899},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"Finding the Slowest Interaction in the Performance Panel\",\n  \"description\": \"Locate the worst INP interaction in a DevTools Performance recording: read the Interactions track, sort by latency, and attribute the slow bar to a handler.\",\n  \"datePublished\": \"2026-06-18\",\n  \"dateModified\": \"2026-06-18\",\n  \"mainEntityOfPage\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F\"\n}\n",[897,905,906],{"type":899},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    { \"@type\": \"ListItem\", \"position\": 1, \"name\": \"Home\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 2, \"name\": \"Core Web Vitals & Measurement\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 3, \"name\": \"Profiling Event Handlers for INP\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 4, \"name\": \"Finding the Slowest Interaction in the Performance Panel\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F\" }\n  ]\n}\n",[908,909,910],"style",{},"html pre.shiki code .sP5qI, html code.shiki .sP5qI{--shiki-default:#A0111F;--shiki-dark:#A0111F;--shiki-light:#A0111F}html pre.shiki code .sf6mN, html code.shiki .sf6mN{--shiki-default:#023B95;--shiki-dark:#023B95;--shiki-light:#023B95}html pre.shiki code .syybb, html code.shiki .syybb{--shiki-default:#0E1116;--shiki-dark:#0E1116;--shiki-light:#0E1116}html pre.shiki code .ssM3C, html code.shiki .ssM3C{--shiki-default:#622CBC;--shiki-dark:#622CBC;--shiki-light:#622CBC}html pre.shiki code .seIZK, html code.shiki .seIZK{--shiki-default:#702C00;--shiki-dark:#702C00;--shiki-light:#702C00}html pre.shiki code .sIIH1, html code.shiki .sIIH1{--shiki-default:#66707B;--shiki-dark:#66707B;--shiki-light:#66707B}html pre.shiki code .s-_DF, html code.shiki .s-_DF{--shiki-default:#032563;--shiki-dark:#032563;--shiki-light:#032563}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":332,"searchDepth":356,"depth":356,"links":912},[913,914,915,916,917],{"id":152,"depth":356,"text":153},{"id":210,"depth":356,"text":211},{"id":290,"depth":356,"text":291},{"id":734,"depth":356,"text":735},{"id":865,"depth":356,"text":866},"Locate the worst interaction in a DevTools session and attribute its latency to a handler.","md",{"slug":12,"type":921,"breadcrumb":922,"datePublished":931,"dateModified":931},"long_tail",[923,926,927,929],{"name":924,"url":925},"Home","\u002F",{"name":26,"url":25},{"name":928,"url":20},"Profiling Event Handlers for INP",{"name":5,"url":930},"\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002F","2026-06-18",true,"\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel",{"title":935,"description":936},"Find the Slowest Interaction in DevTools","Locate the worst INP interaction in a DevTools Performance recording: read the Interactions track, sort by latency, and attribute the slow bar to a handler.","core-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Ffinding-the-slowest-interaction-in-the-performance-panel\u002Findex","yOwrGJyhJxmkQKCEuIlYLvGxscVE61Yob-O_Xd8tmT4",[940,943],{"title":928,"path":941,"stem":942,"children":-1},"\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp","core-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Findex",{"title":944,"path":945,"stem":946,"children":-1},"Reducing Input Delay from Third-Party Tags","\u002Fcore-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Freducing-input-delay-from-third-party-tags","core-web-vitals-measurement\u002Fprofiling-event-handlers-for-inp\u002Freducing-input-delay-from-third-party-tags\u002Findex",1782237171385]