Performance Optimization
performance-optimization
Code Snippets
Debounce Function in JavaScript
Debouncing collapses a burst of calls into a single trailing invocation, which is the standard fix for noisy events like keystrokes, resize, and scroll. This snippet covers the canonical trailing-edge debounce, a variant with a manual `cancel` for component unmount, and a Promise-returning version that resolves only with the last call's result. Drop it into any UI handler that fires faster than the work it triggers.
Throttle Function in JavaScript
Throttling caps how often a function can fire to at most once per interval, which is the right tool for scroll, mousemove, and analytics beacons. This snippet contrasts throttle against debounce, then walks from a leading-edge timestamp gate to a `setTimeout`-driven version that includes a manual `cancel`. Pick the variant that matches whether the very first call should fire immediately.
Throttle with Leading and Trailing Edges
A leading-only throttle drops the last call's arguments; a trailing-only throttle feels laggy on the first event. The Lodash-style throttle that fires on BOTH edges is the version every UI codebase eventually wants: an immediate response on the leading edge plus a guaranteed final fire after the burst ends. This snippet builds that production-grade throttle from scratch with cancel and flush, then shows the configurable `leading` / `trailing` toggle that powers most real-world helpers.
Async Batch Processor
High-volume event streams (analytics, logs, telemetry) are usually best forwarded in batches: batching lowers per-call overhead, plays nicely with bulk endpoints, and lets you compress traffic. The trick is choosing when to flush. This snippet builds a processor that flushes whenever the buffer hits a max size OR a max wait elapses, then layers in flush-on-demand and graceful shutdown so nothing is lost during process exit.
Check if an Element Is in the Viewport
Lazy-loading images, animating sections on enter, and infinite scroll all start with the same question: is this element on screen? The classic answer was a scroll handler plus `getBoundingClientRect`, but `IntersectionObserver` is now the right tool: passive, batched, and rate-limited by the browser. This snippet covers the synchronous bounds check, the async observer-based watcher, and a one-shot helper that resolves once a target enters the viewport.
React useDebounce Hook
Debouncing a fast-changing value (a search input, a window resize, a slider) is one of the first React-specific utilities every project needs. This snippet shows the simplest one-state useDebounce hook, a leading-edge variant for instant first reactions, and a useDebouncedCallback variant that wraps a function instead of a value. Pick the shape that matches what your component actually needs.
React useThrottle Hook
Throttling caps the rate at which a value updates while still letting changes through at a steady cadence. This snippet covers the basic useThrottle that emits at most once per window, a useThrottledCallback variant for wrapping functions, and the leading-plus-trailing edge form that keeps the first and last events without dropping the tail. Use it for scroll handlers, mouse trackers, and any high-frequency stream you need to sample.
React useInterval Hook (Dan Abramov pattern)
Calling setInterval inside useEffect breaks the moment the callback closes over stale state. Dan Abramov's useInterval pattern stores the latest callback in a ref so the timer always fires the freshest version without resetting. This snippet covers the canonical pattern, a pause-aware variant that accepts a null delay, and a useTimeout sibling for one-shot timers.
React useInfiniteScroll Hook
Infinite scroll feels simple until you wire IntersectionObserver, page tracking, and the request lifecycle together. This snippet covers a sentinel-ref hook that fires a load callback when the bottom marker scrolls into view, a paginated variant that tracks the page state for you, and an end-of-feed guard that stops calling the callback once the server says there is no more data.
Question Banks
Debounce, Throttle, and Rate Limiting Quiz
Implement the rate-limiting primitives that ship in every UI codebase: debounce, throttle, leading-edge debounce, and `requestAnimationFrame`-paced throttling.
DOM Observer APIs Quiz (IntersectionObserver, MutationObserver)
Use the three DOM observer APIs the browser ships for free: IntersectionObserver for visibility, MutationObserver for DOM diffs, and ResizeObserver for layout changes.
React Router and Code Splitting Quiz
Four drills on declarative routing with react-router and using React.lazy plus Suspense to split bundles per route or per heavy component.
React Performance Optimization Quiz
Five drills on memoization, stable references, PureComponent, and the trade-offs between fixing a real render-cost problem and prematurely wrapping everything in memo.
React SSR and Hydration Quiz
Three drills on the difference between SSR and CSR, what hydration actually does, and how React 18 streaming SSR plus selective hydration change the picture.
React ReactDOMServer: Two Explanations Quiz
Two explanations of `react-dom/server` rendering APIs (string vs streaming) plus companions on streaming SSR with `renderToPipeableStream` and on hydration mismatches.
React Code-Splitting: Two Explanations Quiz
Two explanations of code-splitting (bundler-level vs `React.lazy` + `Suspense`) plus companions on preloading routes and on splitting non-component utilities.
Community
Why My Context Provider Was Re-rendering Everything
We added a flame-graph and saw every consumer of `<UserContext>` re-rendering on every keystroke in a sibling. The fix took two days to isolate and three lines to ship.
useElementSize With ResizeObserver
Measuring a DOM node's width and height in React without listening to `window.resize`. Uses `ResizeObserver` so it fires for layout-driven changes (sidebar toggling, font load, parent flex) too.
Garbage Collection in V8 Without the Mystique
The working engineer's tour of V8 GC: generational hypothesis, Scavenger for young space, Mark-Sweep-Compact for old, incremental marking, Orinoco's concurrent collector, and what application code can actually do.
Windowing a 10k Row List Without react-window
We had a 10k row list freezing scroll. react-window worked but was overkill for our shape. Here is the 60 line virtualizer we shipped instead.
Route-Level Code Splitting With React.lazy
Our initial bundle was 2.1MB. Splitting routes via React.lazy plus Suspense dropped it to 340KB on first paint. Three accordions on how I wire it.
When `memo` Actually Stops a Re-render (and When It Does Not)
I once added React.memo everywhere and renders barely changed. Memo only works under specific conditions, and outside those it is dead weight. Three accordions on the trap and the fix.
Bit Manipulation Tricks I Keep Forgetting
A working programmer's cheat sheet of bitwise operations: the moves I look up every six months, what each one does, real production uses, and the ones that look clever but I avoid.
The CSS-in-JS Tradeoffs I Keep Explaining to Juniors
Five conversations I keep having: the styling-approach overview, build-time vs runtime CSS-in-JS, CSS Modules vs Tailwind, the styled-components performance trap I keep flagging, and when to walk back to plain CSS.
The React Context Traps I Keep Stepping On
I have lost the same Context fight on three different teams. These are the 5 traps I now check for in every Provider before approving the PR, with the rewrites that actually stop the re-render storm.
useInView Hook With Hysteresis
An IntersectionObserver-based `useInView` that does not flip on/off when an element straddles the viewport edge. Uses two thresholds (enter and exit) so analytics events fire once per real visibility.
