Performance

Junior Questions

Junior
6

What are Core Web Vitals?

  • Core Web Vitals (CWV) are Google's set of metrics measuring real-world user experience. They are ranking signals in Google Search.
  • LCP (Largest Contentful Paint) — Loading performance. Target: ≤ 2.5s.
  • INP (Interaction to Next Paint) — Interactivity/responsiveness. Target: ≤ 200ms. Replaced FID in March 2024.
  • CLS (Cumulative Layout Shift) — Visual stability. Target: ≤ 0.1.
  • Measured from real users via Chrome User Experience Report (CrUX). Lab tools like Lighthouse show field data approximations.

What problems does this solve?

  • Core Web Vitals are the primary framework for web performance discussion — all 3 metrics and their thresholds are expected knowledge.
Junior
15

What is FCP and how does it differ from LCP?

  • First Contentful Paint (FCP) — Time until the first text or image (including background) is rendered. Includes loading indicators. Good: ≤ 1.8s.
  • LCP — Time until the largest meaningful content renders. More representative of perceived load.
  • FCP tells you when the page started rendering something; LCP tells you when the main content finished loading.
  • FCP is no longer a Core Web Vital but remains a useful diagnostic metric available in Lighthouse and CrUX.

What problems does this solve?

  • Distinguishing FCP from LCP shows you understand the performance metrics timeline, not just the CWV acronyms.
Junior
17

What is LCP and how do you improve it?

  • Largest Contentful Paint measures when the largest visible image or text block fully renders. Target: ≤ 2.5s. Poor: > 4s.
  • Typically the LCP element: Hero image, above-the-fold image, large heading text.
  • Improvements:
    • Reduce TTFB — use a CDN, optimise server response time.
    • Preload the LCP resource: <link rel="preload"> for hero images.
    • Use fetchpriority="high" on the LCP image.
    • Avoid lazy-loading the LCP image.
    • Optimise image formats (WebP, AVIF) and sizes (srcset).
    • Eliminate render-blocking CSS/JS that delays painting.

What problems does this solve?

  • LCP is the most impactful CWV for perceived loading speed — optimising it requires understanding the entire resource loading chain.
Junior
18

What is Lighthouse and how do you use it?

  • Lighthouse is an open-source automated tool by Google for measuring web page quality: Performance, Accessibility, Best Practices, SEO, PWA.
  • Performance score (0-100): Weighted average of FCP (10%), SI (10%), LCP (25%), TBT (30%), CLS (25%).
  • How to run: Chrome DevTools (Lighthouse tab), npx lighthouse, CI integration (Lighthouse CI).
  • Lab vs field: Lighthouse is a lab tool (controlled conditions). Real-world CWV data comes from CrUX (Chrome User Experience Report) in PageSpeed Insights.
  • Use Lighthouse to identify issues; use CrUX to understand real user impact.

What problems does this solve?

  • Lighthouse is the de facto performance auditing tool — knowing how to interpret and act on its results is a core frontend skill.
Junior
20

What is TTFB and how do you improve it?

  • Time to First Byte (TTFB) measures the time from the client's request to receiving the first byte of the response. Target: ≤ 800ms. Poorer TTFB is the biggest LCP contributor.
  • Causes of high TTFB: Slow server processing, uncached DB queries, no CDN, slow DNS resolution.
  • Improvements: Use a CDN (serve from edge). Cache responses. Optimise slow DB queries. Use edge compute / SSR caching. Reduce network round-trips.

What problems does this solve?

  • TTFB is the upstream root cause of poor LCP — fixing it benefits all other loading metrics.
Junior
23

What is code splitting and how do you implement it?

  • Code splitting breaks a large JavaScript bundle into smaller chunks that are loaded on demand rather than all upfront.
  • Route-based splitting: Load each route's code only when navigating to it. Supported natively by React Router, Vue Router, Next.js App Router.
  • Component-based: React.lazy(), defineAsyncComponent in Vue.
  • Dynamic import: import('./heavyLib') — webpack/Vite automatically creates a separate chunk.
  • Reduces initial bundle size, improving FCP and TTI. Over-splitting causes waterfall requests — balance granularity.

What problems does this solve?

  • Code splitting is the single most impactful bundle optimisation technique — understanding when and how to split is essential.
Junior
26

What is lazy loading and when should you use it?

  • Lazy loading defers loading of non-critical resources until they're needed (e.g., when they enter the viewport).
  • Images: <img loading="lazy"> — native browser support. Use loading="eager" (or omit) for LCP images.
  • Routes/components: Dynamic import + React.lazy / defineAsyncComponent.
  • Intersection Observer: Custom implementation for any element (load data, play video).
  • Don't lazy-load LCP images — this delays the most important paint.

What problems does this solve?

  • Lazy loading is a fundamental performance technique — the exception for LCP images is a nuanced detail that separates careful practitioners.
Junior
29

What is the browser rendering pipeline?

  • The browser turns HTML/CSS/JS into pixels through this pipeline:
  • 1. Parse — HTML → DOM, CSS → CSSOM.
  • 2. Style — Combine DOM + CSSOM → computed styles for each element.
  • 3. Layout (Reflow) — Calculate geometry (size, position) of each element.
  • 4. Paint — Fill in pixels for each element (text, colours, borders, images).
  • 5. Composite — Layer manager combines painted layers; GPU composites them to screen.
  • CSS properties that trigger only Composite (transform, opacity) are the cheapest to animate — no layout or paint needed.

What problems does this solve?

  • Understanding the rendering pipeline explains why some CSS animations are smooth and others cause jank — foundational for runtime performance.

Mid-Level Questions

Mid
1

How do you analyse and reduce bundle size?

  • Analyse: Rollup Plugin Visualizer, webpack-bundle-analyzer, ANALYZE=true npm run build (Next.js), Vite's built-in bundle analysis.
  • Common culprits: Moment.js (use date-fns/dayjs), lodash (use lodash-es + tree shaking or native), large icon libraries (import individually).
  • Tactics: Dynamic imports for rarely used features, CDN externals for large libraries, choose smaller alternatives (bundlephobia.com).
  • Track bundle size in CI — enforce a performance budget.

What problems does this solve?

  • Bundle analysis is mandatory for production FE work — knowing how to identify and eliminate size culprits is a key skill.
Mid
3

How do you optimise images for web performance?

  • Format: WebP (~30% smaller than JPEG) or AVIF (~50% smaller, wider HDR support). Use JPEG/PNG as fallback.
  • Responsive images: srcset and sizes — serve the right resolution for each screen. <picture> for art direction.
  • Dimensions: Always specify width and height to prevent CLS.
  • Compression: Squoosh, ImageMagick, Sharp for server-side optimisation.
  • Lazy loading: loading="lazy" for below-fold images.
  • CDN with image transforms: Cloudinary, Imgix, Next.js Image component — on-the-fly resizing and format conversion.

What problems does this solve?

  • Images are typically the largest assets on a page — image optimisation has the highest performance ROI for most sites.
Mid
4

How do you optimise web font loading?

  • font-display:
    • swap — show fallback immediately, swap when font loads (FOUT). Good for body text.
    • optional — use font only if already cached (no FOUT, no CLS). Best for non-critical fonts.
    • block — invisible text until font loads (FOIT). Avoid.
  • Preload critical fonts:<link rel="preload" as="font" crossorigin>.
  • Self-host fonts instead of loading from Google Fonts (eliminates cross-origin DNS lookup).
  • Subsetting: Include only the characters/glyphs you need (reduces font file size).
  • Size-adjusted fallbacks: CSS size-adjust and ascent-override minimise CLS on font swap.

What problems does this solve?

  • Font loading is a leading cause of CLS and FCP delays — font-display and preloading are the key tools.
Mid
5

How does HTTP caching affect performance?

  • Caching eliminates network round-trips for unchanged resources — the biggest possible performance win.
  • Strategy: Static assets (JS, CSS, images) with content hashes in filenames → Cache-Control: max-age=31536000, immutable. HTML → no-cache (always revalidate).
  • Service Worker caching: Cache-first or stale-while-revalidate strategies for offline-capable apps.
  • CDN edge caching: Cache responses at CDN level, drastically reducing TTFB for global users.

What problems does this solve?

  • Cache strategy design is one of the highest-leverage performance decisions — improper caching either wastes bandwidth or stales content.
Mid
9

What are Web Workers?

  • Web Workers run JavaScript in a background thread, independent of the main thread, preventing heavy computations from blocking the UI.
  • Communication via postMessage / onmessage (message passing, not shared memory).
  • Use cases: Data parsing (large JSON/CSV), image processing, cryptography, complex calculations.
  • Cannot access: DOM, window, or most browser APIs (but can use fetch, IndexedDB, setTimeout).
  • SharedArrayBuffer + Atomics — shared memory between workers for high-performance use cases (requires COOP/COEP headers).

What problems does this solve?

  • Web Workers are the solution for CPU-intensive work that causes main-thread jank — knowing their limitations is as important as knowing their use.
Mid
10

What are render-blocking resources?

  • Resources that block the browser from rendering the page until they are downloaded and processed:
  • CSS in <head> — Blocks rendering (browser needs CSSOM to paint). Inline critical CSS; async-load non-critical.
  • Scripts without async/defer — Blocks HTML parsing. Add defer (execute in order after HTML parsed) or async (execute as soon as downloaded).
  • defer is safer for scripts that depend on DOM. async for independent scripts (analytics).
  • ES modules (type="module") defer by default.

What problems does this solve?

  • Render-blocking resources are a leading cause of poor FCP — defer/async and critical CSS are the core fixes.
Mid
11

What are resource hints and when do you use them?

  • dns-prefetch — Resolve DNS for a domain in advance. Low cost. Use for any third-party domain.
  • preconnect — DNS + TCP + TLS for a domain. Higher cost. Use for critical third-party origins (fonts, APIs). Don't overuse — each keeps a connection warm.
  • preload — Fetch a specific resource at high priority for the current page (LCP image, critical font, critical script). as="image|font|script|style" required.
  • prefetch — Low-priority fetch for a resource needed on a future navigation.
  • modulepreload — Preload a JS module and its dependencies.

What problems does this solve?

  • Resource hints are surgical performance tools — using the right hint at the right priority avoids wasted bandwidth while eliminating key bottlenecks.
Mid
13

What is CLS and how do you prevent it?

  • Cumulative Layout Shift measures visual stability — how much visible content unexpectedly shifts during the page load. Target: ≤ 0.1.
  • Common causes: Images without width/height, ads/embeds injected above content, web fonts causing FOUT (Flash of Unstyled Text), dynamically injected content.
  • Fixes:
    • Always set explicit width and height on images and videos (or use CSS aspect-ratio).
    • Reserve space for ads and dynamic content (min-height).
    • Use font-display: optional or swap with size-adjusted fallback fonts.
    • Avoid inserting content above existing content after load.

What problems does this solve?

  • CLS is highly correlated with frustrating UX — understanding its causes leads to specific, actionable fixes.
Mid
14

What is Critical CSS?

  • Critical CSS is the minimum CSS needed to render above-the-fold content. Inlining it in <head> eliminates a render-blocking CSS request, improving FCP/LCP.
  • Non-critical CSS is loaded asynchronously: <link rel="preload" as="style" onload="this.rel='stylesheet'">.
  • Tools: Critters (for frameworks), Critical (Node.js), PurgeCSS (remove unused CSS).
  • Trade-off: Increases HTML size and complexity. Caching benefit of external CSS is lost for inlined styles. Best for pages where FCP is critical (landing pages).

What problems does this solve?

  • Critical CSS directly reduces render-blocking delays — it's a common advanced optimisation asked about in performance interviews.
Mid
16

What is INP and how do you improve it?

  • Interaction to Next Paint (INP) measures the latency of all click, tap, and keyboard interactions. Reports the worst-case interaction. Target: ≤ 200ms. Poor: > 500ms.
  • Replaced FID (First Input Delay) in March 2024 — FID only measured first interaction; INP covers the full session.
  • Improvements:
    • Break up long tasks — use scheduler.yield() or setTimeout to yield to the browser between chunks.
    • Defer non-urgent JS with async/defer.
    • Move heavy computation to Web Workers.
    • Use startTransition in React to mark non-urgent renders.
    • Reduce input handler complexity — avoid heavy synchronous work in event listeners.

What problems does this solve?

  • INP is the newest CWV — being current on it signals active performance knowledge.
Mid
21

What is a CDN and how does it improve performance?

  • A Content Delivery Network is a globally distributed network of servers that serves content from the location nearest to the user, reducing latency.
  • Benefits: Lower TTFB (geographic proximity), reduced load on origin server, DDoS protection, TLS termination at edge.
  • Static assets: JS, CSS, images served from CDN (long-lived cache + content hash filenames).
  • Edge compute: Modern CDNs (Cloudflare Workers, Vercel Edge) can run server code at the edge, enabling SSR with near-CDN TTFB.

What problems does this solve?

  • CDN is the default infrastructure for performant web apps — understanding edge compute shows awareness of modern deployment patterns.
Mid
24

What is compression and which formats are used on the web?

  • Compression reduces the size of text-based resources (HTML, CSS, JS, JSON) in transit.
  • Gzip — widely supported, typically reduces text assets by 70%+.
  • Brotli — 15-25% better than gzip on average. Supported by all modern browsers. Preferred.
  • Enable in your server/CDN — the browser sends Accept-Encoding: gzip, br; server responds with Content-Encoding: br.
  • Don't compress already-compressed assets (images, video, audio) — no benefit, wasted CPU.

What problems does this solve?

  • Compression is the simplest 70%+ size reduction for text assets — brotli being preferred over gzip is current knowledge worth demonstrating.
Mid
28

What is requestAnimationFrame and when do you use it?

  • requestAnimationFrame(callback) schedules a function to run before the browser's next repaint, synced to the display refresh rate (typically 60fps = 16ms).
  • Use for: JavaScript-driven animations, canvas drawing, DOM writes that should sync with rendering.
  • Don't use for: Non-visual work (use setTimeout/setInterval or Web Workers).
  • Callbacks receive a DOMHighResTimeStamp — use it to calculate delta time for frame-rate-independent animations.
  • Cancelled with cancelAnimationFrame(id). Paused automatically in hidden tabs.

What problems does this solve?

  • rAF is the correct primitive for smooth animations — using setTimeout for animations is a common anti-pattern that causes jank.
Mid
30

What is tree shaking?

  • Tree shaking is dead code elimination — bundlers (Webpack, Rollup, Vite) statically analyse ES module imports/exports and remove unused code from the bundle.
  • Requires ES modules (import/export) — CommonJS (require) is not statically analysable.
  • Prerequisites: Packages must have "sideEffects": false in package.json. Named imports only — import { debounce } from 'lodash-es' tree-shakes; import _ from 'lodash' does not.
  • Modern frameworks and libraries ship ES module builds specifically for tree shaking.

What problems does this solve?

  • Understanding why certain imports don't tree-shake (CJS, side effects) prevents dead code from inflating your bundle.

Senior Questions

Senior
2

How do you detect and fix memory leaks in the browser?

  • Common causes: Event listeners not removed on unmount, closures holding references, forgotten timers/intervals, DOM references in detached trees, global variables accumulating.
  • Detection: Chrome DevTools Memory tab → Heap snapshot. Record allocation timeline. Look for detached DOM nodes and growing retained size.
  • Fixes:
    • Remove event listeners in cleanup (useEffect return, onUnmounted).
    • Clear timers: clearInterval / clearTimeout.
    • Use WeakRef / WeakMap for caches that shouldn't prevent GC.
    • Abort fetch with AbortController on component unmount.

What problems does this solve?

  • Memory leaks degrade long-lived SPA performance over time — detecting and fixing them shows senior-level debugging skill.
Senior
7

What are JavaScript runtime performance best practices?

  • Avoid long tasks: Break work into chunks < 50ms (INP). Use scheduler.yield() or setTimeout(0).
  • Debounce and throttle: Rate-limit scroll/resize/input event handlers.
  • Avoid synchronous expensive operations in event handlers (DOM reads, network calls).
  • Use efficient data structures: Map/Set for frequent lookups vs Array.includes().
  • Minimise DOM access: Batch reads/writes, use DocumentFragment for bulk inserts.
  • Profile first: Use Chrome DevTools Performance tab before optimising — avoid premature optimisation.

What problems does this solve?

  • "Profile first" is the most important principle — understanding where time is actually spent prevents optimising the wrong things.
Senior
8

What are Service Workers and how do they enable performance?

  • Service Workers are background scripts that intercept network requests, enabling offline support, caching, and push notifications.
  • Cache strategies:
    • Cache-first: Serve from cache; fall back to network. Fast, offline-capable.
    • Network-first: Try network; fall back to cache. Fresh data with offline fallback.
    • Stale-while-revalidate: Serve cache immediately; update cache from network in background.
  • Workbox library simplifies SW caching strategies.
  • Service Workers only run on HTTPS (except localhost).

What problems does this solve?

  • Service Workers are the foundation of PWAs and the mechanism for cache-first loading — understanding the strategies shows PWA-level performance knowledge.
Senior
12

What does a comprehensive web performance checklist cover?

  • Loading: CDN for static assets, Brotli compression, HTTP/2+, resource hints (preconnect, preload LCP), long cache TTL with content hashing.
  • Images: WebP/AVIF, correct srcset, explicit dimensions, lazy-load below fold, no lazy-load on LCP image.
  • JavaScript: Code split by route, tree-shaken, defer/async on scripts, no render-blocking scripts.
  • CSS: Critical CSS inlined, non-critical async, minimal unused CSS (PurgeCSS).
  • Fonts: font-display: swap/optional, preload critical fonts, self-hosted.
  • Runtime: No long tasks (>50ms), event handlers debounced, virtualisation for long lists.
  • Measurement: Lighthouse CI in pipeline, RUM collecting Web Vitals, performance budget enforced.

What problems does this solve?

  • A comprehensive checklist demonstrates systematic performance thinking — interviewers for performance-sensitive roles will expect most of these points.
Senior
19

What is Real User Monitoring (RUM)?

  • RUM collects performance data from real user sessions (vs. lab tools that simulate conditions).
  • Web Vitals JS library: Collects LCP, INP, CLS, FCP, TTFB in the browser and sends to your analytics.
  • Tools: Vercel Analytics, Datadog RUM, New Relic, SpeedCurve, Sentry Performance.
  • CrUX (Chrome User Experience Report): Aggregated real-user data from Chrome browsers. Used by Google Search ranking and visible in PageSpeed Insights.
  • RUM reveals performance issues on real devices and network conditions that lab tools miss.

What problems does this solve?

  • The lab-vs-field distinction is critical — Lighthouse scores don't always match real user experience. RUM is how you close that gap.
Senior
22

What is a performance budget?

  • A performance budget sets quantitative limits on metrics (e.g., JS bundle ≤ 200KB, LCP ≤ 2.5s, Lighthouse ≥ 90) that must not be exceeded.
  • Enforced in CI — PRs that exceed budget are blocked.
  • Tools: bundlesize, Lighthouse CI assert config, Webpack performance.maxAssetSize.
  • Creates shared accountability across the team — prevents performance regressions.

What problems does this solve?

  • Performance budgets prevent the gradual degradation that happens in most production apps — showing you know how to enforce them in CI is a senior signal.
Senior
25

What is layout thrashing?

  • Layout thrashing occurs when JS alternately reads and writes to the DOM in a tight loop, forcing the browser to recalculate layout repeatedly (expensive).
  • Fix: Batch DOM reads, then batch writes. Use requestAnimationFrame to schedule writes. Use FastDOM library.

What problems does this solve?

  • Layout thrashing is a common source of janky animations and slow interactive elements — the read-then-write pattern is the core fix.
Senior
27

What is list virtualisation?

  • Virtualisation renders only the visible items in a long list — DOM nodes for off-screen items don't exist, dramatically reducing DOM size and rendering cost.
  • Libraries: TanStack Virtual (framework-agnostic), react-window, react-virtual, vue-virtual-scroller.
  • When to use: Lists of 100+ items where rendering all at once causes visible lag.
  • Trade-offs: Scroll position management, accessibility complexity, harder to search/print full content.

What problems does this solve?

  • Virtualisation is the go-to solution for large lists — it prevents a common performance cliff while keeping the API simple.