企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
## react15 架构 * reconciler - 调用组件生命周期,进行diff运算等 * renderer - 渲染页面 * 基于栈的 reconciler,直到执行栈被清空之后,才会将控制权交给浏览器进行渲染 ![](https://img.kancloud.cn/20/56/20568b65a8064da4f78f4bea0b246d6e_757x361.png) ### 遇到的问题 1. 递归算法找出差异的过程不可中断 2. 如果有大量的计算,计算时间超过16ms,UI渲染不能及时进行更新页面,造成卡顿 ## react16 架构 * 优化reconciler,将之前不可中断的递归改成可中断的循环 * 引入 fiber 链表结构 * 将耗时的任务分成很多片,切割运算,分片完成(生成fiber的节点),每生成一个 fiber节点,检查是否有高优先级的任务,如果有,就会交出线程,控制权交还给 reconcile,进行高优先级任务的执行。执行完毕之后,继续生成fiber树 ![](https://img.kancloud.cn/e5/39/e539aa050d188c43325cc20020771ccf_772x428.png) ### fiber * 是一个js对象 * 在虚拟dom的基础上,增加一些额外的信息,比如 return、child、sibling、stateNode ![](https://img.kancloud.cn/21/a2/21a2fa71443c17f09ab793ad5b0b2da3_732x552.png) ### fiber-reconciler ![](https://img.kancloud.cn/24/07/240790987bec71ed9488cb1f93a846f8_601x331.png) ## requestIdelCallback * 将浏览器空闲时间断内执行的函数进行**排队** ![](https://img.kancloud.cn/a1/17/a1174f6a7b92f23706eae0969fb82c09_690x304.png) ### `requestIdleCallback`需要注意的: * `requestIdleCallback`是屏幕渲染之后执行的。 * 一些低优先级的任务可使用`requestIdleCallback`等浏览器不忙的时候来执行,同时因为时间有限,它所执行的任务应该尽量是能够量化,细分的微任务(micro task)比较适合`requestIdleCallback`。 * `requestIdleCallback`不会和帧对齐,所以涉及到DOM的操作和动画最好放在`requestAnimationFrame`中执行,`requestAnimationFrame`在重新渲染屏幕**之前**执行。 * Promise 也不建议在这里面进行,因为 Promise 的回调属性 Event loop 中优先级较高的一种微任务,会在`requestIdleCallback`结束时立即执行,不管此时是否还有富余的时间,这样有很大可能会让一帧超过 16 ms。 ![](https://img.kancloud.cn/d6/ed/d6ed8f7f8f8fca088a6640405896a83f_650x658.png) ### 浏览器的一帧,都在干什么 ![](https://img.kancloud.cn/d0/3e/d03e8d05d2d68a7b9e66b6e5260c2836_2398x447.png) 1. 接受输入事件 2. 执行事件回调 3. 开始一帧 4. 执行 RAF (RequestAnimationFrame) 5. 页面布局,样式计算 6. 绘制渲染 7. 执行 RIC (RequestIdelCallback) ⚠️ 1. 第七步的 RIC 事件不是每一帧结束都会执行,只有在一帧的 16.6ms 中做完了前面 6 件事儿且还有剩余时间,才会执行。 2. 如果一帧执行结束后还有时间执行 RIC 事件,那么下一帧需要在事件执行结束才能继续渲染,所以 RIC 执行不要超过 30ms,如果长时间不将控制权交还给浏览器,会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。