System-design · Core Web Vitals

Core Web Vitals Interview Questions
With Answers & Code Examples

6 carefully curated Core Web Vitals interview questions with working code examples and real interview gotchas.

Practice Interactively →← All Categories
6 questions2 beginner3 core1 advanced
Q1Beginner

What are the three Core Web Vitals and what does each measure?

💡 Hint: LCP (loading), INP (interactivity), CLS (visual stability) — Google's user-experience signals that affect search ranking

Core Web Vitals are Google's three standardized metrics for measuring real-world user experience, incorporated into Google's Search ranking since 2021.

LCP — Largest Contentful Paint

  • Measures: how long it takes to render the largest visible image or text block in the viewport.
  • What users feel: "How fast does the main content appear?"
  • Good: ≤ 2.5s | Needs improvement: ≤ 4s | Poor: > 4s

INP — Interaction to Next Paint (replaced FID in 2024)

  • Measures: the latency of the worst interaction (click, keypress, tap) across the entire page visit.
  • What users feel: "Does the page respond quickly when I interact?"
  • Good: ≤ 200ms | Needs improvement: ≤ 500ms | Poor: > 500ms

CLS — Cumulative Layout Shift

  • Measures: unexpected visual shifts of page elements during the entire lifetime of the page.
  • What users feel: "Do things jump around as I try to click?"
  • Good: ≤ 0.1 | Needs improvement: ≤ 0.25 | Poor: > 0.25
Practice this question →
Q2Core

What are the most common causes of poor LCP and how do you fix them?

💡 Hint: Slow TTFB, render-blocking resources, unoptimized hero image, lazy-loaded LCP element

LCP is the time to render the largest above-the-fold element — usually a hero image, banner, or large text block.

Common causes and fixes:

1. Slow server response (TTFB)

  • Fix: CDN, edge SSR, server-side caching, faster DB queries.

2. Render-blocking resources

  • CSS files in <head> block rendering until fully downloaded. Fix: inline critical CSS, defer non-critical CSS.

3. LCP image not preloaded

  • The browser discovers the hero image late (after parsing CSS and JS). Fix: add <link rel="preload" as="image"> in <head> or use Next.js <Image priority>.

4. LCP image is lazy-loaded

  • A common mistake: adding loading="lazy" to the hero image. Browser deliberately delays it. Fix: remove lazy from above-fold images.

5. Unoptimized image

  • Large JPEG served at full resolution. Fix: WebP/AVIF, correct srcset sizing, compression.

6. Web fonts blocking text LCP

  • Text is the LCP element but font isn't loaded. Fix: font-display: swap, preload critical fonts.
Practice this question →
Q3Beginner

What causes CLS (Cumulative Layout Shift) and how do you fix it?

💡 Hint: Elements without dimensions, late-injected content, web fonts causing FOUT, embeds without aspect-ratio containers

CLS measures unexpected visual shifts. A score above 0.1 hurts both UX and SEO ranking.

Common causes and fixes:

1. Images without dimensions

<!-- ❌ Browser reserves no space — content shifts when image loads -->
<img src="hero.jpg" />

<!-- ✅ Browser reserves exact space upfront -->
<img src="hero.jpg" width="1200" height="600" />

2. Dynamically injected content above existing content

  • Banners, cookie notices, ads injected above page content push everything down. Fix: reserve space with a fixed-height placeholder, or inject below the fold.

3. Web fonts causing FOUT/FOIT

  • Text re-renders when the web font loads, causing a shift if the metrics differ. Fix: font-display: optional or size-adjust CSS to match fallback font metrics.

4. Embeds without aspect-ratio containers

<!-- ✅ Reserve 16:9 space for video -->
<div style={{ aspectRatio: '16/9' }}>
  <iframe src="..." />
</div>

5. Animations that trigger layout

  • Animating width, height, top, left triggers layout and can contribute to CLS. Fix: use transform: translate() instead.
Practice this question →
Q4Core

What is INP (Interaction to Next Paint) and how does it differ from FID?

💡 Hint: FID measured only the first interaction's input delay; INP measures the worst interaction delay across the full page visit

FID (First Input Delay) — measured the delay between the first user interaction and when the browser could begin processing it. Only the first interaction counted.

INP (Interaction to Next Paint) — replaced FID in March 2024. Measures the full duration of the worst interaction across the entire page visit: input delay + processing time + presentation delay.

Why INP is a better metric:

  • FID missed slow interactions that occurred after the first one (e.g., a slow button click on a long session).
  • FID only measured input delay, not how long the response took to render — an interaction could start instantly but still feel sluggish.
  • INP captures the full user experience of responsiveness throughout the session.

How to improve INP:

  • Break up long tasks — tasks over 50ms block the main thread. Use scheduler.yield() or setTimeout(0) to yield between chunks.
  • Avoid heavy synchronous work on interaction — defer non-critical updates, use startTransition in React 18 to mark non-urgent renders.
  • Reduce main thread blocking — move heavy computation to Web Workers.
Practice this question →
Q5Core

How do you measure Core Web Vitals in a production React app?

💡 Hint: web-vitals library for field data; Lighthouse and PageSpeed Insights for lab data; Next.js has built-in instrumentation

Core Web Vitals should be measured in the field (real users) not just in lab conditions (Lighthouse), since real network/device conditions differ significantly.

1. web-vitals library

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

onLCP(console.log);
onINP(console.log);
onCLS(console.log);

Call your analytics endpoint inside these callbacks to collect real-user data.

2. Next.js built-in

// pages/_app.tsx or app/layout.tsx
export function reportWebVitals(metric: NextWebVitalsMetric) {
  console.log(metric); // { name: 'LCP', value: 1234, ... }
  // send to your analytics
}

3. Chrome User Experience Report (CrUX) — real-field data from Chrome users, aggregated by URL. Accessible via PageSpeed Insights API or Google Search Console's Core Web Vitals report.

4. Lab tools for debugging

  • Lighthouse (Chrome DevTools) — simulated conditions; identifies specific elements.
  • PageSpeed Insights — combines lab + field data.
  • WebPageTest — detailed waterfall and filmstrip views.
Practice this question →
Q6Advanced

What techniques reduce INP on a React app with expensive renders?

💡 Hint: React 18 startTransition, scheduler.yield, virtualization, memoization, Web Workers for off-thread computation

INP > 200ms usually means the main thread is too busy to respond to user input quickly. React-specific techniques:

1. React 18 startTransition

import { startTransition } from 'react';

// Mark search results update as non-urgent
// Input stays responsive; results update when idle
const handleInput = (e) => {
  setInputValue(e.target.value); // urgent — renders immediately
  startTransition(() => {
    setSearchResults(search(e.target.value)); // deferred
  });
};

2. useDeferredValue — defers a value update until the browser is idle; downstream components that use the deferred value re-render lazily.

3. Virtualize long lists — react-virtual, @tanstack/virtual. Rendering 1000 list items causes a massive layout. Render only what's in the viewport.

4. Memoization — React.memo, useMemo, useCallback to skip re-rendering subtrees that didn't change.

5. Web Workers — move expensive computation (search indexing, data transformation) off the main thread entirely.

6. scheduler.yield() — yield the main thread mid-loop to let interactions interrupt long synchronous tasks.

Practice this question →

Other System-design Interview Topics

Rendering Strategies →Core JS →Type System →React Fundamentals →Functions →Microfrontends →Generics →Async JS →Hooks →Objects →Monorepo →Arrays →'this' Keyword →Utility Types →Error Handling →Modern JS →Bundle Optimization →Performance →DOM & Events →State Management →Classes & OOP →Caching Strategies →Component Patterns →Advanced Types →Authentication →React Router →Forms →Advanced Patterns →Frontend Security →Concurrent React →Server Components →Testing →Ecosystem →Network Optimization →Browser APIs →

Ready to practice Core Web Vitals?

Get AI feedback on your answers, predict code output, and fix real bugs.

Start Free Practice →