Tags: frontend, javascript, typescript, react, web-performance, browser, css
Level: intermediate
TL;DR: Core frontend interview essentials covering the browser lifecycle, React state and reconciliation, rendering performance, and typical architecture tradeoffs.
Critical Rendering Path consists of DOM, CSSOM, Render Tree, Layout, and Paint.
Event loop processes tasks via Call Stack, Microtasks (Promises), and Macrotasks (setTimeout, I/O).
React Virtual DOM detects mutations via reconciliation and applies batch DOM updates.
Component lifecycle separates render phase (pure, no side-effects) from commit phase (DOM writes).
Hydration attaches event listeners to server-rendered HTML markup on the client.
State management balances local state, shared context, and server-cache state.
Web Vitals measure LCP for load speed, INP for responsiveness, and CLS for stability.
Tree shaking relies on static ES module imports to remove unused code during build.
Browser caching leverages HTTP headers like Cache-Control, ETag, and Service Workers.
Cross-Origin Resource Sharing (CORS) enforces browser security boundaries across differing origins.
Q: How does the browser event loop handle microtasks versus macrotasks?R: The call stack executes synchronous code first. When empty, the event loop drains the entire microtask queue before processing the next macrotask from the queue.
Q: What is the difference between useMemo, useCallback, and React.memo?R: I use React.memo to skip re-rendering a component if props did not change, useMemo to cache expensive calculated values, and useCallback to preserve function references across renders.
Q: What triggers layout reflow versus repaint in modern browsers?R: Reflow occurs when geometry or layout properties change, such as width or top. Repaint happens on visual changes that do not alter layout, like color or background-color.
Q: How do you address client-side performance bottlenecks in a large application?R: I profile using Chrome DevTools, split bundles using dynamic imports, virtualize long lists, optimize assets, and memoize computations to avoid unnecessary renders.
Q: How do CSS Grid and Flexbox differ in practical layout architecture?R: I choose Flexbox for one-dimensional flows along a row or column, and CSS Grid for two-dimensional structures requiring strict row and column alignment.
Mutating state objects directly instead of creating shallow or deep copies breaks change detection.
Omitting stable cleanup handlers in useEffect causes memory leaks and dangling subscriptions.
Using array indexes as React key props corrupts component state during reordering.
Triggering layout thrashing by alternating reads and writes to layout properties in a tight loop.
Over-memoizing trivial calculations adds overhead that exceeds the cost of re-rendering.
Blocking the main thread with heavy synchronous computations instead of offloading to Web Workers.
// Debounce implementation for input handlers
function debounce<T extends (...args: any[]) => void>(fn: T, delay: number): (...args: Parameters<T>) => void {
let timer: ReturnType<typeof setTimeout> | null = null;
return (...args: Parameters<T>) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
TypeScript
// Custom hook for abortable fetch requests
import { useEffect, useState } from 'react';
function useFetchData<T>(url: string) {
const [data, setData] = useState<T | null>(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then((res) => res.json())
.then((json: T) => setData(json))
.catch((err) => {
if (err.name !== 'AbortError') throw err;
});
return () => controller.abort();
}, [url]);
return data;
}
[ ] INP (Interaction to Next Paint) measurement and optimization techniques
[ ] CSS containment property and subgrid specifications
[x] JavaScript closure mechanics and prototypical inheritance
[x] Standard HTTP caching headers and cache validation mechanisms