What experienced frontend engineers forget before an interview, grouped by subtopic. For language mechanics see javascript.md and typescript.md; for web vulnerabilities and token storage see security.md; for React and Next.js see react.md and nextjs.md.
| Strategy | Renders | Trade-off |
|---|---|---|
| CSR | in the browser after JS loads | slow first paint and SEO, fast later navigation |
| SSR | on the server, per request | fresh and SEO-friendly, higher server load |
| SSG | at build time | fastest and cheapest, stale until rebuild |
| ISR | like SSG, regenerated in the background after a revalidate interval or on demand | near-CDN speed; serves stale until regeneration succeeds |
- Streaming SSR flushes HTML in chunks, so the shell paints before slow data-dependent sections resolve.
- Hydration runs the render on the client and attaches listeners to the server HTML, reusing the DOM instead of recreating it.
- A hydration mismatch (server and client render different output) can force the framework to re-render that part on the client — React's causes and fixes in react.md.
- Islands architecture: the page is static HTML; only interactive islands ship JS and hydrate independently.
- React Server Components render only on the server and send serialized output, not code — only Client Components ship JS and hydrate (see react.md).
- The router intercepts navigation and updates the URL with the History API (
pushState), no full reload. - A refresh on
/profilehits the server, which must fall back toindex.htmlfor unknown paths or it 404s.
- HTML → DOM, CSS → CSSOM → render tree (visible nodes) → layout → paint → composite (critical rendering path).
- CSS is render-blocking; a classic
<script>is parser-blocking.
async: downloads in parallel, runs as soon as it arrives, no order guarantee.defer: downloads in parallel, runs in order after parsing;type="module"is deferred by default.
- Changing
width/topre-runs layout + paint + composite;transform/opacitycan skip to composite on the GPU once the element has its own layer. will-change: transformhints the browser to promote a layer ahead of time; too many layers waste GPU memory.
- Alternating reads (
offsetHeight) and writes (style.width) in a loop forces a synchronous reflow each time. - Batch all reads, then all writes — or schedule writes in
requestAnimationFrame.
- Specificity: inline > ID > class/attribute/pseudo-class > element; cascade layers and origin rank above specificity, and
!importantinverts layer order.
z-indexonly compares elements within the same stacking context — whyz-index: 9999sometimes "doesn't work".opacity < 1,transform,filter,position: fixed, and positioned elements with az-indexeach create a new context.
- Container queries (
@container) style a component by its container's size, not the viewport — reusable responsive components. :has()selects a parent by its children (form:has(:invalid)), which used to need JavaScript.
- The View Transition API animates between two DOM states:
document.startViewTransition(update)snapshots old and new, then cross-fades or morphs elements sharing aview-transition-name. - Multi-page apps opt in to cross-document transitions with
@view-transition { navigation: auto }.
| Metric | Good at p75 | Measures |
|---|---|---|
| LCP | ≤ 2.5 s | render time of the largest visible element |
| INP | ≤ 200 ms | worst-ish interaction latency over the visit; replaced FID in March 2024 |
| CLS | ≤ 0.1 | unexpected layout shift |
- LCP: preload the hero image or font, cut render-blocking resources, fast TTFB.
- INP: break long tasks (> 50 ms) and yield to the main thread (
scheduler.yield()). - CLS: reserve space with
width/heightoraspect-ratio.
- Code splitting by route or with dynamic
import()keeps the first bundle to what the first screen needs. - Tree shaking needs ES modules;
"sideEffects": falsealso lets the bundler drop unused modules whole — list CSS and polyfill files as exceptions.
srcset/sizeslet the browser pick a resolution per viewport; AVIF/WebP are much smaller than JPEG/PNG.loading="lazy"for below-the-fold images — never on the LCP image, which should getfetchpriority="high".
- Web Workers run JS on another thread (no DOM access), talking via
postMessage(structured clone, or transfer anArrayBufferfor free). content-visibility: autoskips layout and paint for off-screen sections.
preload: fetch this exact resource now, it's needed for the current page.prefetch: low-priority fetch for a likely next navigation.preconnect: open DNS + TCP + TLS early when the resource URL isn't known yet.
no-cachemeans revalidate every time, not "don't cache";no-storemeans never store.max-ageapplies to every cache;s-maxageoverrides it for shared caches (CDN).
- Long
max-age+immutableon content-hashed filenames (app.a3f9c1.js), with HTML servedno-cache— each deploy is a new URL. ETag/Last-Modifiedlet the server answer304 Not Modified— saves the body, not the round trip.
| Storage | Size | Notes |
|---|---|---|
| Cookies | ~4 KB each | sent with every request to the domain |
localStorage |
~5 MB per origin | synchronous (blocks the main thread), strings only |
sessionStorage |
~5 MB per origin | per tab, cleared when the tab closes |
| IndexedDB | a share of total disk, per-origin quota | async, structured data, available in workers |
| Cache API | same origin quota as IndexedDB | request/response pairs, used by service workers |
Any XSS can read all of them except HttpOnly cookies — token storage in security.md.
- Service workers implement cache-first, network-first, or stale-while-revalidate strategies and offline support.
- A waiting service worker is a common reason users keep seeing the old deploy.
- Native elements (
<button>,<nav>,<label>) come with keyboard, focus, and screen-reader behavior for free. - First rule of ARIA: don't use ARIA when a native element already has the semantics.
- Client-side navigation doesn't reset focus — move focus to the new view's heading on route change.
- Everything clickable must be keyboard-reachable with a visible focus indicator; a
<dialog>opened withshowModal()makes the rest of the page inert.
- WCAG AA: 4.5:1 for normal text, 3:1 for large text and UI components.
- Never convey information by color alone (error states need text or an icon).