14 July 2026 · 3 min read
Why your Shopify store is slow
It is almost never the theme. It is the eleven apps nobody removed.
When a founder tells me the store is slow, the theme gets blamed first. It is almost never the theme. Dawn, Impulse, Prestige, Sense: all of them score in the 80s and 90s on a clean install. The store scores 31 because of what was added later and never removed.
The apps
Every Shopify app that touches the storefront adds a script. Reviews, wishlist, currency switcher, size chart, countdown timer, popup, chat, upsell, loyalty, back-in-stock. And the analytics tool that was installed to find out why the store is slow. A typical store I audit has nine to fourteen of these. Each one is 50 to 400 KB of JavaScript. Most of them load on every page, used or not.
It gets worse. Uninstalling an app often leaves its code behind. Old theme app extensions. Snippets in theme.liquid. Script tags in the settings. I have removed scripts for apps that were cancelled two years earlier. They were still loading on every product page.
The fix is an audit, not a plugin. Open the theme code. Search for every script tag in theme.liquid and the layout files. Match each one to a live app. Delete what has no owner. Then go through the app list. For each one, ask what money it makes. Most cannot answer that. Most go.
Images
This is the second biggest cause. A 4,000 pixel hero, exported from Photoshop at 3.2 MB, sent to a 390 pixel phone. Shopify’s image CDN will resize on the fly, but only if the theme asks for the right size. Older themes and hand-edited sections often ask for the original. Use the image_url filter with a width. Add srcset with the responsive widths. Set width and height attributes so the layout does not jump.
Formats matter less than people think. Shopify already serves WebP where the browser supports it. Size and lazy loading matter more. Everything below the fold gets loading="lazy". The hero image does not, and it gets a preload tag.
Collection pages are the worst. Forty product cards, each asking for a 2,000 pixel image to fill a 180 pixel tile. Fix the card snippet once. Every collection page in the store gets faster the same day.
Render-blocking assets
This is anything in the head that must download before the page can show. Font files from three different services. A 200 KB icon font for four icons. A jQuery build the theme does not need. Move scripts to the end of the body or mark them defer. Host the two fonts you really use yourself, and preload them. Delete the icon font and inline the four SVGs.
Pixels
Meta Pixel, TikTok Pixel, Google Ads, GA4, Hotjar, Microsoft Clarity. Each one is a script. Several load their own helpers. Keep the ones that feed a live campaign. Move the rest into Google Tag Manager, so you can switch them off without touching the theme. Think about the Conversions API for Meta, so the browser does less of the work.
The hero video
A 40 MB MP4 on autoplay is the most expensive thing on the page. It plays for two seconds before the visitor scrolls past. If the brand needs motion, use a poster image. Compress the video to under 3 MB with HandBrake at 720p. Strip the audio track. Load it only once the page is interactive.
What moves Core Web Vitals
Three numbers count for ranking and for real people. Largest Contentful Paint is usually the hero image. You fix it by sizing and preloading that image. Interaction to Next Paint is fixed by removing scripts that fight for the main thread. Cumulative Layout Shift is fixed by giving images dimensions, and by not adding banners above content after load.
Here is what does not move them. A caching app. A "speed booster" app. Minifying Liquid. A theme rebuild that keeps all the same apps. Those are theatre. They give you a screenshot of a Lighthouse score, taken on a desktop with the apps turned off. The store is just as slow on Monday.
This week
Run PageSpeed Insights on your best-selling product page. Use the mobile tab. Write down LCP and the total JavaScript in the treemap. Then open Shopify admin, Apps, and count. If the count is above six, pick the two you cannot connect to revenue. Remove them, and their leftover code too. Run the test again. That difference is real, and it is yours to keep.