Is there a problem that needs an urgent fix?Urgent fix?Get emergency help →
Blog

Practical Magento 2 guides on upgrades, security, speed and migration, written by the MageBooster team.

Core Web Vitals for Magento 2: A Practical INP and LCP Checklist

Current LCP, INP and CLS thresholds, how to measure them, and a prioritized checklist of Magento-specific fixes for faster stores.
Magento consultancy

In short

A Magento 2 page passes Core Web Vitals when the 75th percentile of real visits has LCP at or under 2.5 seconds, INP at or under 200 ms and CLS at or under 0.1. On most stores the biggest wins come from a working full page cache, a fast LCP image, less JavaScript on the main thread and tighter control of third-party tags. Measure with field data first, then fix in the order below.

Core Web Vitals are Google’s three user-experience metrics for loading, interactivity and visual stability. For a Magento 2 or Adobe Commerce store they are also a useful health check: a poor score usually points to the same problems that hurt conversion, such as slow uncached pages, heavy RequireJS bundles and tag managers that block the main thread.

This guide covers the current thresholds, how to measure them properly, and the Magento-specific fixes that tend to move the numbers.

The current thresholds

Google evaluates each metric at the 75th percentile of page loads, segmented by mobile and desktop. Since March 12, 2024, Interaction to Next Paint (INP) has replaced First Input Delay (FID) as the responsiveness metric.

MetricMeasuresGoodNeeds improvementPoor
LCP (Largest Contentful Paint)Loading≤ 2.5 s2.5 s to 4.0 s> 4.0 s
INP (Interaction to Next Paint)Responsiveness≤ 200 ms200 ms to 500 ms> 500 ms
CLS (Cumulative Layout Shift)Visual stability≤ 0.10.1 to 0.25> 0.25

PageSpeed Insights reports a page or origin as passing when the 75th percentile of all three metrics is Good. If there is not enough INP data, the assessment can pass on LCP and CLS alone.

How to measure: field data first, lab data second

CrUX and PageSpeed Insights

The Chrome User Experience Report (CrUX) collects real-user data from eligible Chrome users. The CrUX API serves a 28-day rolling average that updates daily, and PageSpeed Insights shows the same field data for the previous 28-day period. Low-traffic URLs may only show origin-level data, or none at all.

A fix you deploy today takes weeks to fully show up in CrUX. Search Console also groups similar URLs, so one slow template can drag down thousands of URLs. Check results per template: home, category, product, cart, checkout and search.

Lighthouse and lab tools

Lighthouse in PageSpeed Insights or Chrome DevTools gives you a repeatable lab run with diagnostics. Use it to find causes, such as render-blocking resources or long tasks. Do not treat a lab score as your Core Web Vitals result. Lab runs cannot measure INP, because INP needs real user interactions.

Real user monitoring (RUM)

CrUX tells you that a template is slow. RUM tells you why, on which devices and on which interactions. Google’s open-source web-vitals JavaScript library reports LCP, INP and CLS from real sessions, including attribution data such as the LCP element and the slowest interaction target. Send those events to your analytics tool or a RUM service and segment by page type.

import { onLCP, onINP, onCLS } from 'web-vitals/attribution';

function send(metric) {
  navigator.sendBeacon('/rum', JSON.stringify({
    name: metric.name,
    value: metric.value,
    pageType: document.body.className, // Magento adds page-type classes to body
    attribution: metric.attribution
  }));
}

onLCP(send);
onINP(send);
onCLS(send);

Magento-specific fixes

1. Server response time and full page cache

Time to First Byte is the first part of LCP. Google’s LCP guidance breaks LCP into four subparts (TTFB, resource load delay, resource load duration and element render delay) and suggests TTFB should be roughly 40% of the total. An uncached Magento page can spend most of the LCP budget before the browser receives any HTML.

Adobe’s configuration best practices recommend Varnish as the production page cache. Enable it and tell Magento where to send purges:

bin/magento config:set --scope=default --scope-code=0 system/full_page_cache/caching_application 2
bin/magento setup:config:set --http-cache-hosts=127.0.0.1:6081

Then export the VCL from Stores > Settings > Configuration > Advanced > System > Full Page Cache. After that, check your hit rate. Common reasons for misses on Magento include blocks marked cacheable="false" in layout XML (which makes the whole page uncacheable), tracking parameters that fragment the cache, and customer-specific content rendered server side instead of through private content sections.

# Find layout XML that disables FPC for a whole page
grep -rn 'cacheable="false"' app/code app/design vendor/*/*/view/frontend/layout

Adobe also recommends setting indexers to Update on Schedule for performance, so catalog saves do not trigger heavy reindexing during traffic:

bin/magento indexer:set-mode schedule
bin/magento indexer:status

Note that Adobe states the Customer Grid index must stay on Update on Save.

2. Cache warming

Every deploy or full cache flush sends the next visitors to PHP. Warm the most valuable URLs right after deploy: home, top categories, top products and key CMS pages. On Adobe Commerce on cloud infrastructure, the WARM_UP_PAGES and WARM_UP_CONCURRENCY post-deploy variables handle this. On self-hosted stacks, a simple crawler over a sitemap works (this example uses GNU grep):

curl -s https://www.example.com/sitemap.xml \
  | grep -oP '(?<=<loc>)[^<]+' \
  | head -500 \
  | xargs -P 4 -I{} curl -s -o /dev/null -w "%{http_code} %{time_starttransfer} {}\n" {}

Also avoid full cache flushes as a routine. Clean specific cache types and rely on tag-based invalidation where possible.

3. The LCP image

On product and category pages the LCP element is usually the main product image or a hero banner. Google’s guidance is direct: never lazy-load the LCP image, and consider fetchpriority="high" on it, while keeping high priority to one or two images at most.

  • Remove loading="lazy" from the first gallery image and from above-the-fold banners.
  • On Luma, the product gallery initializes through JavaScript after the placeholder image loads. Check in DevTools which element is reported as LCP, and make sure that image is requested early in the HTML (or preloaded) rather than discovered by a script.
  • Serve correctly sized images. Magento’s image cache resizes product images per view; make sure your view.xml sizes match the real display size.
  • Use modern formats. On Adobe Commerce on cloud infrastructure, Fastly Image Optimization can convert images to WebP automatically. On other hosting, use a CDN image service or a vetted extension.
  • Do lazy-load images below the fold, such as product grids beyond the first row.

4. JavaScript: bundling and minification vs Hyvä

INP problems on Magento usually come from the main thread being busy. Luma loads many RequireJS and Knockout modules, and extensions add more.

Adobe’s own documentation is cautious about built-in options. It describes native bundling as loading all bundles even when a page needs only a few, recommends third-party tools such as r.js for bundling and minification, notes that HTTP/2 can be a good alternative to bundling, and advises against the deprecated JS and CSS merge settings. Minification is safe to enable:

bin/magento config:set --lock-config dev/js/minify_files 1
bin/magento config:set --lock-config dev/css/minify_files 1

For Luma-based themes, page-type bundles (common, catalog, checkout) built with r.js are the documented advanced route.

The other route is replacing the frontend. Hyvä Theme rebuilds the storefront with a much smaller JavaScript footprint using Alpine.js and Tailwind CSS. Since November 10, 2025, the Hyvä Theme is free and open source (OSL3 + AFL3); Hyvä Checkout and its other commercial products remain paid. Hyvä is a project, not a setting: every frontend extension needs a Hyvä-compatible version or a rewrite, so audit your extension list first.

5. Third-party scripts

Tag managers, chat widgets, review widgets, A/B testing tools and personalization scripts are frequent causes of poor INP and CLS. Run through each one:

  • Remove tags nobody uses. Audit the tag manager container at least quarterly.
  • Load non-essential widgets after user interaction or idle time rather than on page load.
  • Reserve space for anything that renders late (review stars, banners, consent bars) to avoid layout shifts.
  • Break up long tasks in your own code. Google defines a long task as anything over 50 ms and recommends yielding to the main thread with scheduler.yield(), falling back to setTimeout where unsupported.

6. Layout stability

Google lists images without dimensions, ads and embeds, web fonts and dynamically injected content as the main causes of layout shift. In Magento, look at product image placeholders, swatch rendering, minicart and customer-section updates, and promo bars injected by extensions. Set explicit width and height (or aspect-ratio) on images and keep containers a fixed height while content loads.

Prioritized checklist

  1. Pull CrUX and Search Console data per template. Identify which metric fails and where.
  2. Add RUM with the web-vitals library to get the LCP element and slowest interactions.
  3. Confirm Varnish (or Fastly) is serving cache hits on home, category and product pages. Remove stray cacheable="false" blocks.
  4. Set indexers to Update on Schedule and stop routine full cache flushes.
  5. Warm top URLs after every deploy.
  6. Fix the LCP image: no lazy loading, fetchpriority="high", correct size, WebP where possible.
  7. Enable JS and CSS minification; disable JS merging; test page-type bundling or HTTP/2 without bundling.
  8. Audit and defer third-party scripts.
  9. Reserve space for late-loading elements to bring CLS under 0.1.
  10. If INP stays poor on Luma after the steps above, scope a Hyvä migration.
  11. Re-measure after 28 days of field data.

Frequently asked questions

Is FID still a Core Web Vital?

No. INP replaced FID as a Core Web Vital on March 12, 2024. If an old report or tool still shows FID, use INP instead.

Why does PageSpeed Insights show a good score but Search Console says my pages fail?

The performance score comes from a single Lighthouse lab run. Search Console uses CrUX field data from real Chrome users over 28 days. Field data wins for Core Web Vitals, and it includes slow devices and networks that a lab run may not reflect.

Do I need Hyvä to pass Core Web Vitals on Magento?

Not necessarily. Many Luma stores improve substantially with caching, image and script work. Hyvä becomes worth evaluating when INP remains poor because of the volume of JavaScript the Luma frontend and its extensions load.

How long until fixes show up?

CrUX uses a 28-day rolling window, so expect gradual improvement over about four weeks after deploying. RUM data shows the effect immediately.

Failing Core Web Vitals on Magento?

We audit caching, frontend and third-party scripts and give you a prioritized fix plan for your store.

Book a performance audit

Sources

Free Site Audit

Send your store details. We check speed, security and extensions, then reply with three quick wins within 3 working days.

Let's talk

Get a quote

Tell us about your store and we’ll reply within one working day. Prefer to chat? Say hello from WhatsApp