Shopify JavaScript and third-party scripts: fixing INP
INP is almost always somebody else's JavaScript. Here is how to find whose, and what to do about it.
7 min read · Performance ·
INP measures how fast a page responds when someone taps it. On a Shopify store the answer is almost always determined by JavaScript you didn't write — app scripts, analytics, chat, reviews, personalisation — all competing for a single main thread.
Find out whose
Before changing anything, measure what's actually there.
- DevTools → Network, filter to JS, load a product page on a throttled mobile profile.
- Sort by size and by time. Third-party domains you don't recognise are apps.
- DevTools → Performance, record a load, look at the main thread. Long tasks are the ones blocking interaction.
- Coverage tab shows how much of each file is actually used. App scripts are frequently 90% unused on any given page.
You now have a list of who costs what. That list is the whole audit.
The switch-off test
The most reliable method, and worth the tedium. On a copy of the theme, not live:
- Measure the baseline.
- Disable one app.
- Measure again.
- Repeat.
Slow, and it gives you exact numbers per app rather than guesses. Do it for the ten apps you're least sure about — how many apps is too many.
Leftovers from uninstalled apps
Shopify tries to clean up, but apps that wrote directly into the theme leave remnants. Stores routinely load scripts from apps removed two years earlier.
Check theme.liquid and your section files for blocks of code you don't recognise, and check the script tags in the rendered page against your installed app list. Anything unaccounted for is dead weight.
Back up the theme before removing anything.
Loading strategy
For scripts you're keeping:
defereverything that isn't needed for first paint. That's nearly everything.- Load on interaction where possible. A chat widget's JavaScript can wait until someone clicks the bubble; a search modal's until someone opens search. This is the single biggest INP win available on most stores.
- Load below-the-fold widgets on scroll, with an IntersectionObserver.
- Never
document.write. - Self-host what you can. Every extra domain is a DNS lookup, a connection and a handshake.
Your own JavaScript
Themes accumulate their own problems:
- No framework for a carousel. Native scroll-snap does it in CSS.
- Use native elements.
<details>for accordions,<dialog>for modals. Less code, better accessibility. - Bound scroll and resize handlers. Throttle them, and never do layout reads and writes in the same handler.
- Split by template. The product page shouldn't download the cart drawer's code on a blog article.
Modern base themes like Dawn ship very little JavaScript, which is a real part of the case for starting from one.
Checkout is different
In checkout you don't inject script tags — analytics and marketing tags load through the sandboxed Web Pixels API, which is both the supported route and a performance improvement, since they can't block the checkout itself. Covered in checkout extensibility.
If you still have raw scripts in checkout, that's a migration you're overdue.
The honest trade-off
Every script is a business decision, not a technical one. A chat widget that adds 400ms to every page for a feature 2% of visitors use is a bad trade. A reviews widget that adds 200ms and lifts conversion is a good one.
Get the numbers, then have the conversation with whoever owns the decision. "It's slow" is not an argument; "this widget costs 0.4 seconds on every page for a feature 2% of people touch" is.
What to remove first
In order of how often it turns something up:
- Apps installed and never used.
- Leftover scripts from uninstalled apps.
- Duplicate analytics — two tag managers, or the same pixel twice.
- Chat widgets loading on every page.
- Anything doing personalisation above the fold.
INP is a queue for the main thread. Every script you defer, load on interaction, or remove entirely moves your customers up that queue.
Is this the problem you’re looking at?
Send me the link to your store and a line about what is going wrong. You get a straight answer within one business day — no pitch, no obligation.
mario@clicksandcarts.coOr see what I do around Shopify: services, work beyond the theme, selected work.