If Shopify Page Speed Says Your LCP Is a Heading, Stop Fixing Images
When shopify page speed scores keep failing after image fixes, your LCP element might be a heading. Here is why that changes which fix path works.

A merchant posted on the Shopify Community in mid-2024 with a question that is still buried in the archives, unresolved. Their mobile shopify page speed score was stuck at 72. The Largest Contentful Paint entry read 3,150 ms. They had compressed everything they could compress. They had tested with and without the emoji in the headline. And then, scrolling through the Diagnostics panel, they noticed something odd: the LCP element identified by Google was an H2 heading. Just the text of a page title. They wrote one line that keeps surfacing in Shopify search results two years later: it should not take that long to load.
They were right about one thing. Text does not have a download. The browser already has the bytes by the time it is deciding what to render. The reason it still takes 3,150 ms to paint is almost never fixable with the standard advice.
Quick take: every "fix shopify page speed" article you have Googled is written for merchants whose LCP element is a hero image. If your LCP element is a heading, those fixes work on the wrong resource and your score will not move. The fix path for text LCP runs through render-blocking resources and font loading, not image optimization.
The standard advice is written for the wrong page
Open any top-ranked article titled some variant of "how to improve shopify page speed." Scan the list. Compress and resize your hero image. Add fetchpriority="high" to the first image. Change loading="lazy" to loading="eager" on the LCP banner. Preload the hero. Serve WebP.
Every one of those steps targets an image. On a store where the hero image is the LCP element, which is most Shopify stores, the advice is correct and roughly complete. The problem is that it has leaked into every "my shopify page speed is 42, what do I do" conversation on Reddit, in the Shopify Community, and in agency pitch decks, as if it were universal.
It is not universal. On a non-trivial slice of Shopify stores I have audited, the LCP element reported in PageSpeed Insights is not the hero image. It is a heading. H1 on some themes, H2 on others. Occasionally the first paragraph of body copy below the hero. The merchants in these threads applied the standard image fixes and watched their LCP sit there. One r/shopify post titled "PageSpeed insights Nightmare - LCP Issues with H1" spent the first half of its comment chain getting image-optimization replies before anyone noticed the element type.
Why a heading becomes the LCP element
Chrome picks the LCP element by rendered area, not by element type. The hero image is usually the biggest painted thing on the page and wins by default. On a Shopify store, two patterns routinely knock it out of the running.
The first is lazy loading. Most Shopify themes ship with loading="lazy" set globally, including on the hero. A lazy-loaded image is excluded from LCP candidacy entirely. Chrome does not consider it, so the browser scans for the next-largest painted element. On themes with a bold H1 or H2 sized at 36 pixels or larger, that heading wins.
The second is a third-party lazy-loading library like lozad.js or lazysizes applied globally. These libraries override the native loading="eager" attribute you may have added by hand. The hero image still looks eager in the HTML, but the library intercepts it on load. One October 2025 Shopify Community thread documented 2,800 ms of LCP where the fix was removing lozad.js and nothing else.
Add an opacity animation to the heading and the diagnosis gets stranger. The W3C spec for Largest Contentful Paint excludes any element with opacity: 0 at its initial frame. A hero heading that fades in via a CSS transition starting at opacity zero is excluded too. A dev.to case study from April 2026 documented a store with 72 ms TTFB where the H1 was in the DOM from first parse but did not register as LCP until the AOS reveal library fired, six seconds later. The actual measured LCP element in that case was a smaller paragraph that had the misfortune of being visible immediately.
Image fixes cannot help you here
Text does not have a resource load phase. There is no file to compress, no CDN to tune, no preload link that will make an H2 arrive faster, because the bytes for the heading are already in the HTML that the browser has fully parsed.
What text has is a render delay. The browser has the bytes. It has not yet painted them. Something is holding the main thread or blocking the paint. On a Shopify store, that something is almost always one of four things.
- Render-blocking CSS in the document head. Theme stylesheets, app stylesheets, and often one or two orphaned stylesheet links left behind by apps the merchant uninstalled months ago. Each one has to download and parse before the browser will paint anything.
- Render-blocking JavaScript. App injections via
content_for_header, tracking scripts, chat widgets. Deferring them helps less than most tutorials claim. A Shopify Community expert pointed out back in 2023 that deferred scripts still take priority over paint. - A web font that is loading with
font-display: blockor the default behavior. The browser holds text rendering until the font is available. If you are on a store with a large or custom font, this alone can add a second or two. One documented case had a 16 MB font file carrying embedded icon glyphs. Font subsetting and WOFF2 conversion are the fixes. - An anti-flicker snippet from Optimizely, AB Tasty, or Adobe Target. These apply
body { opacity: 0 }on page load and release it only when the testing platform decides on a variant. Shopify's own developer documentation says these snippets "commonly add 2 or more seconds to FCP" and directly hurt LCP. If no test is actively running, remove the snippet.
I missed the anti-flicker case the first few times I ran into it. The snippet is usually installed by a marketing or CRO team, not the merchant, and it does not appear in the Shopify app list. I spent an afternoon last year staring at a merchant's LCP phase breakdown before I thought to search the rendered HTML for async-hide.
The one case where the image advice still applies
Sometimes the correct move on a text-LCP store is to force the hero image back into LCP candidacy. Remove loading="lazy" from the hero. Add fetchpriority="high". If a well-optimized hero image can paint faster than the next-largest text element once you have fixed the obvious render-blockers, then image LCP will be faster than text LCP was, and you are back in territory the standard playbook actually covers.
The counter-argument is worth stating fairly. There is a reading of this that says image LCP is always preferable, because an image has one tangible lever (file size) and text has none. That reading holds exactly when the render delay on the page is low. If the main thread is pinned by app scripts for hundreds of milliseconds, forcing the hero image back into candidacy just produces a slow image LCP instead of a slow text LCP. The underlying problem is still the main thread.
If you have been through this cycle on a store you are responsible for and still cannot tell whether to chase the image or the render blockers first, the first 15 minutes with a help1 expert is free and that is usually enough to decide. If you want the companion read on the LCP phase breakdown PageSpeed Insights hides inside Diagnostics, that is covered in The Shopify LCP Render Delay Your Image Fixes Can't Move.
Where the shopify page speed conversation has to change
The reason this persists is that nobody labels their advice by element type. Every article says "fix your shopify page speed" and jumps straight to image compression. The merchant with the H2 LCP reads it, applies it, sees no change, and either blames themselves or blames Shopify. Both are wrong. The advice was wrong for them, specifically, from the first sentence.
So the honest short answer, before anyone types another sentence of shopify page speed advice: ask what the LCP element is. If PageSpeed Insights reports a text node, the image-focused toolbox is noise for your page. If it reports an image, the toolbox is appropriate. The merchant is not misreading. The articles are indifferent to which page they are describing.
If you open PSI on your own store right now and read the LCP element line, which one does it show you, and are you about to spend the next hour on the right fix or the wrong one?
Still stuck? Talk to an expert.
Our vetted Shopify experts can fix this issue for you in a live session. $39 per session. Your first 15 minutes are free.