Knowledge
Shopify ExcellenceGuide8 min

7 Reasons Your Shopify Store Loads Too Slowly (And How to Fix Each One)

Diagnose and fix the 7 most common Shopify performance killers — from unoptimized images and app bloat to render-blocking scripts and inefficient Liquid code.

Your Shopify store is slow. I know this because almost every Shopify store is slow. The average Shopify store scores between 25 and 40 on Google PageSpeed Insights mobile — well below the 50+ threshold Google considers acceptable. And speed isn't vanity: Google's own research shows that going from 1 second to 3 seconds of load time increases bounce probability by 32%. At 5 seconds, it's 90%. Every 100ms of improvement translates to measurable revenue. The good news is that Shopify speed problems follow predictable patterns. After auditing hundreds of stores, I can tell you that the same 7 issues account for roughly 90% of all speed problems. Even better, most of them are fixable without a developer. This guide walks through each one: how to diagnose it, the exact steps to fix it, and what kind of improvement you can realistically expect.

1. Unoptimized Images: The Biggest Single Offender

Images account for the majority of page weight on most Shopify stores. I regularly audit stores where a single hero image is 3–5MB — larger than the entire rest of the page combined. When your hero banner takes 4 seconds to load on mobile, your LCP (Largest Contentful Paint) score is shot before anything else even matters. How to diagnose: Open Chrome DevTools, go to the Network tab, filter by 'Img', and sort by size. Any image over 200KB on a product page or 500KB on a homepage hero is a problem. Also check the format column — if you see .png or .jpg instead of .webp, your images aren't being served in modern formats. How to fix it: Shopify's CDN automatically serves images in WebP format when the browser supports it, but only if you use Shopify's image_url Liquid filter or the native image picker in your theme. Images hardcoded as static URLs in custom HTML bypass this optimization. Beyond format, resize before uploading. A hero banner doesn't need to be 4000px wide — 1920px is sufficient for any screen. Product images should be 1200–1600px on the longest side. For existing catalogs with thousands of unoptimized images, use a bulk image optimization app like TinyIMG or Crush.pics to compress your existing library. These typically reduce image file sizes by 40–70% without visible quality loss. Implement lazy loading for all images below the fold. Most modern Shopify themes include this by default, but verify it's active. The native loading='lazy' HTML attribute is the simplest approach. Only your hero image and first few visible product thumbnails should load eagerly. Expected improvement: Optimizing images typically improves LCP by 1–3 seconds and can boost your PageSpeed mobile score by 15–25 points. It's almost always the single highest-impact fix.

Create a simple image spec sheet for anyone who uploads products: maximum 1600px wide, WebP or JPEG format, maximum 200KB file size. Post it next to your desk. Most image bloat comes from team members uploading uncompressed photos directly from cameras or design tools.

2. App Bloat: The Silent Performance Killer

Every Shopify app that adds front-end functionality injects JavaScript and CSS into your store. Reviews apps, upsell popups, chat widgets, countdown timers, currency converters, trust badge apps — each one adds weight. The problem isn't any single app. It's the accumulation. I audited a store last quarter running 23 apps. Fourteen of them injected front-end scripts. Total additional JavaScript: 1.2MB. The store's PageSpeed mobile score was 12. After removing 8 apps they weren't actively using, the score jumped to 38 — a 26-point improvement from uninstalling alone. How to diagnose: Go to your storefront, open Chrome DevTools, navigate to the Network tab, and filter by 'JS'. Sort by size and look at the domain names. Every script that doesn't come from cdn.shopify.com or your theme is an app injection. Add up the total size of third-party scripts. If it exceeds 300KB combined, you have an app bloat problem. How to fix it: First, audit ruthlessly. Go to Settings > Apps in your Shopify admin. For each app, ask two questions: 'Is this app generating revenue or saving time that justifies its performance cost?' and 'Is there a lighter alternative?' Apps you installed to try and forgot about are the most common offenders — uninstall them immediately. Uninstalling isn't always enough. Some apps leave behind code snippets in your theme even after removal. Go to Online Store > Themes > Edit Code and search for remnants of uninstalled apps in theme.liquid, layout files, and snippet files. For apps you need to keep, check if they offer a performance or lite mode. Many review apps, for example, can load asynchronously or only on product pages instead of site-wide. Some chat widgets offer a lazy-load option that delays script loading until the visitor scrolls or shows exit intent. Expected improvement: Removing unused apps typically improves PageSpeed by 10–30 points depending on how many scripts you eliminate. Each removed 100KB of JavaScript is roughly 0.5–1 second faster on mobile.

Keep a spreadsheet of every app you install with the date, purpose, and monthly cost. Review it quarterly and uninstall anything you haven't actively used in 60 days. App sprawl happens gradually, and by the time you notice the speed impact, you're carrying a dozen apps you forgot about.

3. Render-Blocking JavaScript: Holding Your Page Hostage

Render-blocking JavaScript is code that must be downloaded, parsed, and executed before the browser can display anything on screen. It's the reason some stores show a blank white screen for 2–3 seconds before content appears — the browser is waiting for scripts to finish before it can paint a single pixel. How to diagnose: Run your store through Google PageSpeed Insights and look for the 'Eliminate render-blocking resources' opportunity in the diagnostics section. It lists every script and stylesheet that blocks rendering, along with the estimated time savings from deferring them. You can also use Chrome DevTools' Performance tab — record a page load and look for long tasks on the main thread during the initial loading phase. How to fix it: The goal is to move non-critical JavaScript from the <head> to the bottom of <body>, and add the 'defer' or 'async' attribute to scripts that don't need to execute immediately. In your Shopify theme code, look at theme.liquid. Scripts in the <head> section without async or defer attributes are render-blocking. Third-party scripts — analytics, tracking pixels, chat widgets — should almost always be deferred. Move them to just before </body> and add the defer attribute. For Google Analytics and Meta Pixel specifically, loading them asynchronously has zero impact on data accuracy but meaningfully improves rendering speed. Google Tag Manager should be loaded with the async attribute, and your GTM container should be configured to fire tags after the DOM is interactive, not on page load. Shopify's own scripts (checkout, dynamic sections, Shopify analytics) are already optimized and shouldn't be modified. Focus your deferral efforts on third-party scripts and app-injected code. One caution: some scripts break when deferred because they depend on being available immediately. Test thoroughly after making changes. A broken checkout because you deferred Shopify's payment scripts is worse than a slow page. Expected improvement: Properly deferring render-blocking scripts typically reduces First Contentful Paint (FCP) by 0.5–2 seconds and improves the PageSpeed score by 5–15 points.

If you're uncomfortable editing theme code, use Google Tag Manager to manage all third-party scripts instead of pasting them directly into your theme. GTM gives you centralized control over when and how each script loads, with built-in triggers for deferred loading.

4. Heavy Themes: When Your Foundation Is the Problem

Your Shopify theme is the foundation of your store's performance. A bloated theme with excessive features sets a performance floor that no amount of optimization can overcome. I've seen premium themes where the theme itself — before any content, apps, or images — scores 45 on PageSpeed because it loads 400KB of JavaScript and 200KB of CSS for features like mega menus, parallax scrolling, product quick-views, and animation libraries that the merchant doesn't even use. How to diagnose: Create a blank test page with no content and test it in PageSpeed Insights. This gives you your theme's baseline score — the best your store can possibly perform before you add any content or apps. If a blank page scores below 70 on mobile, your theme is a significant bottleneck. Also check your theme's total JavaScript and CSS size in Chrome DevTools — themes loading more than 250KB of combined JS/CSS are on the heavy side. How to fix it (without switching themes): Most premium themes include toggle switches for features you may not be using. Disable parallax effects, product quick-views, infinite scroll, and animation libraries you don't need. Check if your theme offers a 'performance mode' or 'lite CSS' option. Remove unused sections from your theme's template files. Some themes load JavaScript for every available section type whether it's used on the page or not — removing unused section definitions can reduce this. When to consider switching themes: If your theme's baseline score is below 50 on mobile and disabling features doesn't meaningfully improve it, the theme architecture itself is the problem. Consider migrating to Shopify's Dawn theme (open source, performance-optimized) or a lightweight premium theme like Prestige, Impulse, or Sense that's built with performance as a priority. Theme migration is a significant project — budget 2–4 weeks for a thorough migration with design customization. Expected improvement: Switching from a heavy theme to a lightweight one typically improves PageSpeed mobile scores by 20–40 points. Disabling unused features on a heavy theme usually yields 5–15 points.

Before purchasing a premium theme, install it on a free development store, add a few test products, and run PageSpeed Insights. Never trust the theme developer's demo score — demo stores are meticulously optimized and don't represent real-world performance with your content and apps.

5. Third-Party Scripts: The Tracking Tax

Beyond Shopify apps, most stores load additional third-party scripts for analytics, advertising, live chat, reviews, social proof, and personalization. Each script makes HTTP requests to external servers, and those servers' response times are completely outside your control. The usual suspects: Google Analytics (GA4), Meta Pixel, Google Tag Manager, Hotjar or Microsoft Clarity, Klaviyo tracking, TikTok Pixel, Pinterest Tag, live chat widgets (Tidio, Intercom, Zendesk), social proof popups (FOMO, Nudgify), and review widgets (Judge.me, Yotpo, Loox). I've seen stores loading 12 or more third-party scripts simultaneously. How to diagnose: In Chrome DevTools, go to the Network tab and look at the 'Waterfall' column during page load. Third-party scripts from external domains often create long chains of dependent requests — one script loads, which triggers another script, which loads a font, which loads a stylesheet. These cascading chains can add 2–5 seconds to your total load time. Also use the Coverage tab in DevTools (Cmd+Shift+P > 'Show Coverage') to see how much of each loaded script is actually used on the page. It's common to see scripts where 70–80% of the code is unused. How to fix it: Consolidate tracking through Google Tag Manager instead of individual script tags. GTM loads one script and manages everything else, giving you control over when each tag fires. Set non-essential tags to fire on 'DOM Ready' or 'Window Loaded' instead of 'Page View' — this defers their execution until after the page is visible. For live chat widgets, implement lazy loading. Load the chat script only when the visitor scrolls past the fold, clicks a chat button, or shows exit intent. Most chat providers support this natively. Tidio and Intercom both offer delayed loading options. For reviews, load review widgets below the fold with intersection observer — the script only loads when the review section scrolls into view. Consolidate overlapping tools. If you're running both Hotjar and Clarity, pick one. If you're running GA4 and a separate analytics tool, evaluate whether you need both. Every elimination is a performance win. Expected improvement: Consolidating and deferring third-party scripts typically improves Time to Interactive (TTI) by 1–3 seconds and PageSpeed scores by 5–20 points.

Audit your third-party scripts quarterly using the 'What's loading on my site?' approach: open DevTools, load your homepage, and screenshot the Network tab. If you can't explain why each external script is there and what revenue it supports, it probably shouldn't be there.

6. Liquid Code Inefficiency: Death by a Thousand Loops

Shopify's Liquid templating language executes server-side before the page is sent to the browser. Inefficient Liquid code increases Time to First Byte (TTFB) — the time between requesting a page and receiving the first byte of data. While Shopify's server infrastructure is fast, poorly written Liquid can add 500ms–2 seconds to TTFB on complex pages. How to diagnose: Use Shopify's built-in performance profiler. Add ?performance=true to any URL on your store (you must be logged into admin). This shows execution time for every Liquid snippet, section, and block on the page. Look for any single component taking more than 50ms. Also check your TTFB in Chrome DevTools' Network tab — if the first response takes more than 800ms consistently, Liquid performance is likely a factor. Common Liquid performance killers: Nested for loops that iterate over large collections within product pages. I've seen themes that loop through every product in a collection to build 'related products' — on a collection with 500 products, this is catastrophic. Excessive use of the 'all_products' global object, which isn't cached and triggers a database query on every reference. Repeated calls to the same metafield data within a loop instead of assigning it to a variable once. Loading entire collection objects when you only need product titles and URLs. How to fix it: Replace loops over large collections with Shopify's 'recommendations' API, which is optimized and cached. Assign frequently accessed objects to variables at the top of your template using capture or assign tags. Use the 'limit' parameter on for loops to cap iterations. Replace inline product rendering in collection pages with Shopify's native section rendering, which leverages edge caching. For stores with heavy Liquid customization, consider moving complex logic to the front-end using JavaScript or Shopify's Storefront API. Server-side Liquid should handle basic rendering, while dynamic features like filtering, sorting, and personalization should run client-side after the initial page render. Expected improvement: Optimizing Liquid code typically reduces TTFB by 200ms–1 second. On pages with severe inefficiency (nested loops over large collections), improvements of 2–3 seconds are possible.

The ?performance=true profiler is the most underused diagnostic tool in the Shopify ecosystem. Run it on your 5 highest-traffic pages and address anything taking more than 50ms. Most merchants have never seen this tool — it's not advertised anywhere in the admin.

7. Large DOM Size: When Your Page Has Too Many Elements

The DOM (Document Object Model) is the browser's representation of your page's HTML structure. Every HTML element — every div, span, image, paragraph, and hidden element — adds to the DOM size. Google flags pages with more than 1,500 DOM elements as potentially problematic, and pages with more than 3,000 elements as excessive. Large DOMs slow down everything: initial parsing, style calculations, layout reflows, and JavaScript execution. How to diagnose: Run PageSpeed Insights and look for the 'Avoid an excessive DOM size' diagnostic. It tells you exactly how many elements your page has and identifies the deepest nesting level and the element with the most children. You can also check in DevTools: open the Console and run document.querySelectorAll('*').length to get a quick element count. Common causes on Shopify stores: Hidden mobile and desktop duplicates — many themes render both mobile and desktop versions of navigation, headers, and footers, then hide one with CSS. This means the browser processes twice the elements even though half are invisible. Product pages with dozens of variant swatches each generating multiple nested elements. Review sections that load all reviews into the DOM at once instead of paginating. Mega menus that render their entire structure (hundreds of links) on every page whether the visitor opens the menu or not. Slider and carousel components that duplicate elements for animation purposes. How to fix it: Replace CSS-hidden duplicates with responsive approaches that use a single HTML structure with CSS media queries. This alone can reduce DOM size by 20–30% on stores with separate mobile/desktop markup. Paginate or lazy-render reviews and product grids — load the first 10 reviews and render more on scroll or click. Defer mega menu rendering until the visitor hovers or taps the menu trigger. Use Shopify sections with the 'loading: lazy' attribute for below-the-fold content. For product pages with many variant swatches, consider rendering only the currently visible options and generating additional swatches when the customer interacts with option selectors. This reduces initial DOM size significantly for products with complex variant matrices. Expected improvement: Reducing DOM size from 3000+ elements to under 1500 typically improves INP (Interaction to Next Paint) by 100–300ms and can improve PageSpeed scores by 5–10 points. The improvement is most noticeable in interaction responsiveness — the page feels snappier when clicking, scrolling, and selecting options.

Run document.querySelectorAll('*').length in your browser console on your homepage, a collection page, and a product page right now. If any page exceeds 2000 elements, you have a DOM size problem worth addressing. Most merchants are shocked by how high the number is.

Conclusion

Shopify store speed isn't mysterious — it's systematic. The same 7 problems affect nearly every store, and the fixes follow a clear priority order: start with images (highest impact, easiest fix), then audit your apps (second highest impact), then address render-blocking scripts, evaluate your theme weight, consolidate third-party tracking, optimize Liquid code, and reduce DOM size. You don't need to fix everything at once. Start with a PageSpeed Insights audit of your three most important pages: homepage, top collection page, and top product page. Address the biggest bottleneck on each. Then re-test and move to the next issue. Incremental improvements compound — fixing three problems that each save 1 second gives you a 3-second faster store. The merchants who take speed seriously see measurable results in their conversion rates. Not because speed is magic, but because every millisecond of friction you remove is one less reason for a visitor to leave before buying.

Key Takeaways

  • 01Unoptimized images are the single biggest speed killer — compress to WebP, resize to 1600px max width, and keep files under 200KB
  • 02The average Shopify store runs 15+ apps, but most inject front-end scripts — audit quarterly and remove anything unused for 60+ days
  • 03Defer non-critical JavaScript using the async or defer attributes, and load third-party tracking through Google Tag Manager
  • 04Test your theme's baseline performance on an empty page — if it scores below 50, the theme itself is your bottleneck
  • 05Use Shopify's hidden performance profiler (?performance=true) to identify slow Liquid code on your highest-traffic pages