H5新Api | requestIdleCallback - requestAnimationFram

本文介绍了浏览器渲染机制,包括事件循环机制,涉及宏队列与微队列、事件循环流程。还讲解了requestAnimationFrame(rAF)和requestIdleCallback两个API,rAF用于按帧重绘网页,requestIdleCallback可在浏览器空闲时间执行任务,文中说明了其API用法、任务拆分及使用场景等。

浏览器渲染机制

  • 每一轮 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() 运行在后台标签页或者隐藏的<iframe> 里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。

requestIdleCallback

对于人眼来说,当每秒切换60张图片时,就会认为是连贯的。所以主流的显示器是60hz的(1s刷新60次),那么每16.7ms需要刷新一次,浏览器会自动适配这个频率,这时对应前端页面就是每16.7ms需要渲染一次。
在这里插入图片描述

页面每隔16.7ms才会渲染一次,那么在两次渲染的中间时间,就是浏览器的空闲时间,在这段空闲时间执行的任务,是不会阻塞到页面渲染的流畅性的。

如果在某一帧区间内执行过多的任务会导致下一帧一直没办法渲染,页面看起来就被卡住。

对大量任务的计算首先考虑Web Worker 使其不占用主线程,如果需要操作DOM,可以考虑任务拆分。

在这里插入图片描述
图中一帧包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值