面试官: 说说 react 的渲染过程
hello,这里是潇晨,大家在面试的过程中有没有遇到过一些和 react 相干的问题呢,比方面试官让你说说 react 渲染的过程,这到题目比拟凋谢,也比拟考验大家对 react 渲染原理以及源码的整体架构的了解。
-
整体流程:
react 的外围能够用 ui=fn(state)来示意,更具体能够用
const state = reconcile(update); const UI = commit(state);
下面的 fn 能够分为如下一个局部:
- Scheduler(调度器):排序优先级,让优先级高的工作先进行 reconcile
- Reconciler(协调器):找出哪些节点产生了扭转,并打上不同的 Flags(旧版本 react 叫 Tag)
- Renderer(渲染器):将 Reconciler 中打好标签的节点渲染到视图上
那这些模块是怎么配合工作的呢:
- 首先 jsx 通过 babel 的 ast 词法解析之后编程 React.createElement,React.createElement 函数执行之后就是 jsx 对象,也被称为 virtual-dom。
- 不论是在首次渲染还是更新状态的时候,这些渲染的工作都会通过 Scheduler 的调度,Scheduler 会依据工作的优先级来决定将哪些工作优先进入 render 阶段,比方用户触发的更新优先级十分高,如果以后正在进行一个比拟耗时的工作,则这个工作就会被用户触发的更新打断,在 Scheduler 中初始化工作的时候会计算一个过期工夫,不同类型的工作过期工夫不同,优先级越高的工作,过期工夫越短,优先级越低的工作,过期工夫越长。在最新的 Lane 模型中,则能够更加细粒度的依据二进制 1 的地位,来决定工作的优先级,通过二进制的交融和相交,判断工作的优先级是否足够在此次 render 的渲染。Scheduler 会调配一个工夫片给须要渲染的工作,如果是一个十分耗时的工作,如果在一个工夫片之内没有执行实现,则会从以后渲染到的 Fiber 节点暂停计算,让出执行权给浏览器,在之后浏览器闲暇的时候从之前暂停的那个 Fiber 节点持续前面的计算,这个计算的过程就是计算 Fiber 的差别,并标记副作用。具体可浏览往期课件和视频解说,往期文章在底部。
- 在 render 阶段:render 阶段的配角是 Reconciler,在 mount 阶段和 update 阶段,它会比拟 jsx 和以后 Fiber 节点的差别(diff 算法指的就是这个比拟的过程),将带有副作用的 Fiber 节点标记进去,这些副作用有 Placement(插入)、Update(更新)、Deletetion(删除)等,而这些带有副作用 Fiber 节点会退出一条 EffectList 中,在 commit 阶段就会遍历这条 EffectList,解决相应的副作用,并且利用到实在节点上。而 Scheduler 和 Reconciler 都是在内存中工作的,所以他们不影响最初的出现。
- 在 commit 阶段:会遍历 EffectList,解决相应的生命周期,将这些副作用利用到实在节点,这个过程会对应不同的渲染器,在浏览器的环境中就是 react-dom,在 canvas 或者 svg 中就是 reac-art 等。
另外咱们也能够从首次渲染和更新的时候看在 render 和 commit 这两个子阶段是如果工作的:
-
mount
时:- 在
render
阶段会依据jsx
对象构建新的workInProgressFiber
树,不太理解Fiber
双缓存的能够查看往期文章 Fiber 架构,而后将相应的fiber
节点标记为Placement
,示意这个fiber
节点须要被插入到dom
树中,而后会这些带有副作用的fiber
节点退出一条叫做Effect List
的链表中。 - 在
commit
阶段会遍历render
阶段造成的Effect List
,执行链表上相应fiber
节点的副作用,比方Placement
插入,或者执行Passive
(useEffect
的副作用)。将这些副作用利用到实在节点上
- 在
-
update
时:- 在
render
阶段会依据最新状态的jsx
对象比照current Fiber
,再构建新的workInProgressFiber
树,这个比照的过程就是diff
算法,diff
算法又分成单节点的比照和多节点的比照,不太分明的同学参见之前的文章 diff 算法,比照的过程中同样会经验收集副作用的过程,也就是将比照进去的差别标记进去,退出Effect List
中,这些比照进去的副作用例如:Placement
(插入)、Update
(更新)、Deletion
(删除)等。 - 在
commit
阶段同样会遍历Effect List
,将这些fiber
节点上的副作用利用到实在节点上
- 在
视频解说(高效学习): 点击学习
往期 react 源码解析文章:
1. 开篇介绍和面试题
2.react 的设计理念
3.react 源码架构
4. 源码目录构造和调试
5.jsx& 外围 api
6.legacy 和 concurrent 模式入口函数
7.Fiber 架构
8.render 阶段
9.diff 算法
10.commit 阶段
11. 生命周期
12. 状态更新流程
13.hooks 源码
14. 手写 hooks
15.scheduler&Lane
16.concurrent 模式
17.context
18 事件零碎
19. 手写迷你版 react
20. 总结 & 第一章的面试题解答