如果这是一个很大,层级很深的组件,react渲染它需要几十甚至几百毫秒,在这期间,react会一直占用浏览器主线程,任何其他的操作(包括用户的点击,鼠标移动等操作)都无法执行。
- 假如有一个组件更新需要1ms,100个组件需要100ms。当这个时间段内,用户输入一个input框,反馈会非常慢!!!等组件更新完了,才出现在input框内。
Fiber 目的:解决组件 “慢慢无期” 的更新过程中会阻塞页面渲染的问题!(页面卡顿)
ps:同步更新局限:一鼓作气,进行到底!
当 React 决定要加载或者更新组件树时,会做很多事,比如调用各个组件的生命周期函数,计算和比对Virtual DOM
,最后更新 DOM
树,这整个过程是同步进行的。
方案:
改变了之前的渲染机制。
同步渲染改异步
React Fiber 一个更新过程被分为两个阶段(Phase):
第一个阶段 Reconciliation Phase
和 第二阶段 Commit Phase
在第一阶段 Reconciliation Phase
,React Fiber
会找出需要更新哪些 DOM
,这个阶段是可以被打断的;但是到了第二阶段Commit Phase,那就一鼓作气把DOM更新完,绝不会被打断。
phase2的生命周期是不可被打断的,React 将其所有的变更一次性更新到DOM上。
这里最重要的是phase1这是时期所做的事。因此我们需要具体了解phase1的机制。
如果不被打断,那么phase1执行完会直接进入render函数,构建真实的virtualDomTree
如果组件再phase1过程中被打断,即当前组件只渲染到一半(也许是在willMount,也许是willUpdate~反正是在render之前的生命周期),那么react会怎么干呢? react会放弃当前组件所有干到一半的事情,去做更高优先级更重要的任务(当然,也可能是用户鼠标移动,或者其他react监听之外的任务),当所有高优先级任务执行完之后,react通过callback回到之前渲染到一半的组件,从头开始渲染。(看起来放弃已经渲染完的生命周期,会有点不合理,反而会增加渲染时长,但是react确实是这么干的)
也就是 所有phase1的生命周期函数都可能被执行多次,因为可能会被打断重来
image.png总结:
所以,facebook在react16增加fiber结构,其实并 不是 为了 减少组件的渲染时间 ,事实上也并不会减少,最重要的是现在可以使得一些更高优先级的任务,如用户的操作能够优先执行,提高用户体验,至少用户不会感觉到卡顿~
网友评论