Common Hydrogen mistakes that quietly tank your Core Web Vitals

Hydrogen gives you a fast foundation, but the same handful of mistakes keep dragging storefronts back down to the scores people were trying to escape from. Sharing this as a checklist - hopefully it saves someone a few days of Lighthouse archaeology.

Quick context on why this matters: Google’s Core Web Vitals (LCP, CLS, INP) affect both search ranking and conversion. A custom Hydrogen build can outperform a Liquid theme, but nothing about Hydrogen makes that automatic. You can absolutely build a slow Hydrogen store.

1. Overfetching in your route loaders

The most common one. A product page loader that requests 60 fields, full metafield trees, and 4 levels of nested collections when the page renders maybe a dozen values. Every extra field adds to the Storefront API response time, and your loader blocks the initial render. Audit your GraphQL queries against what the page actually displays — it’s tedious once and pays off forever.

2. Not deferring below-the-fold data

Related to #1: if reviews, recommendations, or recently-viewed sections are awaited in the main loader, your LCP waits for data nobody can see yet. Use deferred data (defer in your loader, Await/Suspense in the component) so critical content streams first and the rest fills in. One of the biggest single wins available in Hydrogen, and a lot of projects never use it.

3. Skipping Hydrogen’s caching strategies

Hydrogen ships with cache strategies (CacheLong, CacheShort, custom stale-while-revalidate configs) for sub-request caching. If every request hits the Storefront API fresh, you’re paying full API latency on every page view for data that changes rarely — nav menus, shop metadata, collection lists. Match the cache strategy to how often the data actually changes.

4. Raw <img> tags instead of the optimized Image component

Two problems at once: full-size images shipped to mobile devices (LCP), and missing dimensions causing layout shift as images load (CLS). Use Hydrogen’s Image component with proper sizes/aspectRatio so you get responsive srcsets from Shopify’s CDN and reserved layout space. Also: don’t lazy-load your hero image — the LCP element should load eagerly.

5. Third-party scripts loaded synchronously

The classic. Analytics, chat widgets, review platforms, TikTok/Meta pixels — each one added “real quick” by a different stakeholder. Loaded synchronously in the head, they block everything. Load them async/deferred, after hydration where possible, and periodically audit what’s actually still needed. A common single biggest improvement is simply removing a script nobody uses anymore.

6. Fonts causing layout shift

Self-host or preload your critical font files, set font-display deliberately, and consider metric-compatible fallback fonts so the swap doesn’t reflow the page. A hero headline that jumps 20px when the webfont lands is pure CLS you don’t need.

7. Above-the-fold carousels and injected banners

Announcement bars that mount after hydration, hero carousels that resize per slide, CLS from cookie banners - anything that appears or changes size after first paint above the fold hurts. Reserve the space in advance or render these server-side.

8. Shipping too much JavaScript, hydrating everything

Watch your bundle. Heavy client-side libraries for things that could be server-rendered, entire icon libraries imported for three icons, date libraries for one formatted date. Every KB of JS is parse/execute time on a mid-range phone, and INP suffers. Check what’s actually in your bundle before adding the next dependency.

9. Testing only in Lighthouse on your dev machine

Lab data on an M-series laptop over office wifi tells you very little. Check field data (CrUX / Search Console’s Core Web Vitals report) and test on a real mid-range Android over throttled network. The gap between lab and field is where most “but it’s fast for me” conversations end.

10. Optimizing once and never watching again

Scores drift. New app scripts get added, images stop going through review, a marketing pixel appears. Put CWV in something you look at monthly — Search Console is free and enough for most teams.

None of these are exotic. Most slow Hydrogen storefronts are some combination of #1, #4, and #5.

What’s been the biggest performance win (or most painful regression) on your Hydrogen builds? Curious whether other people’s top offenders match this list.

Hi @Weaverse
The point about deferring below-the-fold data is really useful. I’m curious how you decide what should stay in the initial loader versus what can safely be deferred, especially on product pages with reviews and recommendations. Do you usually measure the impact on LCP before and after deferring those requests?

One thing that can be easy to overlook is that performance often changes as the storefront grows.

A Hydrogen site may perform well initially, but additional analytics, tracking scripts, review widgets, chat tools, and other integrations can gradually increase the amount of JavaScript and network activity on the page.

I would also look beyond a single Lighthouse score. Checking LCP, CLS, and INP across real user data can help identify problems that don’t appear during a controlled local test.

For LCP, I’d pay particular attention to the main content and images being loaded above the fold. For CLS, fonts, images without defined dimensions, and dynamically changing elements are worth checking. For INP, excessive client-side JavaScript and third-party scripts can become important as the store becomes more interactive.

Regularly reviewing these areas after major theme or integration changes seems like a good way to catch regressions before they become noticeable to customers.

Hey @Weaverse

hope you’re doing well!

Me too! #1, #4, and #5 have been the biggest performance issues I’ve seen. Great checklist!

Hi @KynaatJohn Good question and yes, measuring before/after is the honest half of the answer, but the decision framework matters more, so let me give both.

The framework I use for what stays in the loader: one question - does the user need this to decide whether they’re in the right place? On a product page that’s a short list: title, price, primary image, availability, variant options. That’s your critical data. Everything else: reviews, recommendations, recently-viewed, even secondary gallery images’ metadata - is content the user reaches after orienting, which makes it deferrable by definition. A useful tell: if a section lives below the fold on mobile, it’s almost always safe to defer. Mobile-first framing keeps you honest here, because desktop viewports tempt you into calling too much “above the fold.”

Reviews are the interesting edge case, because the review summary (star rating, count) often sits right next to the title, top of the critical zone while the review list sits far below. The pattern that resolves it: split them. Rating summary in the critical query (it’s tiny), full review content deferred. Same logic applies to anything with a “teaser above, body below” shape.

One caution in the other direction: deferring isn’t free. Every deferred section needs a skeleton/fallback sized to its eventual content, or you’re just converting an LCP problem into a CLS problem as sections pop in. If you can’t predict a section’s height, that’s a design conversation before it’s a data one.

On measuring: before/after in lab (Lighthouse/WebPageTest with throttling) confirms the mechanism worked, you should see LCP move if the deferred requests were genuinely blocking. But the number that decides whether to keep the change is field data (CrUX / Search Console) over the following weeks, since lab conditions never match your real traffic’s devices. Lab to validate, field to verify, is the loop.

Curious what your product pages carry, is it the classic reviews + recommendations pair, or do you have heavier sections (3D, size guides, UGC) in the mix? The heavier the section, the more deferring pays.

That makes sense, especially the distinction between a review summary and the full review content. The point about deferring content without creating a CLS issue is also really useful, it’s easy to focus on improving LCP and accidentally introduce another performance problem.

I’m more involved with Shopify apps and merchant-side workflows than Hydrogen builds, so I was mainly interested in how you approach these decisions on real storefronts. The “lab to validate, field to verify” approach is a really good takeaway. Thank you for the detailed explanation!