一文看懂react渲染原理

31 阅读3分钟

React 的渲染机制是一个复杂但高度优化的系统,结合了声明式编程、虚拟 DOM、Fiber 架构和协调算法(Reconciliation)。以下是其核心原理的深度解析:


一、核心架构分层

React 渲染流程可分为三层:

  1. 组件层:开发者编写的 JSX/组件代码
  2. 协调层(Reconciler):Fiber 架构实现的虚拟 DOM 协调
  3. 渲染层(Renderer):平台相关的 DOM 操作(react-dom/react-native)

二、JSX 到 Fiber 树的转换

  1. JSX 编译
    // 输入
    <div><Component /></div>
    
    // 编译为 React.createElement
    React.createElement("div", null, React.createElement(Component, null))
    
  2. 创建 React Element 对象
    {
      $$typeof: Symbol(react.element),
      type: 'div',
      props: { children: [/* Component元素 */] },
      // ...
    }
    
  3. Fiber 节点创建
    • 每个组件/原生元素对应一个 Fiber 节点
    • 形成树形链表结构(child/sibling/return 指针)

三、Fiber 架构核心设计

1. Fiber 节点结构

{
  tag: FunctionComponent | ClassComponent | HostComponent,
  stateNode: DOM节点/组件实例,
  type: 组件类型,
  key: 唯一标识,
  pendingProps: 新props,
  memoizedProps: 已提交props,
  memoizedState: Hook链表,
  updateQueue: 状态更新队列,
  effectTag: Placement | Update | Deletion,
  nextEffect: 下一个副作用节点,
  // 链表指针
  child: 第一个子节点,
  sibling: 兄弟节点,
  return: 父节点,
  // 调度相关
  expirationTime: 优先级标记,
  alternate: 当前/workInProgress 切换指针
}

2. 双缓存机制

  • current 树:当前渲染的 Fiber 树
  • workInProgress 树:构建中的新 Fiber 树
  • 通过 alternate 属性相互连接

四、协调过程(Reconciliation)

1. 渲染阶段(可中断)

graph LR
A[开始render] --> B[创建RootFiber]
B --> C[构建workInProgress树]
C --> D{是否中断?}
D -- 是 --> E[保存进度]
D -- 否 --> F[完成整树构建]

2. Diffing 算法优化策略

  • 树比较:仅同级比较
  • 元素类型变化:直接销毁子树
  • Key 优化:列表元素移动识别
  • 组件复用:相同类型组件实例保留

3. 副作用收集

  • 构建过程中标记 effectTag
  • 形成副作用链表(effect list)

五、提交阶段(不可中断)

sequenceDiagram
participant Renderer
participant DOM
Renderer->>DOM: 批量处理副作用链表
Note over DOM: 1. 删除旧节点
Note over DOM: 2. 插入新节点
Note over DOM: 3. 更新属性/样式
Renderer->>Renderer: 交换current/workInProgress

六、调度机制

1. 优先级划分

  • Immediate(用户输入)
  • UserBlocking(动画)
  • Normal(数据更新)
  • Low(数据分析)
  • Idle(非必要任务)

2. 时间切片(Time Slicing)

  • 通过 requestIdleCallbackMessageChannel 实现
  • 5ms 时间片划分,防止主线程阻塞

3. 并发模式更新流程

// 使用 createRoot 开启并发模式
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

七、Hooks 运行机制

1. Hook 链表存储

function Component() {
  const [state, setState] = useState(0); // Hook 节点1
  useEffect(() => {}); // Hook 节点2
  // ...
}
  • 每个 Hook 通过 memoizedState 字段链接

2. 状态更新流程

  1. 创建更新对象加入队列
  2. 调度更新(markUpdateLaneFromFiberToRoot)
  3. 进入协调流程

八、性能优化策略

  1. bailout 机制
    • 浅比较 props 和 state
    • 使用 React.memo/shouldComponentUpdate
  2. 批量更新
    • 事件处理函数中的自动批处理
    • React 18 自动批处理所有更新
  3. Suspense 优化
    <Suspense fallback={<Loader />}>
      <AsyncComponent />
    </Suspense>
    

九、渲染生命周期详解

类组件:

graph TD
A[constructor] --> B[getDerivedStateFromProps]
B --> C[shouldComponentUpdate]
C --> D[render]
D --> E[getSnapshotBeforeUpdate]
E --> F[componentDidUpdate]

函数组件:

graph TD
A[运行函数体] --> B[LayoutEffects清理]
B --> C[PassiveEffects清理]
C --> D[State更新]
D --> E[LayoutEffects执行]
E --> F[PassiveEffects执行]

十、异常处理机制

  1. 错误边界
    class ErrorBoundary extends React.Component {
      componentDidCatch(error, info) {
        // 处理错误
      }
    }
    
  2. Suspense 错误捕获
    <ErrorBoundary>
      <Suspense fallback={...}>
        <Component />
      </Suspense>
    </ErrorBoundary>
    

十一、React 18 新特性

  1. 自动批处理
    • 异步操作中的状态更新自动合并
  2. Transition 标记
    const [isPending, startTransition] = useTransition();
    startTransition(() => {
      // 低优先级更新
    });
    
  3. 流式服务端渲染
    • 通过 renderToPipeableStream 实现

十二、底层渲染器实现

  1. HostConfig 接口
    const ReactDOMRenderer = Reconciler({
      createInstance(type, props) {
        return document.createElement(type);
      },
      // 实现50+个宿主方法
    });
    
  2. 跨平台支持
    • react-dom:DOM 操作
    • react-native:Native 组件
    • react-three-fiber:WebGL 渲染

十三、性能分析工具

  1. React DevTools Profiler
  2. User Timing API 集成
  3. Chrome Performance Tab
  4. React 内部性能标记
    import { unstable_trace as trace } from 'scheduler/tracing';
    

十四、设计哲学总结

  1. 声明式优先:UI = f(state)
  2. 渐进式协调:可中断的渲染过程
  3. 优先级驱动:交互优先的更新策略
  4. 跨平台抽象:统一的核心协调器

通过这种分层架构和精细的调度策略,React 能够在复杂应用场景下保持高性能渲染,同时为开发者提供简洁的声明式编程模型。理解这些底层机制有助于编写高性能React代码和深度优化应用。