react渲染
react渲染机制
注意:知道这个如何在面试中成为亮点:当问到vue渲染的时候,可以穿插着和react渲染做对比,这样才显示出两个框架都熟悉
我们通常认为的渲染的过程是指:从template模版编译到最后dom更新,这整个阶段都可以认为是渲染。但是在react中其实应该更细一点,我们可以把react分为渲染和提交,这里的提交就是更新到dom上。
react渲染主要分为两个阶段,三块功能 (1)schedule调度 (2)reconcile协调 (3)render渲染
一、schedule调度
1.1 什么是调度?为什么需要调度?
想象一个场景,当我们只有一个js引擎来执行的时候,如果有多个任务,那么为了保证尽可能好的用户体验丝滑,我肯定需要对这些要处理的任务进行优先级划分,等级高的我优先执行。这种处理不同优先级任务放入到引擎中执行的机制就是调度。此外,还有一种场景,当我们把某一个优先级高的任务放入到引擎中执行的时候,如果这个任务执行时间是100ms且同步执行不可中断,那么就会产生延迟(浏览器中的延迟定义是: 浏览器渲染周期是60hz,一秒钟执行60次,每次执行16.6ms,如果长时间霸占引擎超过100ms,就会产生用户感知。)因此需要在16.6ms的时候如果一个任务执行不完,那么先中断,等待下个浏览器渲染周期到来之后再继续执行。而不是一直霸占着引擎直到执行完毕。这种处理单个任务中断&继续执行的机制也是调度。 这种调度其实是一种模式,即Concurrent并行模式(之前Legacy mode 同步阻塞模式,会阻塞渲染)
总结:调度的功能就是:1.多个任务的优先级划分;2.当个任务的时间片内的任务中断和恢复
浏览器相关知识 知识点1 : 理解浏览器一帧周期 浏览器以16.6ms为周期内,做了哪些事情? 1.事件处理时期 2.js执行时期 3.视图绘制时期 4.浏览器空闲时期
知识点2: 认识浏览器API - requestIdleCallback( callback, options ) idle是空闲的意思,requestIdleCallback就是请求空闲函数,该函数是浏览器提供给外界在浏览器一帧周期内中“空闲时间周期”自动执行的函数,通常用来执行不重要的任务,以确保这些任务的执行不会阻塞主线程,进而提高页面的响应性。
// deadlineObj中主要的参数 { timeRemaining: () => {} // 返回当前帧还剩的时间 didTimeout: true // 表示回调函数是否在timeout超时时间之前就已经执行 } const ID = requestIdleCallback((deadlineObj) => { // deadlineObj为当前帧对象,可以通过该对象查看当前帧的一些情况,例如当前帧还剩下多少空闲时间 deadlineObj.deadlineObj() // 当前帧剩余的毫秒数 }, {timeout: 1000}) // 这里的 timeout 是指,当过了timeout之后,该回调函数依然没有执行的话,那么就需要将这个回调放入到事件循环队列中执行 window.cancelIdleCallback(ID) // 通过将对应的ID传入调用的window.cancelIdleCallbeck,则可以取消调用 // // 注意:如果多个回调调用requestIdleCallback的话,那么就都会放入到一个统一队列中,先进先出。
举例:
requestIdleCallback((deadline) => { console.log(deadline.timeRemaining()) }, {timeout: 1000})
打印结果:剩余时间是35.6ms,有人会问,不是一帧16.6ms吗,怎么剩余时间比一帧周期时间还要长呢?
因为我们对“空闲时间”的认知和定义过于狭隘: (1)当出现短时间内多次屏幕刷新的时候,那么浏览器会严格按照一帧16.6ms最小间隔去执行事件处理&屏幕刷新,这就是最小刷新间隔,这里存在一个空闲时间 (2)如果屏幕空闲时间很长,那么下一次刷新可能要等很久(用户不交互就不刷新),那么浏览器也不能一直处于空闲时间,因此也要给他一个最大时间限制 - 50ms
知识点3: 认识浏览器API - requestAnimationFrame 请求动画帧这个API本意上是专门用来处理动画的,因为之前如果使用定时器来做动画(每个100ms变换坐标来实现位移的效果)此时就会出现抖动现象,但是如果使用请求动画帧这个API就会丝滑很多。 那么为什么请求动画帧比定时器丝滑?因为他在特定的时间点进行代码执行,而定时器与绘制频率周期没有保持共振,这就导致前两个周期绘制一次,然后在等一个周期绘制一次,在等3个周期绘制一次。这样就会导致下个绘制周期动画不变,造成视觉上感知到短暂静止,连续起来就会形成卡顿。而绘制动画帧就就是保证每次渲染都会执行,这样的严格卡点就会感觉很丝滑。
1.2 怎么调度(react中调度的机制流程)
设定一下任务优先级 react在内部定义了 5 种类型的优先级,以及对应的超时时间timeout
ImmediatePriority, 直接优先级,对应用户的 click、input、focus 等操作; timeout为 -1,表示任务要尽快处理; UserBlockingPriority,用户阻塞优先级,对应用户的 mousemove、scroll 等操作;timeout 为 250 ms; NormalPriority,普通优先级,对应网络请求、useTransition 等操作; timeout 为 5000 ms; LowPriority,低优先级(未找到应用场景);timeout 为 10000 ms; IdlePriority,空闲优先级,如 OffScreen; timeout 为 1073741823 ms;
5 种优先级的顺序为: ImmediatePriority > UserBlockingPriority > NormalPriority > LowPriority > IdlePriority。
转载自:https://juejin.cn/post/7358450927115272226