1. Understanding React Fiber Architecture
React Fiber is a redesigned architecture introduced in React 16 to resolve performance bottlenecks and improve maintainability for large-scale applications. Its core objective is Incremental Rendering: splitting rendering work into discrete small tasks that execute during the browser’s idle periods. This prevents long-running tasks from blocking the main thread and drastically boosts page responsiveness.
Core Fiber Concepts
Fiber Node: A lightweight data structure representing the work unit of a component or native DOM element. Each Fiber node stores component state, instance, type and other metadata. All connected Fiber nodes form the Fiber Tree, which maps one-to-one with the React component tree.
Double Buffering: Two separate Fiber trees are maintained at all times. The
current Fiber treecorresponds to content already rendered on screen, while thework-in-progress (WIP) Fiber treeis built for pending updates. React applies all modifications to the WIP tree instead of mutating the live displayed tree directly. Once construction finishes, the WIP tree switches to become the new current tree.Two-Phase Render Pipeline: Rendering is split into Reconciliation and Commit phases.
1. Reconciliation Phase: Traverses the Fiber tree to mark nodes requiring updates; this phase is interruptible and resumable to fit spare browser runtime.
2. Commit Phase: Applies scheduled DOM modifications from reconciliation; non-interruptible to guarantee consistent page rendering.
Task Prioritization: Update tasks are assigned distinct priorities based on scenario (user interaction, animation, data fetching etc.). High-priority jobs execute first to optimize user experience.
With the Fiber architecture, React efficiently governs component updates and rendering, delivering superior performance for complex projects.
2. JSX-to-DOM Rendering Flow
JSX is syntactic sugar enabling HTML-like markup to define component layout and attributes. It must compile into standard JavaScript before rendering to native DOM elements. The conversion pipeline proceeds in five key steps:
1. JSX Compilation: Completed at build time via tools such as Babel. Code like <div className="container"></div> transpiles into React.createElement('div', {className: 'container'}, null).
2. Create React Element: React.createElement() generates a lightweight React Element object carrying element type, props and child information. This object is a virtual DOM descriptor rather than an actual DOM node.
3. Trigger Render: State or prop changes trigger component re-render, prompting React to generate corresponding real DOM nodes from React Element objects and mount them into the live DOM tree. Relevant lifecycle hooks (componentDidMount, componentDidUpdate) execute during this stage.
4. Reconciliation: The diffing algorithm compares old and new virtual DOM trees to pinpoint changed nodes and eliminate redundant DOM manipulation.
5. Commit DOM Updates: Modifications including node creation, update and deletion are committed to the real DOM in the non-interruptible Commit phase.
In short: JSX Compile → Create React Element → Render Trigger → Reconciliation → DOM Commit.
3. React Performance Optimization
Below are mainstream optimization approaches to accelerate application responsiveness:
1. React.memo: Higher-order component for function components; skips unnecessary re-renders when props remain unchanged via shallow comparison.
2. shouldComponentUpdate / PureComponent: For class components: customize shouldComponentUpdate to manually control re-render logic; inherit PureComponent for built-in shallow prop & state comparison.
3. Code Splitting: Split large bundles into chunks with dynamic import() and bundlers like Webpack for on-demand loading and reduced initial load cost.
4. Optimize Event Handlers: Avoid inline function declarations inside render; bind class methods upfront or cache callbacks with useCallback.
5. React.lazy + Suspense: Lazy-load components only when needed; render fallback placeholders while components load via Suspense.
6. Virtualized List: Adopt libraries such as react-virtualized for lengthy lists to render only viewport-visible items.
7. React.Fragment: Wrap multiple child nodes without generating extra redundant DOM wrapper elements.
8. useMemo: Cache expensive calculated values to avoid repeated computation on every render.
9. Prefer CSS Classes over Inline Styles: Inline styles instantiate new objects each render and may trigger redundant updates.
10. React.Profiler: Built-in profiling API to locate render bottlenecks for targeted tuning.
4. Async/Await in useEffect
The useEffect callback cannot directly return an async function. Wrap asynchronous logic in an inner invoked function:
useEffect(() => {
const asyncFun = async () => {
setPass(await mockCheck());
};
asyncFun();
}, []);IIFE shorthand version:
useEffect(() => {
(async () => {
setPass(await mockCheck());
})();
}, []);5. React Diff Algorithm
The Diff algorithm efficiently contrasts virtual DOM revisions and syncs changes to native DOM, a process named Reconciliation.
Core Rules
1. Same-Layer Comparison Only: Nodes are compared strictly within identical DOM hierarchy levels, cutting algorithm complexity from O(n³) down to O(n).
2. Different Node Types:
Mismatched component type: Destroy old node plus its entire subtree, then construct a brand-new node branch.
Matching component type: Preserve the existing DOM node and recursively diff child elements.
3. Key Attribute for List Items: Unique key marks list nodes to track addition, deletion or reordering:
Identical key: Reuse existing DOM node and update props/children;
Different key: Discard old node and instantiate a new DOM element.
Four DOM Operations
Insert: Add nodes existing only in the new virtual DOM tree;
Delete: Remove nodes exclusive to the old virtual DOM tree;
Move: Reposition matching-key nodes appearing in new locations;
Update: Patch attributes/content for matching-key nodes staying in place.
Execution Steps
1. Traverse old and new virtual DOM trees layer by layer starting from root;
2. Check node type: replace entirely when types mismatch;
3. Leverage key to efficiently diff list components;
4. Generate the minimal set of DOM updates and apply changes to real DOM.