This post is for the developer or technical marketer who owns a hospital website and has seen "INP needs improvement" in Search Console or PageSpeed Insights without a clear next step. Interaction to Next Paint is the Core Web Vitals metric that measures how quickly a page responds when someone taps, clicks or types. On a hospital site the interactions that matter are not abstract: a doctor-search filter, a mega-menu, a date picker, a "book appointment" widget, a city selector.
It answers one question: how do you find out which interaction is slow, in which component, and for which group of visitors? Lab tools such as Lighthouse do not measure INP, because they do not tap anything. The answer comes from field data, a little instrumentation and the Long Animation Frames API. The general speed advice already covered in our healthcare website speed and Core Web Vitals guide is the starting point; this article goes narrower, into diagnosing interactions on the components hospitals actually build.
It assumes you can read JavaScript and deploy a small script. The clinical content of the site is out of scope; the focus is the front end.
What INP measures, and why hospital pages are exposed
INP observes the interactions during a visit and reports a value close to the slowest one. According to web.dev's INP documentation, an INP at or below 200 milliseconds is good, above 500 milliseconds is poor, and the page is assessed at the 75th percentile of page loads, separately for mobile and desktop. Each interaction has three phases:
- Input delay: the wait before event handlers can start, usually because the main thread is busy.
- Processing duration: the time the event handlers themselves take.
- Presentation delay: the time from the end of the handlers until the next frame is painted.
These phases point to different fixes, so a single INP number is not enough. A filter that spends its time in processing needs less work in the handler. A filter that spends its time in presentation delay usually has too much DOM to update. A menu with a long input delay is waiting behind something else, often a third-party script.
Hospital sites are exposed for structural reasons. They tend to have large templates with many departments in the navigation, heavy listing pages (hundreds of doctors on one page), tag managers carrying several marketing pixels, chat widgets, and booking or telehealth scripts loaded from other vendors. Each adds main-thread work that competes with the visitor's tap. A large DOM also matters: web.dev notes that larger DOMs require more work to render, which slows the frame after an interaction.
Step 1: Get field data before touching code
Start with what real Chrome users experienced. Two sources are free.
Search Console and PageSpeed Insights show Core Web Vitals grouped by URL pattern. Use them to find which templates fail: doctor listing, department page, home, booking. If a template group is not listed, there is not enough data for it.
The CrUX API lets you query by page or by origin. The Chrome UX Report API documentation describes a single records:queryRecord endpoint that accepts either a url or an origin, an optional formFactor of DESKTOP, PHONE or TABLET, and a list of metrics that includes interaction_to_next_paint. The response returns a histogram and a p75 value over a 28-day rolling period. Note the eligibility rules in the CrUX methodology: a page must be publicly discoverable and have enough samples, so low-traffic department pages often have origin-level data only.
If you want a sample across several hospital sites, for a benchmark of your own or a prospect audit, the method is simple. Build a list of origins, query each with formFactor set to PHONE, record the p75 and the three histogram bins, and note which origins return no record. Report the sample size and the date, and treat the no-data group as a finding in itself. Do not generalise a small sample to "hospitals in India"; say how many sites, which month and how they were chosen.
The outcome of this step is a short list: which template, which device class, how far above 200 milliseconds. Everything after this step is about finding the cause.
Step 2: Instrument real interactions with attribution
CrUX tells you a page is slow; it does not tell you which element. For that, collect your own field data using the web-vitals library attribution build. Import onINP from web-vitals/attribution, and the callback receives an attribution object with these fields:
interactionTarget: a selector for the element the visitor first interacted withinteractionType:pointerorkeyboardinputDelay,processingDurationandpresentationDelay: the three phases, in millisecondslongAnimationFrameEntries: long animation frame entries that overlap the interaction (empty where the browser does not support the API)
Send a compact beacon when the page is hidden. web.dev's field measurement guidance recommends sendBeacon() and sending on visibilitychange when the page becomes hidden, because unload is unreliable on mobile.
A workable event schema for the beacon, with names you can adapt:
| Field | Source | Why it matters |
|---|---|---|
metric_value | metric.value | The INP for this page view |
target | attribution.interactionTarget | Which control was involved |
type | attribution.interactionType | Touch/click versus keyboard |
input_delay, processing, presentation | the three attribution timings | Which phase dominates |
template | your own page-type label | Group by listing, department, booking |
device_class | viewport or navigator.deviceMemory bucket, if available | Separates budget phones |
loaf_top_script | the biggest script in the long animation frame (see step 3) | Points at the culprit file |
Do not send patient data. The beacon should carry selectors, timings and a template label only. Do not include form values, query strings that might hold names or phone numbers, or full URLs for booking confirmation pages. If the interactionTarget selector might embed text, use the library's generateTarget option to return a safe identifier instead. This keeps the instrumentation outside any personal-data conversation, although the privacy and consent position of your analytics setup remains a decision for the provider's compliance team.




