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. MemoizationReact.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 StrategiesCore JSType SystemReact FundamentalsFunctionsMicrofrontendsGenericsAsync JSHooksObjectsMonorepoArrays'this' KeywordUtility TypesError HandlingModern JSBundle OptimizationPerformanceDOM & EventsState ManagementClasses & OOPCaching StrategiesComponent PatternsAdvanced TypesAuthenticationReact RouterFormsAdvanced PatternsFrontend SecurityConcurrent ReactServer ComponentsTestingEcosystemNetwork OptimizationBrowser APIs

Ready to practice Core Web Vitals?

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

Start Free Practice →