Why JavaScript Hurts Speed
JavaScript is render-blocking by default. When a browser encounters a JS file, it pauses rendering your page to download, parse, and execute that script. The more JS files you have, the longer your visitors wait for a usable page.
Google's Core Web Vitals measure Time to Interactive (TTI) and Total Blocking Time (TBT), both of which are directly impacted by JavaScript. A store with 15 app scripts loading on every page will consistently fail these metrics, harming both SEO rankings and conversion rates.
The average Shopify store loads 800KB-2MB of JavaScript. Well-optimised stores keep this under 300KB. The difference is typically unneeded app scripts, legacy code, and poorly configured third-party tools.
Auditing Your JavaScript
Start by running your homepage and product page through PageSpeed Insights (pagespeed.web.dev). The "Reduce unused JavaScript" and "Eliminate render-blocking resources" recommendations will list specific files by size.
Open Chrome DevTools, go to the Network tab, and filter by JS. Reload the page and note every script file, its size, and its source domain. Third-party domains (not your store's domain) are usually app scripts or analytics tools.
For a more detailed breakdown, use the Chrome Coverage tab (DevTools, More tools, Coverage). This shows what percentage of each JS file is actually used on the current page. Files with 80%+ unused code are prime candidates for deferral or removal.
Removing Unused App Scripts
When you uninstall a Shopify app, its scripts often remain in your theme code. Go to your theme editor, navigate to theme.liquid, and search for script tags from any apps you no longer use. These include GTM tags, chat widgets, review app scripts, and pop-up tools.
Also check the App Embeds section in your theme editor. Active app embeds load their JavaScript on every page. Disable any you no longer use.
Before You Remove
Always duplicate your theme before editing. In the Themes section, click the three dots menu on your live theme and select "Duplicate". Work on the duplicate first.
Deferring Non-Critical JS
Scripts that do not need to run immediately can be deferred using the defer or async attribute. This allows the page to continue rendering while the script downloads in the background.
Add defer to scripts in theme.liquid: change <script src="..."> to <script defer src="...">. Use async for completely independent scripts like analytics. Avoid defer for scripts that other scripts depend on, as this can cause errors.
Third-Party Script Management
Load all marketing and analytics scripts through a tag manager like Google Tag Manager rather than adding them directly to your theme. This gives you centralised control and allows you to fire scripts conditionally (e.g., only on purchase confirmation pages, not every page).
Consider loading chat widgets only after user interaction rather than on page load. A chat button can appear immediately using CSS, with the full chat library only loading when a user clicks it. This can save 200-500KB of JavaScript on every page load.
Measuring Improvements
After making changes, measure using PageSpeed Insights (use the mobile report as it is more stringent), Google Search Console's Core Web Vitals report, and your own analytics to track bounce rate and conversion rate changes.
Aim for a Total Blocking Time under 200ms and Time to Interactive under 3.8 seconds on mobile. These are the thresholds Google uses for "Good" ratings in their Page Experience signal.