Back to Course|Frontend Engineer Interviews: React, System Design & Web Performance Mastery
Lab

Performance Audit & Fix

25 min
Intermediate
3 Free Attempts

Instructions

Objective

You are given a React application with severe performance problems. Your task is to identify and fix issues affecting all three Core Web Vitals: LCP, CLS, and INP.

The Problem Application

The application is a product listing page with the following deliberate performance issues:

LCP Issues

  • Hero image is a 2MB unoptimized PNG with no width/height attributes
  • Three render-blocking Google Fonts loaded via <link> in the head
  • All CSS is in a single large bundle (no critical CSS extraction)
  • No preloading of the hero image

CLS Issues

  • Product images have no width/height or aspect-ratio set
  • A promotional banner is dynamically injected after 2 seconds
  • Web font swap causes visible layout shift (no size-adjust)
  • An ad placeholder has no reserved height

INP Issues

  • Product filtering runs a synchronous loop over 10,000 items on every keystroke
  • Sort function blocks the main thread for 300ms+
  • Click handlers trigger synchronous layout recalculations (forced reflow)

Your Tasks

Task 1: Fix LCP (35 points)

  • Convert the hero image to use <picture> with AVIF/WebP sources and a JPG fallback
  • Add width, height, and fetchpriority="high" to the hero image
  • Add <link rel="preload"> for the hero image
  • Use font-display: swap for custom fonts and preload the primary font file
  • Extract critical above-the-fold CSS into an inline <style> block

Task 2: Fix CLS (30 points)

  • Add width and height attributes (or CSS aspect-ratio) to all product images
  • Reserve space for the promotional banner using min-height before it loads
  • Add size-adjust, ascent-override, and descent-override to the @font-face rule to minimize font swap shift
  • Set a fixed min-height on the ad placeholder container

Task 3: Fix INP (35 points)

  • Debounce the search/filter input with a 300ms delay
  • Break the product filtering into chunks using setTimeout(fn, 0) or scheduler.yield() to yield to the main thread
  • Move the sort comparison into a Web Worker or break it into yielding chunks
  • Replace forced reflow patterns (reading offsetHeight after writing styles) with requestAnimationFrame batching

Starter Code

The starter code below represents the broken application. Fix the issues in place.

Evaluation Criteria

Your submission will be evaluated on whether the fixes correctly address each Core Web Vital issue. You do not need to run Lighthouse — the grading rubric checks your code for the specific optimization patterns.

Grading Rubric

LCP Fix — Hero image uses <picture> with AVIF/WebP sources, has width/height and fetchpriority='high', a <link rel='preload'> is added, fonts use font-display: swap and primary font is preloaded, critical CSS is inlined35 points
CLS Fix — Product images have width/height or aspect-ratio, promo banner container has min-height to reserve space even before content loads, @font-face includes size-adjust/ascent-override/descent-override, ad placeholder has a fixed min-height30 points
INP Fix — Search input is debounced (300ms), product filtering uses chunked processing with setTimeout or scheduler.yield to avoid blocking, forced reflow is eliminated by using requestAnimationFrame for style reads/writes35 points

Your Solution

Use any programming language
3 free attempts remaining