Measuring and Improving Core Web Vitals in a Next.js Production App
This article explains how to measure Core Web Vitals (LCP, INP, CLS) in a real Next.js production environment and apply specific, verified optimization techniques. It does not claim performance improvements without measurement — measurement is a prerequisite.
Important note on measurement
Core Web Vitals must be measured with real user data or verified synthetic measurement. Lighthouse scores and synthetic tests are useful for debugging but do not represent real user experience. Before making any optimization claim, confirm measurements using the web-vitals library or official web.dev/measure tools in a real environment.
Per official Google documentation (developers.google.com/search/docs/appearance/core-web-vitals):
- LCP = Largest Contentful Paint (loading performance)
- INP = Interaction to Next Paint (interactivity, replacing FID)
- CLS = Cumulative Layout Shift (visual stability)
These metrics are measured in real user conditions (device, network, region). Synthetic measurements are a starting point, not proof of improvement.
Problem
A developer needs to improve production performance but does not know which metric (LCP, INP, CLS) requires attention, how to measure it accurately, or which Next.js optimization applies to which metric.
Measurement before optimization
Before applying any optimization:
- Measure real Core Web Vitals using the
web-vitalslibrary orweb.dev/measure. - Record the measurement environment (device, connection, region) — results vary across conditions.
- Identify which metric is below the recommended threshold.
- Confirm the measurement is repeatable. A single measurement is not sufficient evidence for an optimization claim.
This sequence prevents applying the wrong optimization (e.g., improving LCP when INP is the actual problem) and prevents claiming improvements that are not verified.
Working approach by metric
Largest Contentful Paint (LCP)
LCP measures loading performance — how quickly the largest visible content element appears.
Concrete optimization steps (verified by official Next.js documentation, nextjs.org/docs/app/building-your-application/optimizing):
- Use the
next/imagecomponent withpriority={true}for the LCP image. - Confirm font loading uses
next/fontoptimization rather than external CSS that blocks rendering. - Confirm server-side rendering delivers the initial content quickly; avoid slow database queries or external API calls that delay the initial response.
Interaction to Next Paint (INP)
INP measures interactivity — how quickly the page responds to user interactions (clicks, taps, keyboard input).
Concrete optimization steps:
- Reduce JavaScript execution time by using dynamic imports (
import()) withssr={false}for non-critical components. - Confirm the hydration overhead is minimal; avoid unnecessary client-side JavaScript for static content.
- Confirm event handlers are efficient; avoid blocking the main thread with synchronous operations.
Cumulative Layout Shift (CLS)
CLS measures visual stability — whether elements shift unexpectedly as the page loads.
Concrete optimization steps:
- Reserve dimensions for images using
widthandheight(oraspect-ratio) before the image loads. - Confirm no dynamic content (ads, embedded media, or late-loaded elements) inserts above existing content without reserved space.
- Confirm the layout is stable after hydration; client-side changes should not shift visible elements.
Verification procedure
After applying any optimization:
- Confirm the optimization is present in the deployed build (not only locally).
- Run the measurement again in the same environment (device, connection, region) where the previous measurement was recorded.
- Confirm the metric has changed (improved or worsened) — not just that the measurement occurred.
- Document the measurement context and results. Do not claim improvements without documented measurements.
- Confirm no new errors appear in Vercel function logs or browser console.
Caveats
- Optimization results depend on measurement context. A change that improves LCP on desktop may not improve it on mobile, or vice versa.
- Synthetic tests (Lighthouse) and real user data (field measurements) can show different results. Both are useful; neither replaces the other.
- Performance claims must reference the measurement method and context. A claim without measurement evidence is not verifiable.
Related articles
react-server-actions— component-level patterns that affect interaction timing and may influence INP.typescript-strict-nextjs— type-safe configuration that prevents runtime errors affecting performance.deploy-nextjs-vercel-env— environment differences that affect production performance measurement.