Skip to main content
NewNMC’s advertising guidelines for doctors are in force from 6 Oct 2026. See what to change, and get a free compliance auditNew NMC advertising rules for doctors: what to change
Website

INP on Hospital Websites: Finding Slow Interactions in Booking Forms and Filters

Lighthouse cannot measure INP. This guide shows how to use field data, web-vitals attribution and long animation frames to find which hospital-site interactions are slow and why.

INP on Hospital Websites: Finding Slow Interactions in Booking Forms and Filters

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:

  1. Input delay: the wait before event handlers can start, usually because the main thread is busy.
  2. Processing duration: the time the event handlers themselves take.
  3. 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 with
  • interactionType: pointer or keyboard
  • inputDelay, processingDuration and presentationDelay: the three phases, in milliseconds
  • longAnimationFrameEntries: 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:

FieldSourceWhy it matters
metric_valuemetric.valueThe INP for this page view
targetattribution.interactionTargetWhich control was involved
typeattribution.interactionTypeTouch/click versus keyboard
input_delay, processing, presentationthe three attribution timingsWhich phase dominates
templateyour own page-type labelGroup by listing, department, booking
device_classviewport or navigator.deviceMemory bucket, if availableSeparates budget phones
loaf_top_scriptthe 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.

Want this applied to your practice? Get a free website audit.

Book my free audit

Step 3: Read long animation frames

The Long Animation Frames API reports frames where a rendering update is delayed beyond 50 milliseconds. It is supported in Chrome from version 123 and not in Firefox or Safari, so treat it as Chrome-only evidence, which fits the fact that CrUX is also Chrome data.

Each entry has a scripts array. Each script entry carries sourceURL, sourceFunctionName, sourceCharPosition and invokerType, which says how the script was entered: event-listener, user-callback, resolve-promise, classic-script, module-script and others. The entry also carries blockingDuration, renderStart and styleAndLayoutStart.

Reading these together gives a decision rule:

  • Large inputDelay, and the script in the frame has an invokerType that is not your event listener. Something else was running when the visitor tapped. Look at the sourceURL. If it is a tag manager, chat widget or analytics bundle, you have found a third-party cost. Defer it, load it after interaction, or remove it.
  • Large processingDuration, and the script is your own event-listener. The handler is doing too much. Typical hospital causes: filtering a client-side array of 400 doctors and re-rendering all cards synchronously, validating a form on every keystroke, or running a search on each character.
  • Large presentationDelay, with a long gap between styleAndLayoutStart and renderStart, and small scripts. The browser is spending its time on style and layout, which usually means a large DOM or layout thrashing.

Always check the interactionTarget against the phase pattern. A menu that opens slowly because of input delay needs a different fix to a filter that opens slowly because of processing.

Step 4: Fix by component

The common components, with the phase usually responsible and a first remedy.

Doctor-search filters and listings

Processing and presentation delay dominate. The handler filters the full list and re-renders every card. Remedies from web.dev's INP optimisation guidance: do the minimum visible update first and defer other work until after the next frame; keep the DOM small; and consider content-visibility so offscreen cards are rendered lazily. Paginate or virtualise long lists. Filter on the server where the filter changes the result set materially, and return a smaller HTML fragment.

Mega-menus and mobile navigation

Input delay dominates when a menu waits behind scripts. Make sure the menu's JavaScript is not stuck behind a large hydration task. If the navigation contains every department and sub-service, render the closed state cheaply and mount the heavy panel on first interaction. Avoid reading layout values (such as element heights) right after writing styles, which web.dev describes as layout thrashing.

Booking widgets and date pickers

These are often third-party embeds or heavy libraries. Check sourceURL first. If the script belongs to a vendor, ask them for a lighter build, load the widget on user intent (the first tap on "Book") with a placeholder button that responds instantly, and measure again. For form-specific usability, see the existing piece on accessible clinic appointment forms, which covers labels, errors and the booking step; this article only addresses the speed of the controls.

Forms with validation and tracking

Validate on blur or submit instead of on every keystroke, and keep tracking calls out of the input handler. If tracking fires from the same click as the submit, send it with sendBeacon() or after the next paint, so the visible confirmation is not delayed. Where forms collect health information, the compliance questions are separate; see HIPAA-compliant website forms for the data handling side.

Step 5: Yield and verify

Where a handler must do real work, split it. web.dev notes that yielding indiscriminately is better than not yielding at all, and setTimeout is one method. Show the interaction result (the menu opening, the spinner, the filter chip) before the heavy part. After deploying a fix, do not trust one lab run. Compare the beacon distribution for the affected template before and after, over the same weekday mix, and wait for the CrUX 28-day window to roll over before declaring the Search Console status fixed. CrUX data lags by about two days and the window means old samples drop out slowly.

A diagnostic checklist

QuestionWhere to lookIf yes
Which template fails INP at p75?Search Console, CrUX APIPrioritise by traffic and enquiry value
Is it phones only?CrUX formFactorTest on a mid-range Android, not a developer laptop
Which element?interactionTarget in beaconsGroup by selector and template
Which phase dominates?inputDelay, processing, presentationPick the fix by phase
Is a third-party script in the frame?scripts[].sourceURLDefer, load on intent or remove
Is the DOM large?Count nodes on listing pagesPaginate, virtualise, content-visibility
Did the fix hold?Beacon distribution, then CrUX after 28 daysClose the ticket only then

The wider implementation work, including template performance and how it feeds into Core Web Vitals work, belongs to the website team; the point of this process is that it tells them exactly where to look. The Core Web Vitals glossary entry is useful for briefing non-technical stakeholders on the three metrics. If your site serves international patients on slower connections, the page-weight considerations in what international patients look for on a medical tourism site apply here too, since interaction speed is part of first impressions.

Filed underINP hospital websiteinteraction to next paint healthcarelong animation framesweb-vitals attributionhospital website speed

About the author

Co-Founder & CTO · Gurugram, India

Arush builds the systems the rest of the company runs on — the patient-acquisition pipelines, the AI chatbots, the analytics that tie a single click to a booked appointment. If a campaign reports a number, it's because something his team built is tracking it.

Free guide · 15 pages

WhatsApp AI Chatbot for Hospitals (14-Day Deploy)

The 14-day WhatsApp booking-bot implementation playbook.

The Pioneers Brief — one essay, three benchmarks, one teardown, every Thursday. Subscribe free →

Free website audit

Your next chapter starts with a conversation.

Three quick questions. We come prepared with a plan for your specialty and city.

  • A 30-minute call with a healthcare specialist
  • Your top three growth opportunities, in writing
  • Honest advice — even if that means not hiring us
  • No obligation and no hard sell
You’ll speak with a senior strategist
Consultations are hosted by Arush Thapar’s team.
Step 1 of 3Takes 30 seconds

What do you want to improve first?

Details stay privateNo obligationReply within 1 working day

Client portfolio · Healthcare websites

Work relevant to inp on hospital websites finding slow interactions in booking.

Explore client work →