1
0
Fork 0
Browse Source

vault backup: 2022-04-24 20:42:34

master
YuJian920 3 years ago
parent
commit
2e4d347d7a
  1. 8
      React 的源码深入/React 的流程解析 - Fiber 递归/React 的流程解析 - Fiber 递归.md

8
React 的源码深入/React 的流程解析 - Fiber 递归/React 的流程解析 - Fiber 递归.md

@ -1,14 +1,14 @@
>React 从 16 开始,对底层架构做了一次重构,和 15 不同,渲染 vdom 的时候一改以往的递归执行,引入了一个新的概念,叫做 Fiber,虽然最后渲染到页面的时候还是递归,但是 Fiber 的递归是可以中断的,根据优先级由浏览器优先执行任务,保证在大量视图需要更新的时候,浏览器仍然能保证快速的响应 >React 从 16 开始,对底层架构做了一次重构,和 15 不同,渲染 vdom 的时候一改以往的递归执行,引入了一个新的概念,叫做 Fiber,虽然最后渲染到页面的时候还是递归,但是 Fiber 的递归是可以中断的,根据优先级由浏览器优先执行任务,保证在大量视图需要更新的时候,浏览器仍然能保证快速的响应
在 React 中,视图的更新使用了双缓存的方式,也就是说在 React 运行时,同时有着两棵 Fiber 树,一颗是当前视图上的 Fiber 树,叫 `current`,另外一棵是存在内存当中的下一次视图更新时用的叫做 `workInProgress`,React 在构建时会创建整个 app 唯一的根 Fiber 节点,叫做 `FiberRootNode`,这个节点上有一个 `current 指针`,指向的是当前正在页面上显示的 Fiber 树也就是 `current`,当 `workInProgress` 递归生成完毕,指针会立即指向 workInProgress ,而旧的 `current` 就会在下一次渲染中变成 `workInProgress` ,就这样循环交替完成页面的递归渲染 在 React 中,视图的更新使用了双缓存的方式,也就是说在 React 运行时,同时有着两棵 Fiber 树,一颗是当前视图上的 Fiber 树,叫 `current`,另外一棵是存在内存当中的下一次视图更新时用的叫做 `workInProgress`,React 在构建时会创建整个 app 唯一的根 Fiber 节点,叫做 `FiberRootNode`,这个节点上有一个 `current 指针`,指向的是当前正在页面上显示的 Fiber 树也就是 `current`,当 `workInProgress` 递归生成完毕,指针会立即指向 workInProgress ,而旧的 `current` 就会在下一次渲染中变成 `workInProgress` ,就这样循环交替完成页面的递归渲染
本次源代码解读的 DEMO 只用了最简单的 `useState` 做计数器修改触发页面刷新,并没有新增新的DOM 节点之外的其他操作,第一次和第二次和之后页面刷新实际上都只是 `useState` 触发变化并在页面上显示计数内容出现变化 本次源代码解读的 DEMO 只用了最简单的 `useState` 做计数器修改触发页面刷新,并没有新增新的 DOM 节点之外的其他操作,第一次和第二次和之后页面刷新实际上都只是 `useState` 触发变化并在页面上显示计数内容出现变化
## 首屏渲染 ## 首屏渲染
### createWorkInProgress ### createWorkInProgress
React 的首屏渲染时会交由 `createWorkInProgress` 函数生成一个 WorkInProgress Fiber 节点,这个节点就是 FiberNode,`createWorkInProgress` 接收两个参数,分别是 `current``pendingProps`,这里的 `pendingProps` 是组件的属性 React 的首屏渲染时会交由 `createWorkInProgress` 函数生成一个 `WorkInProgress Fiber` 节点,这个节点就是 FiberNode,`createWorkInProgress` 接收两个参数,分别是 `current``pendingProps`,这里的 `pendingProps` 是组件的属性
因为传入的是 current Fiber 树,所以 `createWorkInProgress` 内会从 `current``alternate` 取出中取出与之链接的 WorkInProgress Fiber 节点,并对其做空值判断,因为对于首屏渲染而言,WorkInProgress 是不存在的,所以会走到不存在 WorkInProgress 的逻辑,在这里也就是调用 `createFiber` 函数,这个函数会更加传递的参数 `new` 一个 Fiber 的实例,其内部并没有什么复杂的逻辑,而是对 Fiber 节点的属性进行了初始化,`createFiber` 返回之后,会对返回的 FiberNode 节点进行赋值,复用 current FiberNode 节点的内容,并对它们各自的 alternate 进行赋值,双向链接 因为传入的是 `current Fiber` 树,所以 `createWorkInProgress` 内会从 `current``alternate` 取出中取出与之链接的 `WorkInProgress Fiber` 节点,并对其做空值判断,因为对于首屏渲染而言,`WorkInProgress` 是不存在的,所以会走到不存在 `WorkInProgress` 的逻辑,在这里也就是调用 `createFiber` 函数,这个函数会更加传递的参数 `new` 一个 Fiber 的实例,其内部并没有什么复杂的逻辑,而是对 Fiber 节点的属性进行了初始化,`createFiber` 返回之后,会对返回的 FiberNode 节点进行赋值,复用 `current FiberNode` 节点的内容,并对它们各自的 `alternate` 进行赋值,双向链接
`createWorkInProgress` 之后,Fiber 的操作就会交由 `beginWork``completeWork` 开始正式的递归 `createWorkInProgress` 之后,Fiber 的操作就会交由 `beginWork``completeWork` 开始正式的递归
### beginWork ### beginWork
@ -141,4 +141,4 @@ createInstance 会调用 createElement 方法创建一个 DOM 实例,并调用
completeWork 逻辑结束 completeWork 逻辑结束
你可以会问我,到这里就没有了吗?,是的没有了,这就是一个简单例子下 React Fiber 递归的全部流程,从 beginWork 到 completeWork,从首屏渲染到触发更新,可以从中看到 你可以会问我,到这里就没有了吗?,是的没有了,这就是一个简单例子下 `React Fiber` 递归的全部流程,从 `beginWork``completeWork`,从首屏渲染到触发更新,没有涉及到新增节点和删除属性的情况,但是简单的递归逻辑已经是到这里就结束了,后边还会写更加详细的单个 render 阶段函数的详细解析和 commit 阶段的流程解析
Loading…
Cancel
Save