# camp 4-1 React 设计原理 **Repository Path**: hj-min/fed-e-task-04-01 ## Basic Information - **Project Name**: camp 4-1 React 设计原理 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-10-31 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## React 设计原理 VirtualDOM Diff算法 Fiber 及源码解读 ------ ### 简单题 1. 请简述 React 16 版本中初始渲染的流程 render 阶段负责创建 Fiber 数据结构并为 Fiber 节点打标记,标记当前 Fiber 节点要进行的 DOM 操作。 - 将子树渲染到容器中 (初始化 Fiber 数据结构: 创建 fiberRoot 及 rootFiber) - 判断是否为服务器端渲染 如果不是服务器端渲染,清空 container 容器中的节点 - 通过实例化 ReactDOMBlockingRoot 类创建 LegacyRoot,创建 LegacyRoot 的 Fiber 数据结构 - 创建 container,创建根节点对应的 fiber 对象 - 获取 container 的第一个子元素的实例对象 - 计算任务的过期时间,再根据任务过期时间创建 Update 任务,将任务(Update)存放于任务队列(updateQueue)中。判断任务是否为同步 调用同步任务入口。 - 构建 workInProgress Fiber 树 commit 阶段负责根据 Fiber 节点标记 ( effectTag ) 进行相应的 DOM 操作。 2. 为什么 React 16 版本中 render 阶段放弃了使用递归 在 React 15 的版本中,采用了循环加递归的方式进行了 virtualDOM 的比对,由于递归使用 JavaScript 自身的执行栈,一旦开始就无法停止,直到任务执行完成。如果 VirtualDOM 树的层级比较深,virtualDOM 的比对就会长期占用 JavaScript 主线程,由于 JavaScript 又是单线程的无法同时执行其他任务,所以在比对的过程中无法响应用户操作,无法即时执行元素动画,造成了页面卡顿的现象。 在 React 16 的版本中,放弃了 JavaScript 递归的方式进行 virtualDOM 的比对,而是采用循环模拟递归。而且比对的过程是利用浏览器的空闲时间完成的,不会长期占用主线程,这就解决了 virtualDOM 比对造成页面卡顿的问题。 3. 请简述 React 16 版本中 commit 阶段的三个子阶段分别做了什么事情 commit 阶段可以分为三个子阶段: - before mutation 阶段(执行 DOM 操作前) - mutation 阶段(执行 DOM 操作) - layout 阶段(执行 DOM 操作后) 第一个子阶段: 关键函数 `commitBeforeMutationEffects`, `commitBeforeMutationLifeCycles`。调用类组件的 getSnapshotBeforeUpdate 生命周期函数。 第二个子阶段:关键函数 `commitMutationEffects`, `commitPlacement`, `getHostParentFiber`, `insertOrAppendPlacementNodeIntoContainer`, `insertInContainerBefore`, `appendChildToContainer`。 根据 effectTag 执行 DOM 操作,挂载 DOM 元素。 第三个子阶段:关键函数 `commitLayoutEffects`, `commitLifeCycles`, `commitUpdateQueue`, `commitHookEffectListMount`。调用类组件的 componentDidMount/componentDidUpdate 生命周期函数,和函数组件的钩子函数。处理 render 方法的第三个参数。 4. 请简述 workInProgress Fiber 树存在的意义是什么 在 React 中最多会同时存在两棵 Fiber 树,当前在屏幕中显示的内容对应的 Fiber 树叫做 current Fiber 树,当发生更新时,React 会在内存中重新构建一颗新的 Fiber 树,这颗正在构建的 Fiber 树叫做 workInProgress Fiber 树。 React 使用双缓存技术完成 Fiber 树的构建与替换,实现DOM对象的快速更新。 在双缓存技术中,workInProgress Fiber 树就是即将要显示在页面中的 Fiber 树,当这颗 Fiber 树构建完成后,React 会使用它直接替换 current Fiber 树达到快速更新 DOM 的目的,因为 workInProgress Fiber 树是在内存中构建的所以构建它的速度是非常快的。一旦 workInProgress Fiber 树在屏幕上呈现,它就会变成 current Fiber 树。