什么是双缓冲?

e1f4d9548195e22c9a8b30d17fd88671.png

以 canvas 为例子,当我们用canvas绘制动画,每一帧绘制前都会调用ctx.clearRect清除上一帧的画面。

如果当前帧画面计算量比较大,我们就很容易因为绘制太慢了出现白屏。为了解决这个问题,我们可以先在内存中绘制当前帧的动画,绘制完毕后,直接用当前帧替换上一帧,这样就省去了两帧的替换时间,不会出现从白屏到出现画面的闪烁情况。这种在内存中构建并直接替换的技术叫做双缓冲。

31dec050c39acfd1331c5fab825b6aba.png

React使用“双缓存”来完成Fiber树的构建与替换——对应着DOM树的创建与更新。

react 根据双缓冲机制维护了两个fiber树,一颗用于渲染页面 (current),一颗是 workInProgress Fiber 树,用于在内存中构建,然后方便在构建完成后直接昔换 current Fiber树。

workInprogress Fiber 树的 alternate 指向 Current Fiber树的对应节点, current 表示页面正在使用的 fiber 树。

当 workInprogress Fiber 树构建完成,workInProgress Fiber 则成为了 current 渲染到页面上,而之前的 current 则缓存起来成为下一次的workInProgress Fiber,完成双缓冲模型。

ff0ca9f905e8781872501270d5d7940f.png

首先要明白,React要完成一次更新分为两个阶段:render阶段和commit阶段,两个阶段的工作可分别概括为新fiber树的构建和更新最终效果的应用。

render阶段

render阶段实际上是在内存中构建一棵新的fiber树(称为workInProgress树),构建过程是依照现有fiber树(current树)从root开始深度优先遍历再回溯到root的过程,这个过程中每个fiber节点都会经历两个阶段:beginWork和completeWork。组件的状态计算、diff的操作以及render函数的执行,发生在beginWork阶段,effect链表的收集、被跳过的优先级的收集,发生在completeWork阶段。构建workInProgress树的过程中会有一个workInProgress的指针记录下当前构建到哪个fiber节点,这是React更新任务可恢复的重要原因之一。

commit阶段

在render阶段结束后,会进入commit阶段,该阶段不可中断,主要是去依据workInProgress树中有变化的那些节点(render阶段的completeWork过程收集到的effect链表),去完成DOM操作,将更新应用到页面上,除此之外,还会异步调度useEffect以及同步执行useLayoutEffect。

这两个阶段都是独立的React任务,最后会进入Scheduler被调度。render阶段采取的调度优先级是依据本次更新的优先级来决定的,以便高优先级任务的介入可以打断低优先级任务的工作;commit阶段的调度优先级采用的是最高优先级,以保证commit阶段同步执行不可被打断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值