首先要了解react更新渲染的两个阶段
- 渲染阶段 在这个阶段 React 会更新数据生成新的 Virtual DOM,然后通过Diff算法,快速找出需要更新的元素,放到更新队列中去,得到新的更新队列,以及记录commit 阶段将要执行的生命周期函数。注意:render方法也是在这个阶段调用的,也就是说在render函数内并不能获取dom实例。他只是提供了虚拟DOM tree
- commit阶段 这个阶段 React 会遍历更新队列,将其所有的变更一次性更新到DOM上,并执行上一步调和阶段记录的生命周期函数。commit结束后才可以访问dom实例 并且调用componentDidMount。
版本的差异
在react v16之前更新组件只有两层,分别是:
- Reconciler(调和器)—— 负责找出变化的组件;
- Renderer(渲染器)—— 负责将变化的组件渲染到页面上; 缺点就是采用递归的方式去调和虚拟Dom且这个调和的过程不能被打断。如果是一个很大的项目,很容易卡住页面。 react v16+新增加了一层调度器。分别是:
- scheduler(调度器)—— 负责调度任务的优先级,优先级高的任务有限执行。暂停其他任务。
- Reconciler(协调器)—— 负责找出变化的组件:更新工作从递归变成了可以中断的循环过程。Reconciler内部采用了Fiber的架构
- Renderer(渲染器)—— 负责将变化的组件渲染到页面上;
fiber是什么
在 React 中,Fiber 就是 React 16 实现的一套新的更新机制,让 React 的更新过程变得可控,避免了之前采用递归需要一气呵成影响性能的做法。
- 每个元素都会有一个fiber对象对应。这些fiber对象之间相互关联,构成了fiber tree。
- react fiber的更新过程是碎片化的,一次更新会分为n个任务片。每个片执行完成后就会吧控制权交给调度器。
- 调度器会查看浏览器是否有级别更高的任务(比如:alert,onclick,等),如果有执行这个高级别任务,如果没有继续执行fiber更新。这个功能是基于requestIdleCallback实现的。
这样以来你就不用担心浏览器会卡死现象。