Find out what your theme's JavaScript actually does, remove anything that duplicates a native browser or theme feature, defer everything that does not need to run before the first view, and test every storefront feature after each change. Work in a theme copy so nothing touches the live store until it passes.
You cannot cut what you cannot see. Open the theme on a product page in a desktop browser, open developer tools, and run the Coverage tab while scrolling the page and using its features. Coverage shows which scripts load and how much of each one actually executes. In most themes, the results surprise the owner: a slider library that renders one hero carousel, an animation framework used by a single section, and utility libraries loaded on every page for features that live on one. Write down every script, what it does, and whether any customer-facing feature depends on it. Also separate first-party theme JavaScript from app JavaScript, because the two are reduced differently and apps are usually the bigger problem.
Deleting a script beats deferring it. Look for these common candidates. Carousels and sliders that only show one view at a time can often be replaced with CSS scroll-snap, which handles swiping and snapping with no JavaScript at all. Countdown timers, announcement-bar rotators, and scroll-triggered reveal animations are decorative and safe to drop or convert to CSS. Duplicate jQuery loads (one from the theme, one from an app) should be consolidated or eliminated since modern themes do not need jQuery. Social share buttons that load a third-party widget can become plain links. Be honest about features nobody uses: the fancy quick-view modal with a 2% open rate is costing every visitor load time. Remove in the theme copy, then publish the copy to a preview link and click through everything before it goes live.
Some JavaScript earns its place: the cart drawer, the product form, predictive search, filter logic. That code does not need to run before the first paint, though. Mark non-critical scripts with the defer attribute so they load after the page renders, and load below-the-fold features only when they approach the viewport. A reviews widget, for example, can wait until the shopper scrolls near it. For scripts that only matter on one template, use conditional loading in Liquid: check the template name and only include the script where it is used, instead of loading it globally in theme.liquid. The rule is simple: if a feature is not visible in the first view, its JavaScript should not block the first view.
Browsers have absorbed features that used to require libraries. CSS scroll-snap handles carousels and horizontal scrollers. The details and summary elements build accordions and collapsible content with zero scripts. Native lazy loading on images and iframes replaces custom lazy-load libraries. Sticky positioning in CSS replaces scroll-listener sticky headers. The dialog element can replace modal libraries for simple popups. Each replacement removes a dependency, a download, and a failure mode. The tradeoff is control: native features behave like the browser says, not like the designer dreamed. For standard commerce UI (accordions, drawers, tabs, carousels) the native behavior is good enough, and the speed gain is real. Reserve custom JavaScript for interactions that genuinely have no native equivalent.
In most stores, apps contribute more JavaScript than the theme itself. Audit app embeds the same way you audited theme scripts: list them, name the customer-facing job each one performs, and disable anything you cannot name. Uninstall apps you stopped using; disabled embeds from uninstalled apps can linger, so check the theme files for leftover script tags after an uninstall. For apps you keep, check whether the app offers a lightweight mode, fewer features enabled, or loading only on specific pages. Talk to the app developer if the script loads globally with no way to scope it. One heavy app (reviews, loyalty, chat) can outweigh all the theme reductions you just made, so do this audit before touching theme code.
JavaScript removal breaks things in ways that are easy to miss. After each change, walk the storefront on desktop and on a phone: open the cart drawer, add and remove items, use search and filters, open the mobile menu, expand every accordion, submit the newsletter form, and complete a test checkout. Do this after every single change, not at the end, so you know exactly which removal caused a problem. Keep a list of the scripts you removed and why, so the next theme update or app install does not silently reintroduce them. When the cleaned-up copy passes the full walkthrough, publish it and re-run your speed measurements to confirm the gain. The number should move on mobile product pages first, which is where most shoppers will feel it.
Reviewed Sep 24, 2026.
Always work on an unpublished copy for anything beyond a tiny text change. Preview the copy, test the cart and checkout paths, then publish when it checks out. Your previous version is your rollback.
A metafield is a custom data field attached to a product, collection, or page, like a care instruction or a sizing note. Themes can display metafields natively, which makes them the clean way to store per product content.