No history yet

Study Guide

đź“– Core Concepts

JavaScript uses a single-threaded event loop to manage asynchronous tasks like timers and promises, preventing the main thread from blocking while waiting for I/O. (Topic: JS Runtime & Event Loop)

Closures capture variables from their defining scope, which in React can lead to functions referencing outdated state if dependencies are not managed correctly. (Topic: Closures & Stale State)

The browser converts HTML and CSS into pixels through a multi-step process (DOM/CSSOM, layout, paint, composite) that JavaScript can block or optimize. (Topic: Critical Rendering Path)

React's Fiber architecture enables concurrent rendering by breaking updates into smaller, interruptible units, improving UI responsiveness during complex state changes. (Topic: React Fiber Architecture)

Memoization techniques like useMemo and useCallback prevent unnecessary re-renders by caching values and functions, but have their own performance trade-offs. (Topic: Memoization & Performance)

Immutable state updates allow React to detect changes efficiently using cheap reference comparisons, ensuring predictable rendering and optimized performance. (Topic: Immutability & Change Detection)

React automatically batches multiple state updates from asynchronous operations into a single render, optimizing performance and preventing unnecessary UI churn. (Topic: Asynchronous Updates & Batching)

Hooks rely on a stable call order because React stores their state in a linked list on a component's internal fiber node. (Topic: Rules of Hooks Internals)

Core Web Vitals (LCP, INP, CLS) are user-centric metrics for measuring perceived performance, which can be profiled and improved using browser DevTools. (Topic: Core Web Vitals & Profiling)

Concurrent features like useTransition allow React to handle non-urgent UI updates without blocking user input, creating a more fluid and responsive experience. (Topic: Concurrent React Features)

Properly cleaning up side effects and managing object references is crucial for preventing memory leaks that degrade application performance over time. (Topic: Memory Management & Leaks)

While React helps prevent Cross-Site Scripting (XSS), developers must still sanitize input and use features like Content Security Policy for robust security. (Topic: Web Security in React)

📌 Must Remember

JS Runtime & Event Loop

  1. Single-threaded: JavaScript has only one call stack and executes one task at a time.
  2. Call Stack: Tracks function calls; a "stack overflow" error occurs when it exceeds its maximum size.
  3. Memory Heap: An unstructured memory region where objects and functions are stored.
  4. Event Loop: Continuously checks the task queues and moves tasks to the call stack when it's empty.
  5. Microtasks first: The microtask queue (e.g., Promises) is always processed completely before the macrotask queue (e.g., setTimeout).

Closures & Stale State

  1. Lexical Scope: A function's ability to access variables from its parent scope.
  2. Closure: A function bundled with references to its surrounding state (the lexical environment).
  3. Stale State: Occurs when a closure in a hook (like useEffect) captures an old value of state or props.
  4. Dependency Arrays: Tell React when to re-create a function or effect with fresh state values.
  5. Functional Updates: Using setState(prevState => ...) accesses the most current state without needing it in a dependency array.

Critical Rendering Path

  1. DOM/CSSOM: The browser builds tree structures from HTML and CSS.
  2. Layout (Reflow): The browser calculates the size and position of every element on the page.
  3. Paint: The browser fills in the pixels for each element (colors, images, text).
  4. Composite: The browser draws layers to the screen in the correct order. Changes to transform and opacity only trigger this step.
  5. Layout Thrashing: Rapidly reading and writing layout-triggering properties, forcing expensive, repeated reflows.

React Fiber Architecture

  1. Fiber: A unit of work representing a component; it's a JavaScript object with information about the component and its connections.
  2. Reconciliation: The algorithm React uses to diff two virtual DOM trees (now powered by Fiber).
  3. Render Phase: Asynchronous and interruptible. React can build a new Fiber tree over time without blocking the main thread.
  4. Commit Phase: Synchronous and cannot be interrupted. React applies the changes to the actual DOM.
  5. Keys: Help React identify which items have changed, been added, or been removed in a list, preventing unnecessary DOM mutations.

Memoization & Performance

  1. Referential Integrity: An object is only equal to itself (obj === obj). A new object {} is never equal to another {}.
  2. useMemo: Caches the result of a calculation. Use for expensive computations.
  3. useCallback: Caches a function definition. Prevents re-creating functions on every render.
  4. React.memo: A Higher-Order Component (HOC) that prevents a component from re-rendering if its props haven't changed.
  5. Over-memoization: The cost of memoizing (memory usage, dependency checks) can sometimes be greater than the cost of a simple re-render.

📚 Key Terms

Call Stack: A data structure that records where in the program we are, adding a 'frame' for each function call and removing it when the function returns.

  • Used in context: When you debug JavaScript, the call stack in your browser's dev tools shows you the chain of functions that led to the current point.
  • Topic: JS Runtime & Event Loop

Stale Closure: A closure that holds a reference to an outdated variable from its parent scope, often causing bugs in React components with hooks.

  • Used in context: The event handler kept showing the initial count because it was a stale closure that captured count when it was 0.
  • Topic: Closures & Stale State

Layout Thrashing: A performance bottleneck where the browser is forced to repeatedly calculate layout (reflow) because JavaScript code alternates between reading and writing DOM properties.

  • Used in context: The loop that read an element's offsetHeight and then immediately changed its width caused severe layout thrashing.
  • Topic: Critical Rendering Path

Fiber: An internal React object that represents a unit of work and contains information about a component, its input, and its output.

  • Used in context: React's reconciler walks the Fiber tree to determine what changes need to be made to the UI.
  • Topic: React Fiber Architecture

Referential Integrity: The principle that an object or array reference is only equal (===) to itself, which is the basis for React's default prop comparison.

  • Used in context: Because we created a new array on every render, the component's props failed the referential integrity check, causing an unnecessary re-render.
  • Topic: Memoization & Performance

Structural Sharing: An immutability optimization where creating a "new" version of a data structure reuses as much of the old structure as possible, only creating new parts for what changed.

  • Used in context: When we updated one key in our state object, structural sharing ensured the unchanged parts of the object shared the same memory references.
  • Topic: Immutability & Change Detection

Automatic Batching: A React 18+ feature that groups multiple state updates (including those inside promises, timeouts, or native event handlers) into a single re-render for better performance.

  • Used in context: Thanks to automatic batching, the two setState calls inside our fetch callback only triggered one component re-render.
  • Topic: Asynchronous Updates & Batching

Interaction to Next Paint (INP): A Core Web Vital metric that measures the latency of all user interactions with a page, reporting a single value that represents the worst interaction latency.

  • Used in context: Our application had a high INP because a long-running JavaScript task was blocking the main thread after the user clicked a button.
  • Topic: Core Web Vitals & Profiling

Transition: A new concept in React 18 that allows developers to mark certain state updates as non-urgent, allowing them to be interrupted by more important updates like user input.

  • Used in context: We wrapped the search results update in a startTransition so that typing in the search box would remain fluid and responsive.
  • Topic: Concurrent React Features

Cross-Site Scripting (XSS): A security vulnerability where an attacker injects malicious scripts into a trusted website, which then execute in a victim's browser.

  • Used in context: React's JSX automatically escapes content to protect against XSS, but using dangerouslySetInnerHTML can re-introduce the risk.
  • Topic: Web Security in React

🔍 Key Comparisons

FeatureMicrotasksMacrotasks
DefinitionTasks that should execute immediately after the current script finishes.Tasks that are scheduled to run after the browser has had a chance to render.
PriorityHighLow
QueueMicrotask QueueMacrotask Queue (or Task Queue)
ProcessingThe entire queue is emptied before yielding to the browser.Only one task is processed before checking the microtask queue again.
ExamplesPromise.then(), queueMicrotask()setTimeout(), setInterval(), I/O, UI rendering

Memory trick: Micro is small and fast—it cuts in line. Macro is big and slow—it has to wait its turn.

Topic: JS Runtime & Event Loop


FeatureLayout (Reflow)PaintComposite
What it isCalculating element geometry (position, size).Filling in pixels for each element (color, text, shadows).Drawing pre-painted layers to the screen in order.
PerformanceVery expensive; often affects the entire DOM tree.Expensive, but less so than layout.Cheapest; ideal for animations. Often GPU-accelerated.
Triggered ByChanging element size, position, or content (width, top, font-size).Changing properties that don't affect layout (color, background-image).Changing transform, opacity.
In ReactManipulating the DOM directly, changing CSS that affects geometry.Changing styles like backgroundColor.Using CSS transform: translate() for animations.

Memory trick: Layout is the architect (blueprints), Paint is the painter (colors), Composite is the assembler (stacking finished pieces).

Topic: Critical Rendering Path


FeatureuseTransitionDebouncing/Throttling
MechanismTells React an update is low-priority and can be interrupted.Uses timers (setTimeout) to delay or limit function execution.
ResponsivenessUI remains interactive during the update.UI can become unresponsive during the delayed execution.
IntegrationDeeply integrated with React's renderer.A generic JavaScript pattern, unaware of React's state system.
CancellationReact automatically discards stale, interrupted renders.Requires manual logic to cancel pending timers.
When to useFor keeping the UI responsive while a slow, non-urgent render is happening.For limiting the rate of API calls or expensive event handlers.

Memory trick: A transition is like letting people pass you in line. Debouncing is like waiting until the line is empty to go.

Topic: Concurrent React Features

🔄 Key Processes

The Event Loop

Step 1: Execute Global Code

  • What happens: The main script runs. Any function calls are pushed onto the Call Stack and executed.
  • Key indicator: Your code starts running from top to bottom.

Step 2: Check the Microtask Queue

  • What happens: The Event Loop checks if there are any tasks in the microtask queue (e.g., from a resolved Promise).
  • Key indicator: .then() or .catch() callbacks are being prepared.
  • Common error: Assuming setTimeout runs before a Promise's .then().

Step 3: Process All Microtasks

  • What happens: If the microtask queue is not empty, the loop takes all tasks from it, one by one, and pushes them onto the Call Stack to be executed. This continues until the microtask queue is empty.
  • Key indicator: A chain of .then() callbacks executing back-to-back without any rendering in between.

Step 4: Check if Rendering is Needed

  • What happens: The browser decides if the screen needs to be updated based on DOM changes.
  • Key indicator: The UI updates on the screen.

Step 5: Check the Macrotask Queue

  • What happens: The Event Loop checks if there are any tasks in the macrotask queue (e.g., a setTimeout callback).
  • Key indicator: A timer has finished, or an I/O operation has completed.

Step 6: Process One Macrotask

  • What happens: The loop takes only one task from the macrotask queue and pushes it onto the Call Stack.
  • Key indicator: A setTimeout callback finally runs.

Step 7: Repeat

  • What happens: The loop returns to Step 2 to check for any new microtasks that may have been queued by the macrotask. This cycle repeats indefinitely.

Topic: JS Runtime & Event Loop


React's Render and Commit Phases

Step 1: Trigger an Update

  • What happens: A state update is triggered by an event (e.g., setState is called).
  • Key indicator: A user clicks a button or data is fetched.

Step 2: Begin the Render Phase (Interruptible)

  • What happens: React starts building a new "work-in-progress" Fiber tree in memory. It calls your components and determines what changed.
  • Key indicator: Your component functions are executed.
  • Common error: Placing side effects (like API calls) directly in the render logic, which might run multiple times.

Step 3: Check for Higher Priority Work

  • What happens: While building the new tree, React checks if a higher-priority task (like user input) has occurred. If so, it pauses the current render.
  • Key indicator: The UI remains responsive even while a complex component is re-rendering.

Step 4: Complete the Render Phase

  • What happens: React finishes building the new Fiber tree in memory. It now knows exactly which DOM changes are needed.
  • Key indicator: React has a complete list of mutations (additions, deletions, updates).

Step 5: Begin the Commit Phase (Synchronous)

  • What happens: React takes the list of changes from the Render Phase and applies them to the actual DOM. This phase cannot be interrupted.
  • Key indicator: You see the visual update on the screen.
  • Common error: Assuming useEffect cleanup functions run before the new UI is visible (they run after).

Step 6: Run Effects

  • What happens: After committing to the DOM, React runs useEffect and useLayoutEffect hooks.
  • Key indicator: API calls inside useEffect are dispatched.

Topic: React Fiber Architecture

⚠️ Common Mistakes

❌ MISTAKE: Mutating state directly, such as myState.push(newItem) or myObject.key = 'new value'.

  • Why it happens: This is a natural instinct from imperative programming. However, React's change detection relies on checking if object references have changed.
  • âś… Instead: Always create a new object or array. Use the spread syntax ([...myState, newItem]) or functional updaters (setState(prev => ({...prev, key: 'new value'}))).
  • Topic: Immutability & Change Detection

❌ MISTAKE: Omitting a dependency from a useEffect or useCallback dependency array to "prevent it from running too often."

  • Why it happens: Developers try to force an effect to run only once, but the effect's code relies on a value that changes, leading to a stale closure.
  • âś… Instead: Include all values from the component scope that are used inside the effect. If a function is causing re-runs, wrap it in useCallback or move it inside the effect.
  • Topic: Closures & Stale State

❌ MISTAKE: Placing an object or array directly in a dependency array, like useEffect(() => {...}, [myObject]).

  • Why it happens: Objects and arrays are re-created on every render, so their reference changes, causing the effect to run every time, even if the contents are the same.
  • âś… Instead: Memoize the object with useMemo (const myObject = useMemo(() => ({ key: 'value' }), [])) or use a primitive value (like myObject.id) in the dependency array if possible.
  • Topic: Memoization & Performance

❌ MISTAKE: Calling hooks inside loops, conditions, or nested functions.

  • Why it happens: It seems logical to conditionally run a hook, but this breaks the stable call order that React relies on to associate state with the right hook call.
  • âś… Instead: Always call hooks at the top level of your component. You can put the conditional logic inside the hook (e.g., useEffect(() => { if (condition) { ... } }, [condition])).
  • Topic: Rules of Hooks Internals

❌ MISTAKE: Using useEffect to derive state from props.

  • Why it happens: It's a common pattern to see props change and want to update some local state in response, but this often leads to bugs and overly complex logic.
  • âś… Instead: Calculate the derived value directly during rendering. If the calculation is expensive, memoize it with useMemo. Example: const fullName = useMemo(() => ${firstName} ${lastName}, [firstName, lastName]);
  • Topic: Closures & Stale State