前端动画优化及性能检测工具使用
前端使用动画可以分为两类:
- css 动画
- js 动画
我们提倡能够使用 css 完成的动画尽量使用 css ( 即使用 animation 和 keyframes )。因为处理 css 是浏览器渲染线程,并不会占用 js 线程,也不会被 js 线程所影响。因而会更加流畅。
但是 css 动画在复杂的场景下并不能满足需求。一些复杂的动画需要通过 js 进行一些计算。如果使用 js 渲染动画可能会出现因为 js 线程忙于计算其他任务,而迟迟不到下一个事件循环导致动画得不到更新,表现出卡顿。
另外,不管是 css 还是 js 动画都要尽量去减少重排和重绘。因为频繁的重排和重绘会使页面的使用流畅度和体验下降。
使用 GPU 运算合成图层
浏览器渲染过程:
DOM树 + CSSOM树 --> render tree --> 分成很多图层 --> GPU 渲染 --> 合成图层
GPU 的工作并不会加速而是会将某个元素拿到一个新的图层中,然后单独进行渲染,然后在动画结束后将多个图层合并到一个图层中,最终展示在浏览器中。将动画分到单独的合成图层中,在每次重排和重绘时,只需要重排重绘自己的图层,而不影响其他图层。
GPU 带来的损耗是内存占用,每个合成层都会有内存损耗,过多的合成层可能会带来性能问题。但总体来说,一些频繁更新的动画使用 GPU 加速更好。
“ GPU 是廉价的”,我们可以去使用 GPU 进行一些动画的渲染和运算。触发 GPU 渲染的css 属性:
- transform 中使用3d ,translate3d 、 scale3d、 rotate3d
- opacity
- will-change
使用window.requestAnimationFrame
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
在每次浏览器重新渲染之前更新动画,我们可以避免无用的更新,替代 setInterval 的更新。
这里写了一个小 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>test</title>
<style>
html {
height: 100%;