react渲染流程是怎样的

整体流程:
在这里插入图片描述
react的核心可以用ui=fn(state)来表示,更详细可以用:

const state = reconcile(update);
const UI = commit(state);

上面的fn可以分为如下一个部分:

  • Scheduler(调度器): 调度任务,排序优先级,让优先级高的任务先进行reconcile
  • Reconciler(协调器): 生成Fiber对象,找出哪些节点发生了改变,并打上不同的Flags(旧版本 react叫Tag),著名的diff算法也是在这个阶段中执行的;
  • Renderer(渲染器): 将Reconciler中打好标签的节点渲染到视图上

调度器

在react16之前,采用的是stack架构,所有任务只能同步进行,无法被打断,导致浏览器出现丢帧情况,表现出卡顿,react为了解决这个问题,从16之后进行了两大更新:

  • 引入Fiber
  • 新增了Scheduler
    Scheduler在浏览器原生API中实际是有类似API的,reqestIleCallback虽然每一帧的绘制时间约为16.66ms,但是若屏幕没有刷新,那么浏览器会安排长度为50ms左右的空闲时间。
    为什么是50ms?
    据研究,100ms以内用户感觉都是瞬时发生的,不会感受到延迟感,因此将空闲时间设置为50,浏览器仍然还剩余50ms。
    后期react打算重新开发这个Scheduler,这意味这调度器不仅仅是在react中使用,凡是有任务调度的项目都可以使用Scheduler。

协调器

协调器是render阶段的第二个阶段,类组件或者函数组件本身就是在这个阶段被调用的。
根据Scheduler调度结果的不同,协调器起点可能是不同的;
performSyncWorkOnRoot(同步更新流程)
会执行workLoopSync这个方法
performConcurrentWorkOnRoot(并发更新流程)

function workLoopSync (){
  while(workProgress != null){
     performUnitOfWork(workProgress)
}
}
function workLoopConcurrentSync (){
  while(workProgress != null && shouldYield()){
     performConcurrentWorkOnRoot(workProgress)
  }
}

新的架构使用Fiber对象来描述dom结构,最终需要形成一棵Fiber tree,不过这棵Fiber树是通过链表形式串联在一起的。
workInProgress代表的是当前的FiberNode

performUnitOfWork方法创建下一个FiberNode,并且还会将已经创建的FiberNode连接起来(child、return、sibling),从而形成一棵链表结构的Fiber tree。
若workInProgress为空,则表示没有下一个FiberNode,也就说整颗Fiber Tree已经构建完毕。

上面两个方法的区别是是否调用了shouldYield方法,该方法表明了是否可以中断。

performUnitOfWork在创建下一个FiberNode 时候,整体分为以下两大块:

  • 递阶段
  • 归阶段

递阶段
从HostRootFiber开始按照深度优先(先找到最底层)原则进行遍历,遍历到的每一个FiberNode执行beginWork方法,该方法会根据传入的FiberNode创建下一级的FiberNode,此时可能存在两种情况:

  • 下一级只有一个元素,beginWork方法会创建对应的FiberNode,并且与workInProgress连接
  • 下一级有多个元素,beginWork方法会依次创建所有的子FiberNode并且通过与subling连接到一起,每个FiberNode也会和workInProgress连接。
<ul>
<li></li>
<li></li>
<li></li>
</ul>

此时会创建3个li对应的FiberNode,连接情况如下:

所有的子Fiber依次连接

Li0Fiber.sibling = Li1Fiber
Li1Fiber.sibling = Li2Fiber
子Fiber还要和父Fiber连接
Li0Fiber.return = UlFiber
Li1Fiber.return = UlFiber
Li2Fiber.return = UlFiber

由于采用的是深度优先原则,因此无法再往下走的时候,会走入归阶段。

归阶段

归阶段会调用completeWork方法来处理FiberNode,做副作用的收集。
当某个FiberNode执行完了completeWork,若存在兄弟元素,就会进入到兄弟元素的递阶段,若不存在兄弟元素,就会进入父FiberNode的归阶段。

我们来看一张图:
在这里插入图片描述

渲染器

Renderer工作阶段称为commit阶段,该阶段会将各种副作用commit到宿主环境的UI中。
相较于之前的render阶段可以被打断,commit阶段一旦开始就会同步执行直到完成渲染工作。

整个渲染过程可以分为三个子阶段:
beforeMutation
Mutation
Layout

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>