Shopify third-party scripts: where each app loads from, what each costs, and what to remove first
App embeds, script tags and theme edits each load differently. How to list every app on the product page, price each one in milliseconds, and what to remove first.
11 min read
Contents — 5 sections
- Every app on the page arrived by one of three routes, and each route loads differently
- A synchronous script in the head is paid for before the first pixel paints
- Twenty minutes in DevTools names every app on the product page and prices it in milliseconds
- Remove in order of what each script costs, and the first three cost nothing to remove
- Fix it in this order, and it takes an afternoon
Every app on the page arrived by one of three routes, and each route loads differently
A third-party script is any JavaScript the browser fetches from an origin that is not the page's own. On a Shopify storefront nearly all of it belongs to apps, and the route an app took onto the page decides where its script sits, whether it blocks anything, and whether uninstalling the app removes it. Shopify's app integration overview lists the routes; three of them put code on a product page.
The first is the theme app extension, which every new app submitted to the App Store has to use. Its configuration reference describes two kinds of block. An app block renders inline, where you place it in the theme editor. An app embed block has no place in the layout: Shopify injects it before the closing head or body tag, and it is meant for chat bubbles, badges, analytics and pixels. The JavaScript file an embed declares in its schema is added as a script async tag in the head, once per page however many blocks reference it. Embeds are off when the app is installed and switched on in the theme editor under Theme settings, App embeds, per theme. The size guidance in the same reference is a suggested 10 KB of compressed JavaScript per extension, and suggested is the operative word: the 100 KB Liquid limit is enforced at deploy, the script budget is not.
The second is the script tag, an Admin API record that tells Shopify to load a remote file into the storefront on every page. It never appears in theme code, so a search of the theme finds nothing, and it cannot be limited to a template. Shopify is removing it: an app cannot create or update a script tag after 1 October 2026, and on 1 March 2027 Shopify stops injecting them into storefronts altogether. The migration guide spells out what that means for a store. A feature that depends on one stops working on that date, and a vendor that has shipped the replacement embed but not yet deleted the tag is loading its script twice, which can double-count analytics events or render its widget twice.
The third is the edit: an older app, or a developer following a vendor's instructions, wrote a script tag or a render into theme.liquid or a snippet. Shopify's audit guidance is plain about the consequence: uninstalling from the admin does not always remove code from the theme, and the tag or snippet keeps loading on every page. The overview adds that an app which edits theme code takes the theme off its upgrade path, and that the app is required to tell the merchant how to remove every line.
Tracking is the exception. A pixel built as a web pixel runs in a sandbox, a web worker for app pixels and a sandboxed iframe for custom pixels, and it cannot read or write the page's DOM. It still costs a request and CPU, but it is not on the document's rendering path, which is why it is the replacement Shopify names for a script tag that only collects data.
A synchronous script in the head is paid for before the first pixel paints
Shopify's defer and async page gives the sequence. When the parser meets a script src with neither attribute, it stops, downloads the file, runs it, and only then resumes. Nothing below the tag is rendered, and the preload scanner that finds images and stylesheets further down the document pauses with it, so the LCP image is discovered later than it would have been. Lighthouse's render-blocking rule is exactly this: a script in the head with no defer and no async, or a stylesheet with no media attribute that matches the device.
async runs the file the moment it arrives, which can still interrupt parsing; defer waits until parsing is done and runs files in document order before DOMContentLoaded. Shopify's guidance is defer for anything that touches the DOM and async only for independent tags such as analytics. Dawn, the reference theme, loads its own scripts with defer in its layout file and places content_for_header, where Shopify writes what it needs, after them. The one script that is synchronous by design is the anti-flicker snippet of an A/B testing tool, which hides the page until the variant loads. Shopify's page on it puts the cost at over two seconds of first contentful paint in common cases, paid by every visitor for a test that runs on a fraction of them, and says to remove it whenever no test is running.
Then the work after the paint. Every script runs on the one main thread that also lays out, paints and answers taps. Web.dev's definition of a long task is anything over 50 milliseconds, the point past which the browser cannot break off to respond to input; total blocking time is the sum of everything beyond that line, and it is the lab proxy for INP, whose threshold is 200 milliseconds. Lighthouse's third-party audit fails a page when scripts from other origins block the main thread for 250 milliseconds or more between them. The Web Almanac's 2022 chapter on third parties found that 94% of pages load at least one, and an average median blocking time of 1.4 seconds across the ten most used.
The rule that governs what an app may cost is per app. Shopify's App Store requirement is that an app must not reduce the storefront's Lighthouse performance score by more than ten points, measured on a benchmark store weighted 40% product page, 43% collection and 17% home. Nothing in it caps the sum. Ten apps each inside the limit are ten apps, and the product page pays for all of them on every load.
Twenty minutes in DevTools names every app on the product page and prices it in milliseconds
Use the best-selling product page, not the homepage. It carries the review widget, the size chart, the upsell and the sticky bar, and it is the page that has to sell.
Which scripts load. Open the page in Chrome, open DevTools, go to the Network panel, and in the filter bar choose More filters and tick 3rd-party requests. The panel reference defines the filter as every request whose origin differs from the page's, so Shopify's own CDN is in the list alongside the vendors; the theme's files and app extension assets both come from it, and the file names tell them apart. Reload, and the status bar gives the count. Sort by Domain and write every domain down with what it weighs. Then map domains to apps: Settings, Apps and sales channels, for what is installed; the theme editor, Theme settings, App embeds, for which embeds are on; and the page source, where each app block sits in a wrapper carrying the shopify-app-block class, per Shopify's app-injected content note. A domain with no app behind it is the finding.
What each costs. Open the Performance panel, set CPU throttling to 4x slowdown and the network to a slow 4G profile, because that is the mobile condition Lighthouse tests under and a script that is cheap on a laptop is not cheap on the phone your buyers use. Record a reload. With nothing selected, the Summary tab shows what the panel reference calls the 1st / 3rd party table: every detected entity, its transfer size and its main-thread time. That column is the number. Hover an entity and click Bottom-up to see which of its functions the time went to; tick Dim 3rd parties to see the page's own work on its own. The Insights tab lists render blocking requests, and any script without defer or async appears there.
What removal would save, before removing anything. Shopify's audit page has the method. In the Network panel open Network request blocking from the drawer, add a pattern for one vendor's domain, enable blocking, reload, and record again. The difference in main-thread time is that app's cost. Web.dev's guide adds that three runs and the median are more stable than one, and that if blocking a domain changes nothing, the culprit is elsewhere.
The cross-check. Run Lighthouse in the same DevTools on mobile. Eliminate render-blocking resources lists the offending URLs, Reduce JavaScript execution time warns past two seconds and fails past three and a half, and the Treemap link shows every script as a box sized by bytes. The Coverage tab, per Shopify's worst offenders guide, shows how much of each file ran; a script that is mostly red on the product page is a candidate, once it has also been checked on a collection page where it might do its work. On a theme in a code editor, shopify theme check runs Shopify's linter, whose ParserBlockingScript and RemoteAsset checks flag exactly the two things this page is about.
Then the field. The Web Performance dashboard in the admin reports Core Web Vitals from real visitors by page type and device, and Shopify's testing guide says what it is for: a baseline, and a regression check after an app install. The lab run says which script; the field says whether buyers felt it.
Remove in order of what each script costs, and the first three cost nothing to remove
First, scripts with no app behind them. Shopify's audit page lists where they hide: layout/theme.liquid for script tags, the snippets folder for files named after an app, and render or include tags in sections that point at them. Search the theme for script src and for each domain from the Network list, then search the page source for the domain to confirm it no longer loads. Delete the file and the tag that renders it. This is pure removal and it is free.
Second, duplicates. Two review apps, two analytics providers, a tag manager loading a pixel Shopify already fires. Shopify's list of usual suspects is worth reading against your own: chat, reviews, email capture, analytics, A/B testing, recommendations, social embeds. Keep one of each.
Third, the anti-flicker snippet, on any day no test is running. Two seconds of first paint for nothing.
Fourth, apps by their number. Shopify's render-blocking page sets the bands: an app blocking for 500 milliseconds or more is removed or replaced now; under 100 milliseconds, it is optimised and left. Between the two, ask whether it earns its place on every page. A review summary can be rendered from the standard reviews.rating metafield in Liquid with no script at all, and the same page shows the snippet.
Fifth, what stays gets scoped. An app embed is on or off per theme, not per template. A script in theme code can be wrapped in {% if template.name == 'product' %} so it loads nowhere else. A chat widget can be a facade, a button that looks like the bubble and loads the real script on click, which is the pattern Lighthouse's facade audit recommends for chat, video and social embeds. Web.dev's loading guide puts a preconnect to a vendor the page will certainly use at 100 to 500 milliseconds saved, with the caution that the browser drops an unused connection after ten seconds: one or two, not one per vendor.
Sixth, the calendar. Ask each remaining vendor whether the app still uses a script tag. After 1 March 2027 that script does not load and the feature it powers stops. A vendor that has shipped its app embed but not deleted the tag is on the page twice until then.
One thing not to install: an app that promises a score. Shopify's page on fake performance apps describes the mechanism, a script that detects Lighthouse by its user agent and serves it a lighter page, or paints a transparent element so that LCP reports the wrong thing. If PageSpeed Insights and a local Lighthouse run differ by 20 points or more, one of them is being lied to.
Fix it in this order, and it takes an afternoon
First, the list: Network panel, third-party filter, product page, twenty minutes including the mapping to apps. Second, the leftovers: search the theme, delete, confirm in the page source; half an hour, no developer for a snippet, a developer for anything in theme.liquid you do not recognise. Third, the duplicates and the anti-flicker snippet, which is a decision more than a technical task. Fourth, the Performance recording and the blocking test for each app that remains, ten minutes per app, and a written number next to each. Fifth, scoping and deferring what stays, an hour for a developer. Sixth, the field: Shopify's lab and field guide notes that public field data is a 28-day rolling window, so check the dashboard a month on.
It is the second of the four causes in why your Shopify store is slow, and the one that also moves cumulative layout shift when a widget arrives late and pushes the price down. Section two of the audit checklist is where the number lands. If you would rather have the apps listed, priced and ranked against everything else on the store, that is the Store Teardown: €750, five days, and the document is yours whatever you decide to do with it.