H5新Api | requestIdleCallback - requestAnimationFram

文章目录

  • 浏览器渲染机制
    • 事件循环机制
      • 宏队列与微队列
      • 浏览器中事件循环流程
    • requestAnimationFrame(rAF)
      • requestAnimationFrame API
    • requestIdleCallback
      • requestIdleCallback API
      • 任务拆分
        • requestIdleCallback的使用场景

浏览器渲染机制

  • 每一轮 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新特性)

浏览器中事件循环流程

H5新Api | requestIdleCallback - requestAnimationFram_第1张图片

  • 同步任务和异步任务进入不同的执行环境,同步任务放入执行栈中,异步任务放入任务队列中。
  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() 运行在后台标签页或者隐藏的