• H5新Api | requestIdleCallback - requestAnimationFram


    浏览器渲染机制

    • 每一轮 Event Loop 都会伴随着渲染吗?
    • requestAnimationFrame 在哪个阶段执行,在渲染前还是后?在 microTask 的前还是后?
      requestAnimationFrame在重新渲染屏幕之前执行
    • requestIdleCallback 在哪个阶段执行?如何去执行?在渲染前还是后?
      requestIdleCallback在渲染屏幕之后执行,并且是否有空执行要看浏览器的调度

    事件循环机制

    作用:事件循环机制的作用是协调事件、用户交互、脚本、渲染及网络任务等。

    宏队列与微队列

    一个事件循环有一个或多个宏队列,有一个微队列

    一个宏队列在数据结构上是一个集合(叫做任务队列),事件循环处理模型会从选定的任务队列中获取一个可运行任务。微队列是FIFO先进先出队列。

    • 宏任务
      • setTimeout、setInterval
      • setImmediate(node 独有)
      • DOM事件、Ajax事件
      • 用户交互、用户操作事件
      • script(整体代码)
      • indexDB操作
    • 微任务
      • process.nextTick
      • Promise一些方法,如.then
      • Async/Await(实际就是promise)
      • MutationObserver(html5新特性)

    浏览器中事件循环流程

    在这里插入图片描述

    • 同步任务和异步任务进入不同的执行环境,同步任务放入执行栈中,异步任务放入任务队列中。
    1. 先执行同步代码
    2. 检查微任务队列,执行并清空微任务队列,如果在微任务的执行中又加入了新的微任务,也会在这一步一起执行。
    3. 进入更新渲染阶段,判断是否需要渲染(根据屏幕刷新率、页面性能等)。并不是每轮事件循环都会执行浏览器渲染
    4. 没有就开启下一轮循环,取出一个宏任务执行。一个宏任务执行完毕后就清空微队列,然后见检查需不需要。循环这个过程

    DOM的修改不会立刻导致渲染,渲染线程和Javascript线程是互斥的,必须等待Javascript的这次调度执行完或线程挂起了,才能执行渲染。
    这次调度可以看成是一轮事件循环完,一次事件循环=宏任务(第一次是同步代码)+微任务
    在这里插入图片描述

    requestAnimationFrame(rAF)

    是什么

    requestAnimationFrame是H5新增的API类似于setTimeout ,告诉浏览器在重新渲染屏幕之前执行。主要用途是按帧对网页进行重绘。

    rAF是官方推荐的用来做一些流畅动画所应该使用的 API,做动画不可避免的会去更改 DOM,而如果在渲染之后再去更改 DOM,那就只能等到下一轮渲染机会的时候才能去绘制出来了

    优势
    调用时机:在重新渲染前调用。
    requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。保证回调函数在屏幕每一次刷新间隔中只执行一次,避免丢帧

    如果浏览器不渲染,是不是就不会调用requestAnimationFrame? 如果requestAnimationFrame做太多事情,会导致降频,比如1s刷新60次变成1s刷新30次。

    requestAnimationFrame API

    基本语法:requestAnimationFrame (callback)
    返回值:回调函数列表中的唯一值,可以使用cancelAnimationFrame传入请求ID取消回调函数。

    说明

    1. requestAnimationFrame不管理回调函数,意思是多次调用带有同一回调函数的 requestAnimationFrame,会导致回调在同一帧中执行多次。
      由rAF的返回值是回调函数列表中的唯一值,可以理解为即使是同一回调函数,但是在回调函数列表中的值都是不一样的。
      所以配合cancelAnimationFrame使用。
    2. requestAnimationFrame() 运行在后台标签页或者隐藏的