How to Speed Up a Shopify Store Without Apps
Most Shopify speed problems come from images, scripts and installed apps, and none of them need another app to fix. Here is the order to work in, with the Liquid to do it.

Short answer: measure first, then work through five fixes in order: remove or replace unused apps, load the first-screen image correctly, defer non-essential scripts, trim fonts, and simplify heavy Liquid loops. Each is a theme change, so no speed-booster app is involved. The Liquid for the image fix and the script fix is below. Checked against Shopify's developer documentation, October 2026.
How do I find out why my Shopify store is slow?
Start with field data for your slowest important page, which is usually the home page, a collection page or a product page. Run it through PageSpeed Insights and read the real-user (field) section before the lab score, since field data reflects what visitors experienced over the last 28 days.
Google's "good" thresholds are LCP of 2.5 seconds or less, INP of 200 milliseconds or less and CLS of 0.1 or less. Note which metric fails, because the fix differs: a slow LCP points to images or render-blocking resources, a high CLS points to missing image dimensions or font swapping, and a high INP points to heavy JavaScript. For a deeper walk-through of each metric, see Core Web Vitals for Shopify Liquid themes.
Which apps should I remove first?
Remove apps that do one small visible job, since those are the easiest to replace with a theme section. Common examples are announcement bars, countdown timers, sticky add-to-cart buttons, size charts, simple pop-ups and color swatches. Each of these can be a Liquid section or a few lines of CSS.
Keep apps that do work the theme cannot do, such as payments, subscriptions, reviews with moderation, and email. For each remaining app, open your browser's Network tab, filter by JavaScript, and check how many requests and how many kilobytes the app adds. Shopify's own Built for Shopify program requires listed apps not to reduce a store's Lighthouse performance score by more than ten points, so an app that is not in that program has no such guarantee.
| App type | Replace with | Caveat | |---|---|---| | Announcement bar | Theme section | None | | Color swatches | Linked-product swatches in Liquid (how) | Needs one product per color | | Size chart | Page or metaobject rendered in a modal | Needs content upkeep | | Sticky add-to-cart | Theme section plus CSS | Test on mobile | | Landing-page builder | Custom Liquid sections | Needs a developer | | Chat widget | Keep, but load it after the page | Load on click or after a delay |
How do I uninstall an app without leaving junk in my theme?
Duplicate your live theme first, then uninstall the app, then search the duplicate for the app's name. Shopify's documentation says uninstalling apps often leaves code edits, which it calls ghost code, behind in the theme, and that this can cause quality and performance issues.
Search the theme code editor for the app's name, for render calls to its snippets, and for <script> tags that point at its domain. Delete what is clearly the app's, check the preview on the home, collection, product and cart pages, then publish the duplicate. Apps built with theme app extensions do not edit theme code, so they tend to leave nothing behind, but older apps often do.
How do I fix a slow hero image on Shopify?
Load the first-screen image eagerly, mark it as high priority, and use Shopify's image_tag filter. Shopify's performance documentation says never to lazy-load the LCP image, because loading="lazy" deprioritizes it and delays the download until after the browser runs an IntersectionObserver check.
{%- liquid
if section.index == 1
assign loading = 'eager'
assign priority = 'high'
else
assign loading = 'lazy'
assign priority = 'auto'
endif
-%}
{{ section.settings.image
| image_url: width: 1600
| image_tag:
loading: loading,
fetchpriority: priority,
widths: '800, 1200, 1600',
sizes: '100vw' }}This code uses section.index so only the first section on the page loads eagerly. The image_tag filter adds a srcset and the width and height attributes, which prevents layout shift. Avoid CSS background-image for the hero, since the browser's preload scanner finds an <img> earlier. Do not hide the hero behind a fade-in animation either, because animations delay the LCP event even after the image has loaded.
How do I lazy-load collection images correctly?
Load the first few product cards eagerly and the rest lazily. A collection page can render up to 50 products in its first section, and only the first row is visible without scrolling. Shopify's docs show using forloop.index for this.
{% for product in collection.products %}
{%- liquid
if forloop.index <= 4
assign image_loading = 'eager'
else
assign image_loading = 'lazy'
endif
-%}
{{ product.featured_image
| image_url: width: 400
| image_tag: loading: image_loading, widths: '200, 300, 400',
sizes: '(min-width: 1200px) calc(25vw - 2rem), (min-width: 768px) calc(33vw - 2rem), calc(50vw - 2rem)' }}
{% endfor %}If your theme uses a JavaScript lazy-loading library such as lazysizes, remove it. Those libraries replace src with data-src, which hides the image URL from the preload scanner until JavaScript runs. Put src back and add loading="lazy" to images below the first screen.
How do I defer scripts in a Shopify theme?
Add the defer attribute to your own non-critical scripts, and write the tag by hand because the script_tag filter does not support defer or async.
<script src="{{ 'theme-interactions.js' | asset_url }}" defer></script>Defer analytics, chat widgets and anything that is not needed for the first paint. Shopify's docs give a pattern for chat widgets: show a lightweight placeholder button and load the real widget on click, or after a delay such as ten seconds. Two things cannot be deferred: content_for_header, which Shopify injects, and A/B testing anti-flicker snippets, which must load synchronously by design.
How do fonts slow down a Shopify store?
A web font adds a download to the critical path, and a font swap can shift the layout. The fastest option is system fonts, which need no download and cause no swap. If your brand needs a custom font, self-host a WOFF2 file from your theme assets with font-display: swap.
@font-face {
font-family: "Brand Font";
src: url("brand-font.woff2") format("woff2");
font-display: swap;
}Add a fallback @font-face with size-adjust values measured for your font, so the swap does not move text. Shopify's docs point to tools such as Fontaine and Capsize for generating those values. Preload at most one or two resources, since overusing preload competes with the browser's own prioritization and can slow the page.
Why is my Shopify server response time slow?
Nested Liquid loops are the most common cause. Shopify's performance documentation says loops nested across products, variants or options grow quadratically with catalog size, so a theme that is fast on 10 products can be slow on 100.
Look for loops inside loops in your collection and product templates. Also avoid rendering every variant of a product, since product.variants returns at most 250 variants and Shopify recommends product.options_with_values for building option pickers instead. Move work out of the first render when you can, such as loading related products after the page paints.
What did I do on real stores?
I build storefront sections in Liquid instead of installing page-builder apps. Zaiqa uses a premium theme with almost all sections custom coded, and Naturabites uses custom Liquid sections for the landing, about and product pages. On BAOBAB, the color-swatch variant picker was custom coded rather than added through an app.
I have not published before-and-after speed numbers for these stores, and I will not invent them. See the Naturabites, Zaiqa and BAOBAB case studies for the work itself.
When should I get help?
Get help when the fix needs theme code edits you are not comfortable making, or when the audit shows apps that must be replaced with custom sections. A good first step is a list of installed apps with the JavaScript each one adds.
If you want an app and speed audit on your store, see my Shopify development services or get in touch with your store URL.
Related
- Do Shopify apps slow down your store?
- Shopify Core Web Vitals for Liquid themes
- Shopify parallax scrolling without hurting speed
- Shopify app bloat removal and speed service
Sources
- Shopify: Performance best practices for themes
- Shopify: Never lazy-load the LCP image
- Shopify: Defer render-blocking CSS and JavaScript
- Shopify: Remove or optimize apps causing render-blocking issues
- Shopify: Reduce CLS from font swapping
- Shopify: Migrate to theme app extensions
- Shopify: Built for Shopify requirements
Frequently asked questions
Can I speed up a Shopify store without installing a speed app?
Yes. The biggest wins are usually removing unused apps, loading the hero image correctly, deferring non-essential scripts and trimming fonts. All of these are theme changes, not app installs.
Which Core Web Vitals numbers should I aim for?
Google's 'good' thresholds are LCP of 2.5 seconds or less, INP of 200 milliseconds or less and CLS of 0.1 or less. Shopify's Built for Shopify requirements use the same CLS and INP figures.
Should I lazy-load every image on a Shopify store?
No. Lazy-load images below the first screen, and load the first-screen image eagerly. Shopify's performance docs call lazy-loading the main above-the-fold image one of the most common and damaging mistakes in themes.
Does uninstalling an app remove all of its code from my theme?
Not always. Shopify's developer documentation says uninstalling apps often leaves code edits, called ghost code, behind in the theme. Search your theme files for the app's name after you uninstall.
Can I defer every script on my store?
No. Shopify injects content_for_header and it cannot be deferred. You can defer your own theme scripts, analytics and chat widgets.
Store loading slowly?
I fix Shopify performance by hand — images, scripts, app bloat, theme code — without installing another app to fix the apps. Send me your store URL and I'll tell you what is actually costing you.


