ARTICLE

INP Fixes for Hyvä: The JavaScript Patterns That Actually Move the Needle

INP Fixes for Hyvä: The JavaScript Patterns That Actually Move the Needle

Interaction to Next Paint (INP) replaced First Input Delay as a Core Web Vital in March 2024, and it has quietly become the most underrated performance metric on eCommerce sites. The reason: INP measures how responsive a page feels when a customer actually interacts with it, not just how fast it loaded the first time. A site that loads in 1.5 seconds and then takes 400 milliseconds to respond to every tap feels slow, conversion suffers, and the customer cannot tell you why.

Hyvä-themed Adobe Commerce stores have a structural advantage on INP compared to Luma because Alpine.js is dramatically lighter than KnockoutJS. But the advantage only translates into excellent INP scores when the implementation follows certain patterns. The same Hyvä codebase can produce INP scores in the 60-100ms range (excellent) or in the 300-500ms range (poor) depending on how the interactive components are built.

Bemeir’s Hyvä team has tuned INP on dozens of Adobe Commerce stores. The patterns that work are specific, the patterns that fail are also specific, and the difference is almost always in how the JavaScript handlers are structured rather than in how much code is shipped.

What INP actually measures

INP measures the latency between a user interaction (tap, click, key press) and the next paint of the page after the interaction has been processed. The metric reports the 75th percentile of all interactions during a page visit, which means a single slow interaction can dominate the score even if most interactions are fast.

The thresholds defined by Google’s Core Web Vitals documentation are:

  • **Good:** under 200 milliseconds
  • **Needs improvement:** 200 to 500 milliseconds
  • **Poor:** over 500 milliseconds

Critically, INP includes the full processing time of the interaction: event handler execution, layout recalculation, style updates, paint, and any synchronous work the handler kicks off. A handler that calls a slow function blocks the next paint and degrades INP, even if the handler itself looks small.

For eCommerce stores, INP is most visible on three interaction types: tapping into a search input, opening a mini-cart or hamburger menu, and adding a product to cart. These three interactions dominate the customer’s perception of “is this site responsive.”

The Hyvä baseline and why it matters

A vanilla Hyvä installation ships approximately 25KB of JavaScript: Alpine.js plus the Hyvä-specific components. This baseline matters because every additional script the merchant adds eats into the INP budget. The starting point is excellent; the customizations are where the score either holds or degrades.

In our experience tuning Hyvä INP, the baseline Hyvä storefront with no customizations typically produces INP scores in the 60-120ms range on mid-tier mobile devices. After typical merchant customizations (analytics, chat widgets, personalization, custom interactive components), INP can drift to 250-400ms if the customizations are added without discipline. The work of INP tuning on Hyvä is mostly disciplining the additions, not optimizing Hyvä itself.

The most common INP killers on Hyvä

Five patterns consistently degrade INP on Hyvä-themed Adobe Commerce stores. Each one is fixable.

1. Synchronous third-party script execution on interaction

The most common pattern: an analytics or marketing script attaches a synchronous handler to add-to-cart, click events on product cards, or search submissions. The handler does meaningful work (fires events, builds payloads, sends network requests synchronously) before returning. The next paint waits.

The fix: schedule the third-party work asynchronously after the immediate UI response. Use `requestIdleCallback` for non-urgent work, or `setTimeout(handler, 0)` to push the work to a later tick of the event loop. The UI updates first, the analytics fire after.

2. Heavy Alpine.js component initialization

Some custom Alpine components do significant work in their initialization: fetching data, parsing JSON, building lookup tables. When a customer first interacts with the component, the initialization runs synchronously and blocks INP.

The fix: lazy-initialize. Use Alpine’s `x-init` to schedule the heavy work asynchronously, or split the component into a lightweight initial state and a deferred enrichment that runs after the first paint. The component appears responsive immediately and gains its full functionality after.

3. Unbatched DOM updates in interaction handlers

A handler that updates several DOM elements without batching forces multiple layout recalculations. Each recalculation blocks paint until complete.

The fix: batch DOM reads and writes. Read all the values you need first, then write all the updates. Alpine handles most of this for you when you update its reactive state, but custom handlers that touch the DOM directly need to follow the pattern manually.

4. Large layout shifts triggered by interaction

When a customer opens a mini-cart, expands a navigation menu, or filters a product list, the layout changes. If the new content causes other elements to reflow, the browser has to recalculate layout for the entire page. On large pages with complex layouts, this recalculation is the largest single contributor to slow INP.

The fix: use CSS containment (`contain: layout`) on the changing elements, reserve space with `min-height` for content that will appear, and prefer `transform` and `opacity` for animations over properties that trigger layout. Hyvä’s Tailwind setup makes this straightforward; the discipline is using the right utility classes consistently.

5. Long tasks during page load that overlap with first interaction

If the page loads, the customer immediately interacts with a button, and a long task (over 50ms) is still running from the page load, the interaction is queued behind the long task. INP suffers even though the handler itself is fast.

The fix: break up long-running scripts using `scheduler.yield()` (where supported), `setTimeout` chunking, or web workers for genuinely heavy work. The Chrome long task documentation describes the patterns for identifying and fixing these.

A side-by-side: typical INP scores by site profile

The pattern across the Hyvä sites we have tuned:

Site profile Typical INP before tuning Typical INP after tuning
Vanilla Hyvä storefront 80-140ms 60-100ms
Hyvä + 3 marketing scripts 180-280ms 90-140ms
Hyvä + 5 marketing scripts + chat widget 280-400ms 120-180ms
Hyvä + heavy personalization 350-500ms 150-220ms
Hyvä + 10+ marketing scripts (uncontrolled) 450-700ms 200-300ms

The tuning typically reduces INP by 40-60% across the board. The largest wins come from controlling the marketing script footprint; merchants who add scripts disciplined never reach the high-end ranges.

The diagnostic process that finds the actual problems

INP problems are best diagnosed with field data, not synthetic tests. The Chrome User Experience Report and the Real User Monitoring tools that consume it (PageSpeed Insights field data, SpeedCurve, Cloudflare Web Analytics, DebugBear) all expose real-user INP measurements that can be filtered by page type, device class, and geography.

The diagnostic sequence we use:

First, identify the slowest pages by 75th percentile INP from field data. Usually two or three page types account for most of the bad scores.

Second, on each slow page, identify the slowest interactions. The browser’s Performance panel in DevTools can record specific interactions and show exactly which scripts ran during the handler.

Third, attribute the slow time to specific code: was it Alpine component logic, was it a third-party script, was it layout recalculation, was it the original handler logic?

Fourth, apply the appropriate fix from the patterns above and re-measure.

For most Hyvä stores, this diagnostic process surfaces two to four specific fixes that, applied together, move the INP score from “needs improvement” to “good.”

The patterns that hold up under load

Some INP fixes work in lab tests and degrade in production. The patterns that hold up consistently under real traffic:

Defer all non-essential JavaScript to after first interaction. Use the `loading=”lazy”` pattern for components that aren’t immediately visible, and the `requestIdleCallback` pattern for work that doesn’t need to happen synchronously.

Use `data-` attributes for state that doesn’t need reactive updates. Alpine reactive state is fast, but for state that only needs to be read occasionally, plain attribute lookups are faster than reactive bindings.

Cache computed values in Alpine components. A component that recomputes the same value on every render burns INP budget. Compute once, cache in component state, invalidate when dependencies change.

Throttle high-frequency events. Scroll handlers, resize handlers, and input handlers can fire dozens of times per interaction. Use `requestAnimationFrame` throttling for visual updates and debouncing for network-triggering work.

Audit third-party scripts quarterly. New marketing tools get added; old ones rarely get removed. A quarterly audit that asks “is this script still earning its INP cost?” catches the slow drift that degrades scores over time.

What this looks like as an engagement

INP tuning on a Hyvä-themed Adobe Commerce store is typically a 2-4 week engagement. The work breaks down approximately as: 3-5 days of field data analysis and slow-page identification, 5-10 days of diagnostic profiling and root-cause analysis on the slowest interactions, 3-5 days of fixes and code changes, and 2-3 days of validation against new field data.

The expected outcome is INP scores in the green band (under 200ms at 75th percentile) on the highest-traffic pages, with a documented set of patterns the in-house team can apply to future development to keep INP from regressing.

Bemeir’s Hyvä team runs INP tuning as a standalone engagement when the rest of the site is otherwise performing well but INP scores are dragging Core Web Vitals into the yellow or red bands. The work pays for itself in conversion lift; even small INP improvements on mobile checkout flows consistently produce measurable conversion gains.

The metric that earns its keep

Of all the performance metrics eCommerce sites track, INP correlates most directly with how customers perceive the site as “fast” or “slow.” LCP measures how long they wait to see content; CLS measures whether the page feels stable; INP measures whether the page responds when they try to do something. For sites where customers actually interact (which is every commerce site), INP is the metric that determines whether the rest of the experience feels worth using.

Hyvä gives Adobe Commerce stores the best starting point in the industry for INP. The patterns above are how merchants keep that starting point as the site grows in complexity. The discipline pays off in scores that stay green even as the marketing team adds tools, the personalization team adds rules, and the product team adds features. INP is not a one-time fix; it is an ongoing discipline. The teams that treat it that way ship sites that feel fast for years.

Let us help you get started on a project with INP Fixes for Hyvä: The JavaScript Patterns That Actually Move the Needle and leverage our partnership to your fullest advantage. Fill out the contact form below to get started.

more articles about ecommerce

Read on the latest with Shopify, Magento, eCommerce topics and more.