Shopify INP fix: stay under 200 ms with checkout UI extensions

What Interaction to Next Paint measures on a Shopify checkout, why script-injecting upsell apps push it past 200 ms, and how native extensions fix it.

Published Feb 6, 2026· Updated Sep 6, 2026· 7 min read· By the Cart X team

Interaction to Next Paint (INP) measures how quickly a page visually responds after a shopper taps or clicks. Google made it a Core Web Vital in March 2024, replacing First Input Delay, and the threshold is unforgiving: 200 ms or less is “good”, 200 to 500 ms “needs improvement”, and above 500 ms “poor” (web.dev).

On a Shopify store, the storefront theme is usually where INP problems start, but checkout is where they cost the most. A shopper who taps “Pay now” and sees nothing happen for half a second will tap again, hesitate, or leave. This article explains what INP measures, why apps built on the old checkout model made it worse, and how Shopify’s Checkout Extensibility architecture fixes the root cause.

What INP actually measures

INP looks at every interaction during a page visit (clicks, taps, key presses) and reports roughly the slowest one, measured from the input event until the browser paints the next frame. It is a field metric: Google’s Chrome User Experience Report collects it from real Chrome users and reports the 75th percentile per origin.

Three things add up to a single interaction’s latency:

  1. Input delay. The main thread is busy (running someone else’s script) so the browser cannot even start handling the tap.
  2. Processing time. The event handlers themselves.
  3. Presentation delay. Layout, style and paint of the resulting change.

The first component is the one third-party code inflates. If an injected script is parsing, rendering an iframe, or polling the DOM when the shopper taps, the tap waits.

Typical checkout interactions INP catches: selecting a shipping method, applying a discount code, toggling a checkbox, tapping “Pay now”, and accepting or declining a post purchase offer.

Why INP matters for a checkout

Two reasons, one of which is often overstated.

Conversion. This is the real one. A checkout that hesitates on tap reads as broken. Shoppers on mid-range Android devices over mobile networks, which is where much of Shopify traffic comes from, feel this most, because the main thread is slower to begin with.

Search. Core Web Vitals feed Google’s page experience signals, and CrUX aggregates INP at the origin level, so slow interactions on yourstore.com/checkouts/... count against yourstore.com even though checkout pages themselves are not indexed. It is a minor ranking factor compared to content and links, so treat it as a tiebreaker, not a penalty to panic about.

Shopify surfaces real-user LCP, CLS and INP for your store in the Web performance report in admin, and Google’s PageSpeed Insights shows CrUX data for the origin.

How legacy checkout apps inflated INP

Before Checkout Extensibility, an upsell or tracking app had three ways into checkout, and all three ran on the main thread:

Legacy method What it did INP impact
Script tags Loaded external JavaScript into the storefront and order status page with full DOM access High: arbitrary work competing with the shopper’s taps
iframes and post-payment redirects Loaded a whole separate page inside or instead of checkout High: a second page load, layout thrash, and often a payment re-entry
checkout.liquid customizations (Plus) Custom markup and scripts in the checkout template Medium to high, depending on what was added

None of this was malicious. It was the only way to build an upsell at the time. But every additional app stacked more work onto the same thread, and the merchant had no way to see the cumulative effect until the Web performance report turned red.

Shopify retired all three mechanisms: checkout.liquid on the checkout steps in August 2024, and checkout.liquid, script tags and additional scripts on the thank you and order status pages in August 2025. The migration guide covers the details.

How checkout UI extensions fix the root cause

A checkout UI extension does not run on the checkout page’s main thread. Shopify executes the extension’s JavaScript in a separate web worker and gives it no DOM access. The extension describes UI with Shopify’s components; Shopify’s own renderer draws them. The same model applies to post-purchase extensions.

Consequences for INP:

  • No input delay from app code. The worker cannot block the main thread. If an extension does heavy work, the shopper’s tap still gets handled immediately.
  • No iframes, no redirects. A post-purchase offer renders as part of Shopify’s checkout, on Shopify’s domain, using the stored payment method. Accepting is one tap and one network call.
  • No layout shifts from injected markup. Components render into targets Shopify defines, sized by Shopify’s layout.
  • No cumulative stacking. Multiple extensions each run in isolation rather than competing in the same script context.
  • Shopify owns the performance budget. Shopify can optimize the renderer for every store at once, and extensions inherit the improvement.

This is why “fixing INP” on a Shopify checkout is less about tuning code and more about which apps are installed.

A step-by-step INP fix for Shopify checkout

Step 1: Measure

  • Open the Web performance report in Shopify admin and note INP for the last 28 days.
  • Run your homepage and a product URL through PageSpeed Insights and read the “Discover what your real users are experiencing” section, which is CrUX origin data. Lab tests (Lighthouse) do not report INP reliably; use field data.
  • If INP is above 200 ms at the 75th percentile, continue.

Step 2: Separate storefront from checkout

Most origin-level INP comes from the theme: sliders, mega menus, review widgets, and apps that add storefront scripts. Use Chrome DevTools’ Performance panel with the “Interactions” track on your product page to see which script owns the longest task. Fix or remove those first; they affect every visit, not just purchases.

Step 3: Audit checkout apps

Go to Settings > Checkout > Customize. Apps built on Checkout Extensibility appear as app blocks or as the post-purchase app. Then compare with Settings > Apps and sales channels: any checkout-related app that is not in the editor is either broken since August 2025 or working around the platform. Uninstall it.

Step 4: Replace with native extensions

For each function you lose (post-purchase offers, thank you page offers, surveys, tracking), install an app that ships it as a checkout UI extension, post-purchase extension or web pixel. Recreate the configuration, test with a live order, then remove the old app.

Step 5: Re-measure after 28 days

CrUX is a rolling 28-day window, so the score lags the fix. Check the Web performance report a month later.

Where Cart X fits

Cart X runs its checkout surfaces as native extensions: the one-click post purchase upsell is a post-purchase extension, and thank you page and order status page offers are checkout UI extensions. Neither adds a script to the checkout page.

The in-cart popup lives on the storefront, not in checkout, so it is delivered as a theme app extension rather than a script tag. That is Shopify’s supported mechanism for storefront app code: it is versioned with the app, removed cleanly on uninstall, and does not rely on editing your theme. Any storefront code is main-thread code, so the popup is kept small and loads only when a shopper adds a matching product to the cart.

Nothing about a native architecture forces you to give up AOV. The offers are the same; the delivery mechanism is what changed. If anything, an offer that renders inside Shopify’s checkout, in the store’s checkout styling, with a clear “Pay now” and “Decline offer”, converts more consistently than a third-party popup that some browsers never showed. Details on the placement trade-offs are in pre-purchase vs post-purchase upsell.

Frequently asked questions

What INP score counts as passing?

200 ms or less at the 75th percentile of real user visits is “good”; above 500 ms is “poor” (web.dev). Between the two is “needs improvement.”

Where do I find my store’s real INP data?

The Web performance report in Shopify admin, or PageSpeed Insights for the origin. Both use field data. Lighthouse lab runs do not measure INP.

Will removing legacy upsell apps lower my average order value?

Not if you replace them with native equivalents. A post-purchase extension shows the same offer, renders more reliably (no ad-blocker losses), and does not slow the tap that completes the original sale.

Is checkout extensibility Plus-only?

No. Post-purchase and thank you / order status page extensions are available on every Shopify plan. Only extensions on the information, shipping and payment steps require Plus. See checkout UI extensions vs legacy apps.

Does an extension-based app add any script to my checkout?

No. Extension bundles are loaded and executed by Shopify inside a worker; the checkout page’s own script budget is unchanged.

Try it on your store

Cart X delivers post-purchase, thank you page and in-cart offers on Shopify’s native extension architecture, with targeting rules, A/B testing and analytics built in. Install it from the Shopify App Store; every feature is free up to 100 orders a month, and paid plans charge a flat fee with no commission.

#inp#core web vitals#checkout ui extensions#checkout extensibility#performance