CONCEPTS - rs-hash/GETTHATJOB GitHub Wiki
This document explains the entire flow of browser internals: how requests are processed, the critical rendering path, DOM, CSSOM, reflow, compositing, the JavaScript event loop, rendering cycle, and performance best practices.
🔹 1. Request Processing & Navigation Lifecycle
-
User Action: Typing URL / clicking link.
-
Networking:
- DNS resolution → IP address lookup.
- TCP handshake → secure connection (TLS if HTTPS).
- HTTP request → headers, cookies, caching validation.
- Response → status code, headers, HTML payload.
-
Navigation Stages (per [Navigation Timing API]):
-
fetchStart→ request initiated. -
responseEnd→ HTML fully received.
-
-
Parsing begins immediately (streaming): browser does not wait for full HTML to start building DOM.
✅ Best Practice: Optimize server response time (TTFB) & enable caching/CDN.
🔹 2. Critical Rendering Path (CRP)
-
Steps:
- Parse HTML → Build DOM.
- Parse CSS → Build CSSOM.
- Combine DOM + CSSOM → Render Tree.
- Layout (Reflow) → calculate positions/sizes.
- Paint → draw pixels (backgrounds, borders, text).
- Compositing → GPU assembles layers for screen.
-
Blocking Resources:
- CSS is render-blocking.
- JavaScript is parser-blocking (unless
async/defer).
✅ Best Practice:
- Minimize render-blocking JS/CSS.
- Use
preload/prefetchfor critical assets. - Inline critical CSS.
🔹 3. DOM, CSSOM & Render Tree
-
DOM (Document Object Model):
- Tree structure built from HTML.
- Nodes represent elements, text, comments.
-
CSSOM (CSS Object Model):
- Parsed CSS → cascade & inheritance resolved.
- Style rules mapped to DOM nodes.
-
Render Tree:
- Combination of DOM + CSSOM.
- Excludes
display:nonebut includes pseudo-elements.
✅ Best Practice:
- Avoid deep DOM trees (affects traversal & reflow).
- Prefer class selectors over heavy descendant selectors.
🔹 4. Layout (Reflow), Paint & Compositing
-
Layout (Reflow):
- Calculate box metrics (width, height, position).
- Triggered by DOM changes or style recalculation.
-
Paint:
- Convert render tree into actual pixels.
- Draw borders, shadows, text, backgrounds.
-
Compositing:
- Layers sent to GPU for rasterization.
- Browser combines layers efficiently for smooth animations.
-
tablelayouts → full reflow. - Changing
width/height/top/left→ layout. - Changing
color/background→ paint.
✅ Best Practice:
- Prefer
transform&opacityfor animations (only compositing). - Minimize layout thrashing.
🔹 5. JavaScript Execution & Rendering Order
-
Main Thread:
- Executes JS, builds DOM/CSSOM, handles input, paints.
-
Blocking:
-
<script>withoutasync/defer→ blocks parsing. - Long JS tasks → freeze rendering.
-
-
Async/Defer:
-
async: download in parallel, execute ASAP. -
defer: download in parallel, execute after DOM parsed.
-
✅ Best Practice:
- Split large scripts into smaller chunks.
- Use Web Workers for CPU-heavy work.
🔹 6. Browser Event Loop + Rendering Cycle
-
Event Loop Phases:
- Macro-tasks: script, setTimeout, setInterval, I/O.
- Micro-tasks: promises, MutationObserver.
- Render Opportunity: after microtasks, before next frame.
-
Frame Budget:
- 60fps target → ~16ms per frame.
- If tasks >16ms → dropped frames.
✅ Best Practice:
- Use
requestIdleCallbackfor low-priority tasks. - Use
requestAnimationFramefor animations.
🔹 7. requestAnimationFrame (rAF)
-
What it does:
- Tells browser you want to perform an animation.
- Callback fired before next repaint.
-
Advantages:
- Synced with refresh rate (60Hz / 120Hz).
- Prevents jank.
-
Usage:
function step(timestamp) { element.style.transform = `translateX(${timestamp/10}px)`; requestAnimationFrame(step); } requestAnimationFrame(step);
✅ Best Practice:
- Always use
rAFfor smooth animations. - Cancel unused rAF loops.
🔹 8. Dirtying, Style Recalculation & Forced Synchronous Layout
-
Dirtying:
- DOM/style changes mark nodes as needing recalculation.
-
Style Recalculation:
- Triggered when classes/styles change.
-
Forced Synchronous Layout:
- Happens when JS queries layout (
offsetHeight,getBoundingClientRect) right after DOM mutations. - Forces browser to flush pending layout tasks → expensive.
- Happens when JS queries layout (
// BAD: Forces reflow
el.style.width = "200px";
console.log(el.offsetHeight); // Forces sync layout✅ Best Practice:
- Batch reads & writes using libraries like FastDOM.
- Minimize DOM thrashing inside loops.
🔹 9. Practical Examples & Best Practices
-
Optimize Paint/Compositing:
- Use
will-change: transform, opacity;.
- Use
-
Reduce Layout Thrashing:
// BAD for (let i=0; i<1000; i++) { el.style.left = i + "px"; console.log(el.offsetWidth); } // GOOD const width = el.offsetWidth; for (let i=0; i<1000; i++) { el.style.left = i + "px"; }
-
Script Loading:
- Place scripts at bottom or use
defer.
- Place scripts at bottom or use
-
CSS:
- Inline critical CSS, defer non-critical.
-
Animations:
- Stick to
transformandopacity.
- Stick to
-
Event Loop Optimization:
- Break long tasks with
setTimeout(fn, 0)orqueueMicrotask.
- Break long tasks with
- Rendering is pipeline-based (Parse → Style → Layout → Paint → Composite).
- JS execution blocks rendering.
- Avoid forced sync layouts.
- Use
rAFfor animations & keep work under 16ms per frame. - Always optimize CRP for fast first render.