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(),defineAsyncComponentin 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. Useloading="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:
srcsetandsizes— serve the right resolution for each screen.<picture>for art direction. - Dimensions: Always specify
widthandheightto 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-adjustandascent-overrideminimise 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 usefetch, 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) orasync(execute as soon as downloaded). deferis safer for scripts that depend on DOM.asyncfor 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
widthandheighton images and videos (or use CSS aspect-ratio). - Reserve space for ads and dynamic content (
min-height). - Use
font-display: optionalor swap with size-adjusted fallback fonts. - Avoid inserting content above existing content after load.
- Always set explicit
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()orsetTimeoutto yield to the browser between chunks. - Defer non-urgent JS with
async/defer. - Move heavy computation to Web Workers.
- Use
startTransitionin React to mark non-urgent renders. - Reduce input handler complexity — avoid heavy synchronous work in event listeners.
- Break up long tasks — use
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 withContent-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": falsein 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 (
useEffectreturn,onUnmounted). - Clear timers:
clearInterval/clearTimeout. - Use
WeakRef/WeakMapfor caches that shouldn't prevent GC. - Abort fetch with
AbortControlleron component unmount.
- Remove event listeners in cleanup (
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()orsetTimeout(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 CIassertconfig, Webpackperformance.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
requestAnimationFrameto 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.