Third-Party Scripts and Interaction Delay: A Budget Before the Next Widget
Every chat pane, tag, and embed is a yes or a no before the first click. Inventory them, decide what may run before the first interaction, and use the Interaction to Next Paint article for the parts of a slow tap. Do not guess a vendor’s milliseconds.

Someone wants a chat bubble on the homepage by Friday. The vendor page shows a snippet. The snippet goes into the head because that is where the install note says to put it. Next month the field report says the page feels late when people tap. Nobody can name the tag that was allowed to run first.
The scoreboard for Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS) is the Core Web Vitals delivery guide. This page is the budget for INP only: what may run before the first click, tap, or keypress. Security review of the same paste lives in the marketing-site security guide. Read both. A tag can be safe enough to trust and still be too early to run.
What Interaction to Next Paint is timing
Sourced from Interaction to Next Paint (INP) (web.dev, Jeremy Wagner and Barry Pollard, last updated 2025-09-02 UTC, checked 28 September 2026). INP assesses responsiveness from the Event Timing API. It observes the latency of interactions and reports a value that all, or nearly all, of them were under. A low INP means the page could respond quickly to the vast majority of interactions.
The article’s scope is specific. INP watches clicks, taps, and key presses for the whole visit. It does not watch hover, zoom, or scroll, except where those gestures include a click, tap, or key. The intent is not to time every later effect of a tap, such as a network fetch that finishes afterward. It times how long the next paint is blocked. Visitors read a delayed frame as a page that did not hear them.
For most sites, the slowest interaction is the one that gets reported. On pages with a lot of interactions, web.dev says one highest interaction is ignored for every 50 interactions, because a single hiccup would otherwise dominate. The 75th percentile of page views is what you still judge in the field, split by mobile and desktop. A good INP is 200 milliseconds or less. Above 200 and at or below 500 needs improvement. Above 500 is poor. Those bands are the article’s, not a guess about your chat vendor.
INP replaced First Input Delay (FID). FID only measured the input delay of the first interaction. INP watches interactions across the visit: input delay, the time to run event handlers, and the wait until the next frame is painted. A page can feel fine on the first tap and still fail INP on a later one. The budget has to cover the whole visit, not the hero animation.
The three parts of a slow interaction
web.dev splits an interaction into three stretches. Use these names in the ticket so you are not blaming “the widget” as a mood.
- Input delay: Time before any callback for that interaction runs. The article says this can be caused by long tasks on the main thread. If a script is still busy when the visitor taps, the tap waits.
- Processing duration: Time for the event handler callbacks that belong to that interaction to run. The longest event in the group is what feeds the interaction’s latency. A heavy click handler lives here.
- Presentation delay: Time after those callbacks finish until the next frame is on screen. The interaction is not done when the function returns. It is done when the visitor can see that something happened.
The article’s picture of a poor tap is an accordion blocked by long tasks. The visitor clicks again because nothing moved. When the main thread catches up, the delayed clicks open and close the accordion out of order. The responsive version paints the open state immediately. That is the failure mode you are budgeting against. Not a leaderboard of vendors.
JavaScript is often the primary driver of interactivity, the article says. Browsers also ship controls that are not JavaScript: checkboxes, radio buttons, and controls powered by CSS. A third-party snippet is usually JavaScript you did not write, running on that same main thread, or an iframe the visitor can click. The article does not publish a millisecond price for any vendor. Neither will this page. If a salesperson quotes you a cost for their tag, treat it as their claim until you measure your page.
Inventory every tag before you add one
Framework. Do this on the templates people actually use: homepage, offer page, article, contact. A tag that only loads on the article template can still be your INP problem on that template. An origin-level field score will not tell you which one. web.dev says the Chrome User Experience Report (CrUX) can tell you there is a problem and cannot tell you the cause. Your own real-user monitoring can attribute INP to a specific interaction, whether it happened during or after load, and whether it was a click, a keypress, or a tap. Until you have that, the inventory is the only honest list.
- Name: What the snippet is, in your words. “Chat”, “video embed”, “tag manager”, “font loader”, “your menu”. The vendor’s product name is fine. A millisecond claim is not.
- Owner: A person who can remove it. Marketing, engineering, or legal. If nobody can remove it, it does not go on the page.
- Template: Which layouts load it. Global head tags are the expensive default. A form page does not need the homepage’s promo embed.
- Before first interaction: Yes or no. Yes means it is allowed to run before the visitor clicks, taps, or presses a key. No means it waits. “The install doc said head” is not a yes.
- Iframe or not: Write this down. A click inside an iframe counts toward the top-level page’s INP. Your script may not see that click.
flowchart TD
Tag["A tag on the template"] --> Need{"Required before the first click, tap, or keypress?"}
Need -->|Yes| Keep["On the before-interaction list, with an owner"]
Need -->|No| Wait["Not allowed to run before the first interaction"]
The diagram is the decision, not a performance trace. You still have to look at the three stretches when a real interaction is slow. Input delay points you at work that was already on the main thread, including long tasks. Processing duration points you at the handler for that gesture. Presentation delay points you at the wait for the next frame. A widget can sit in any of those. The diagram only stops you from adding the next one by default.
What may run before the first interaction
Framework. Start from an empty yes list. Add a tag only when the page is false without it, and when you can name the owner. Typical arguments that earn a yes, and the arguments that do not:
- Your own interface: The menu, the form, the primary button. These are the interactions INP will record. They belong in your code, where you can see the handler. A form you operate yourself is a different object from a pasted form embed. The build notes for forms on this stack live with the dynamic forms guide.
- Measurement you will read: A tag that records a lead is allowed only if someone uses the report. How events and lead quality are defined is the measurement plan. This page does not pick the event names. It asks whether that collector must run before the first tap. Often it does not.
- A legal or consent control: If you must show a choice before other tags run, that control is on the yes list. The tags behind it are not, until the choice says so.
- Chat, heatmaps, social pixels, promo embeds: Default no. They can load after the first interaction, or only on the template where someone proved they are used. A global chat bubble is the usual way a quiet article template inherits a homepage problem.
Event names and what counts as a qualified lead belong in the measurement plan. Owning the form endpoint, instead of pasting a third-party form, is the dynamic forms guide. Use those when the question is “what did we record?” or “where does the submission go?” Stay here when the question is “may this run before they tap?”
Iframes still count
web.dev is direct. Interactions happen in the main document or in iframes. The example is clicking play on an embedded video. End users do not know which pixels are an iframe. INP on the top-level page includes those interactions. JavaScript Web APIs do not get the contents of the iframe, so your own collector can miss a slow play tap that CrUX includes. The article tells you to consider subframe timings if you want a complete INP, and it notes that some cross-origin frames cannot be measured from the parent.
Framework applied to that rule. A chat widget, a calendar, a map, or a video that lives in an iframe is not off the page for INP. Put it on the inventory. Mark it as an iframe. Do not assume your analytics script saw the slow click. If you cannot justify the embed on that template, remove it. Do not print a millisecond cost for the vendor. Measure your own origin if you need a number.
Field first, then a lab pass that actually taps
The INP article says the best measurement is field data from real users. Start there. CrUX, when your site has enough Chrome data, can give you an origin view and sometimes a URL view, through PageSpeed Insights and the other Core Web Vitals tools. It still will not name the widget. Real-user monitoring is how you attach the number to an interaction.
Lab is for reproducing a slow interaction you already suspect. The value you get depends on which interactions you perform. User behavior varies, so a scripted lab pass can miss the tap real people make. Some lab tools never interact, so they never report INP. Total Blocking Time (TBT) can stand in as a proxy in that gap. It is not INP. When you do use the lab, the article’s strategy is to follow common flows and to interact while the page is loading, because the main thread is often busiest then. A test that waits until the page is idle will miss the moment your early tags collide with the first tap.
A page can also have no INP. The visitor never clicked, tapped, or pressed a key. Or they only scrolled and hovered. Or a bot loaded the URL and did not interact. Empty is not green. Say “no interactions recorded” and move on.
Hypothetical: the chat snippet in the head
Hypothetical, labeled as such. A founder asks for chat on every page. The install note says to paste a script in the head. Nobody writes an owner. The before-interaction column is blank, which in practice means yes. A month later the mobile field report for INP is outside the good line. CrUX does not name a tag. The lab test was a load-only run, so it reported no INP and someone quoted Total Blocking Time as if it were the field number.
The fix this framework allows: put the chat on the inventory, owner named, iframe marked if that is how it mounts, before-interaction set to no. Load it after the first interaction, or only on the contact template. Reproduce by tapping during load, which is the lab strategy the article actually gives. Do not publish a millisecond you did not measure on your own origin. Do not remove the analytics tag in the same swing unless it is also on the yes list without a reason. One change, then wait for field data.
Keep the list alive
Tags accumulate. The inventory belongs on the maintenance blueprint as a recurring check: new snippets since last month, each with an owner and a yes or no. A tag that lost its owner gets removed. That is the whole governance.
What this budget does not prove: that a yes-list will put you at 200 milliseconds or less. Device mix, your own handlers, and presentation work can still miss the line. The article also says INP is calculated when the visitor leaves the page, with extra rules for long-lived tabs and for pages restored from the back/forward cache. Your collector has to follow that, or you will argue with CrUX for a measurement reason, not a widget reason. The web-vitals library is what web.dev points at for those cases.
If the head of the site is a junk drawer of snippets, clean it up as part of the website, not as a Friday paste. Start a conversation with the inventory, not with a vendor’s speed claim.
Frequently asked questions
Which interactions does Interaction to Next Paint count?
Sourced from the web.dev Interaction to Next Paint (INP) article, checked 28 September 2026. INP observes clicks with a mouse, taps on a touchscreen, and key presses on a physical or onscreen keyboard. Hovering, zooming, and scrolling are not observed, unless the gesture also includes a click, tap, or key press. If a visitor only scrolls, the page can report no INP value. That silence is not a good score.
Can a click inside an embedded video or chat pane affect the page?
Yes for the class of interaction the article describes. Interaction to Next Paint (INP) includes interactions in iframes embedded in the page. The example web.dev gives is clicking play on an embedded video. Visitors do not know what sits in an iframe. A chat pane that is an iframe is the same kind of click from the visitor’s side. JavaScript on the parent page may not be able to see inside that frame, which web.dev says can show up as a difference between the Chrome User Experience Report (CrUX) and your own real-user monitoring. That is not a millisecond cost for any chat product.
Is Total Blocking Time a substitute for Interaction to Next Paint?
No. The Interaction to Next Paint (INP) article says some lab tools never report INP because they only watch the page load and never interact. In those cases Total Blocking Time (TBT) may be a reasonable proxy, and it is not a substitute for INP. The field number is still INP at the 75th percentile, mobile and desktop separately. A good INP is 200 milliseconds or less. Above 200 milliseconds and at or below 500 milliseconds needs improvement. Above 500 milliseconds is poor.
Why can our script and the Chrome User Experience Report disagree?
web.dev’s vitals article says Core Web Vitals measured in JavaScript with public APIs may differ from the Core Web Vitals reported by the Chrome User Experience Report (CrUX). The Interaction to Next Paint (INP) article adds one concrete limit: the metric includes interactions inside iframes, and JavaScript Web APIs do not have access to the contents of those frames. That can show up as a difference between CrUX and real-user monitoring. Other differences are described on web.dev’s CrUX and real-user monitoring page. Read that page before you name one.
Should every tag wait until after the first click?
Framework. No. Some tags have to run early because the page is wrong without them. Analytics you actually use, a consent choice you are required to show, and your own menu are candidates you must justify. Everything else waits, or it stays off that template. The Chrome User Experience Report (CrUX) can tell you Interaction to Next Paint (INP) is poor. web.dev says CrUX cannot tell you the cause. The inventory is how you stop guessing which widget it was.