Your Shopify theme is the foundation everything else sits on. A bloated theme loads unused JavaScript, renders hundreds of unnecessary DOM elements, and bakes in animations that hurt mobile performance. The fix starts with choosing lean themes, removing sections you never use, cleaning Liquid templates, and testing every change. Get the foundation right and every other optimization becomes more effective.
Why Your Theme Is a Bigger Problem Than You Think
Most store owners blame their apps when speed drops. Apps are definitely a factor, but the theme is often the silent culprit sitting underneath everything else.
Here is why: Shopify themes ship with code for every feature they support. Mega menus, video backgrounds, product quick-buy overlays, parallax scrolling, countdown timers, wishlists, image zoom, sticky headers with color transitions. You turn on three of these. The code for all fifteen loads anyway.
The other issue is that theme code ages poorly. A theme you installed three years ago was probably fine then. Shopify's platform has evolved, browser standards have shifted, and what counted as acceptable code in 2021 is now a performance liability in 2026. Themes need maintenance, not just initial setup.
How to Choose a Fast Shopify Theme
The time to think about speed is before you install a theme, not after.
Check the theme's PageSpeed score before buying. Shopify's Theme Store shows a performance score for each theme. Look for mobile scores above 60 on a clean install with no apps. If a theme scores 42 out of the box, it will be significantly worse with a real store on top of it.
Look at what the theme loads by default. Install the theme on a development store, open Chrome DevTools, go to the Network tab, and count the JavaScript files. A lean theme loads 3 to 6 JS files. A heavy theme loads 15 or more.
- Dawn - Free, Shopify's reference theme. No jQuery, minimal JS, clean Liquid.
- Sense - Clean design, good performance defaults, well-maintained.
- Craft - Minimal, content-focused, fast out of the box.
- Crave - Slightly heavier but well-optimized for food and lifestyle brands.
Any theme marketing itself heavily on animations, parallax effects, or "immersive storytelling" features. These descriptions often mean high JavaScript overhead baked into the core structure that cannot be removed.
How to Remove Unused Theme Sections
Every section you leave in your theme customizer, even if hidden or unused, may still contribute to your DOM size and in some cases still loads associated JavaScript.
Go to Online Store > Themes > Customize. Click through every page template. Look for sections that are:
- Hidden (toggled off but still present in the template)
- Empty (added but never configured)
- Duplicated (same functionality from two different sections)
- Irrelevant (a "featured blog" section on a store with no blog)
For sections you keep, audit what they load. A "featured collection" section that loads a carousel with Swiper.js just to display four products is doing too much. A simple grid achieves the same goal with a fraction of the JavaScript.
Also check your JSON templates. Shopify themes store page configurations in JSON template files like templates/index.json. Open these in the theme code editor and look for section entries that reference sections you have removed. Orphan references can cause Liquid errors or unnecessary rendering.
Cleaning Shopify Liquid Templates
Liquid is Shopify's templating language. It runs server-side, which means slow Liquid code increases your Time to First Byte (TTFB), the time before the browser receives even the first byte of HTML.
Common Liquid performance problems to fix:
A loop inside a loop is expensive. If your theme renders all collections and then for each collection renders all products, the server executes a large number of queries. Look for
for loops inside other for loops and refactor where possible.Fetching a metafield value for every product in a 48-product collection means 48 separate lookups. Move metafield-dependent logic outside of product loops or cache results in a variable.
Liquid
assign tags that set variables never used later add minor overhead and signal the template was edited carelessly over time. Clean them up during audits.Here is a simple example of inefficient vs cleaner Liquid:
<!-- Avoid: assigns an unnecessary variable on every loop iteration -->
{% for product in collection.products %}
{% assign badge = product.metafields.custom.badge %}
<div class="badge">{{ badge }}</div>
{% endfor %}
<!-- Better: access the metafield directly -->
{% for product in collection.products %}
<div class="badge">{{ product.metafields.custom.badge }}</div>
{% endfor %}
How to Reduce DOM Size in Shopify
DOM size is the total number of HTML elements on a page. Google recommends keeping total DOM nodes below 1,500. Many Shopify stores run 3,000 to 6,000 nodes on their product pages. That is a browser performance problem.
A large DOM slows down initial page rendering, JavaScript that queries and manipulates elements, layout calculations on reflow after dynamic updates, and memory usage on low-end mobile devices.
Where DOM bloat comes from in Shopify themes:
-
Hidden elements: Many themes render elements hidden by CSS rather than conditionally in Liquid. A mobile navigation menu hidden via
display: noneon desktop still adds nodes. Use{% if %}conditions to not render elements that are not needed. -
Nested wrapper divs: Themes built without performance constraints often wrap every element in multiple container divs. A product card that needs three
<div>elements ends up wrapped in seven. On a 24-product grid, that is hundreds of extra nodes. - App-injected elements: Each app that injects content adds DOM nodes. Some apps inject significant HTML structures globally, even on pages where they are irrelevant.
Practical fixes:
- In your theme Liquid files, look for
style="display:none"andclass="hidden"on large elements. Replace CSS-hidden elements with conditional Liquid rendering where possible. - Flatten nested div structures in your theme's snippet files. If a section has four nested wrapper divs that serve no layout purpose, remove the inner wrappers.
- Check what each app is injecting by inspecting the DOM in Chrome DevTools. Elements injected by apps show up in the DOM tree even if they are invisible.
Optimizing Shopify Theme Structure
A well-structured theme loads only what each page needs. Use Shopify's section schema to load section-specific assets instead of loading all CSS and JavaScript globally in theme.liquid:
{% schema %}
{
"stylesheet": "section-featured-collection.css",
"javascript": "section-featured-collection.js"
}
{% endschema %}
This ensures the CSS and JS for a section only loads on pages where that section is used. A homepage-only section should not add scripts to your product pages.
Also preload critical resources in your theme's <head>:
<link rel="preload" as="font" href="{{ 'YourFont.woff2' | asset_url }}" crossorigin>
And move non-critical JavaScript to the bottom of the body or add defer. In theme.liquid, audit every <script> tag and add defer to anything that is not immediately critical for rendering.
Avoiding Heavy Animations in Shopify Themes
Animations are where themes add the most visual appeal and the most performance damage at the same time.
Run on the browser's compositor thread and do not block the main thread. Transitions and keyframes are generally fine for performance.
Especially scroll-triggered ones. These fire JavaScript on every scroll event, block the main thread, and cause dropped frames and high INP scores on mobile.
Practical rules for animations:
- Limit entrance animations to above-the-fold content where they serve a clear purpose
- Disable parallax effects on mobile they rarely work well and always cost performance
- Replace JavaScript scroll animations with CSS
animation+ Intersection Observer - Always respect the
prefers-reduced-motionmedia query:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
How to Debug a Slow Shopify Theme
When your theme is the problem but you cannot identify exactly where, these tools narrow it down fast.
Record a page load. The flame chart shows which JavaScript functions ran, for how long, and when. Look for long tasks over 50ms, these block the main thread and directly cause slow INP scores.
Press Ctrl+Shift+P, type "coverage," and run it while loading your page. Shows the percentage of each JS and CSS file actually used. Cross-reference with your theme code to find dead features.
A Chrome extension that shows Liquid render times for each template, section, and snippet. If your theme takes 800ms to render server-side, this tool tells you which Liquid code is responsible.
Theme Customization Best Practices
- Add custom CSS in the theme customizer, not in a separate app. Many store owners install a CSS/JS injection app for minor styling changes. Every app adds overhead. Use Settings > Custom CSS or your theme's CSS file instead.
- Test performance after every theme section you add. Run a quick PageSpeed check after adding a new section. If the score drops significantly, you know the new section is the cause.
- Avoid installing multiple page builder apps. Page builders (PageFly, GemPages, Shogun) generate DOM-heavy HTML and load their own JavaScript globally. If you use one, commit to it. Running two simultaneously is a performance and maintenance problem.
- Document every code edit you make to the theme. A short comment above any custom code addition makes future audits much faster. When you need to remove something added two years ago, you will know exactly what it was and why.
How to Test Shopify Themes Before Committing
- Install on a development store first. Shopify Partners accounts can create unlimited development stores. Configure sections as you plan to use them and run performance tests before going live.
- Test with a realistic app stack. A theme that scores 72 with no apps might score 45 with your real set of apps. Install your five to eight most critical apps on the development store before testing.
- Test on real mobile devices. PageSpeed simulates mobile performance but does not replicate the actual feel of scrolling and interacting. Test on a real mid-range Android device.
- A/B test themes if you are switching. Run the new theme as an unpublished theme, test it thoroughly, then switch. Watch your real user conversion data for the first week after launch.
Shopify Theme Speed Final Checklist
Choosing and Setup
- Theme selected based on PageSpeed score and JS file count
- Unused features disabled in theme settings, not just hidden
- Unused sections removed from all page templates
Code
- No nested Liquid loops fetching data unnecessarily
- Non-critical JavaScript files using defer attribute
- Section-specific CSS/JS loaded at section level, not globally
- Custom CSS added in theme settings, not via injector app
- Explicit width and height on all img tags
DOM and Structure
- DOM node count below 1,500 (check with DevTools)
- Hidden elements rendered conditionally in Liquid, not via CSS
- No unnecessary nested wrapper divs in product cards
Animations and Testing
- No JavaScript scroll animations on mobile
- prefers-reduced-motion respected
- Parallax disabled on mobile via CSS media query
- PageSpeed tested on homepage, product page, and collection page
- Coverage tab checked for unused JS/CSS percentage
- Tested on a real mobile device, not just lab simulation
Summary
Your theme sets the performance ceiling for everything else. A bloated theme means you are constantly fighting headwinds. Apps make it worse, but the theme creates the underlying drag. Choose lean themes, clean your Liquid, reduce your DOM, disable animations that cost more than they deliver, and test properly before going live.