FPS
是浏览器的每秒的渲染帧数,也就是浏览器切换画面的次数,大多数设备的刷新率都是 60FPS
,一般来说FPS
越低页面就会越卡顿。
像素管道是浏览器单个帧的渲染流水线,如果其中有某些环节执行过程过长就会导致卡顿
.headline
或 .nav > .nav__item
)计算出哪些元素应用哪些 CSS 规则的过程,这个过程不仅包括计算层叠样式表中的权重来确定样式,也包括内联的样式,来计算每个元素的最终样式。上述的五个阶段并不是一定都会执行到的,这五个阶段中涉及到了老生常谈的两个概念:重排跟重绘,虽然初次渲染布局跟绘制必不可少,但是后期我们可以控制避免通过这两个管道:以下是当我们修改不同的样式属性时,会触发的几种帧流程:
从上图中能看到 JS 阶段以及 Style 和 Composite 阶段 是不可避免的,因为需要 JS 来引发样式的改变,Style 来计算更改后最终的样式,Composite 来合成各个层最终进行显示,能跳过的步骤只有布局跟绘制,我们知道,执行的阶段越少,耗时就越少,每秒的渲染帧数就会越高,那么能不能直接跳过这两个步骤直接到合成呢?答案是肯定的,如下的属性只会触发合成阶段:transform、opacity、pointer-events、perspective (透视效果)、curosr、orphans 设置当元素内部发生分页时必须在页面底部保留的最少行数(用于打印或打印预览)、widows(设置当元素内部发生分页时必须在页面顶部保留的最少行数(用于打印或打印预览))。
综上所述,当我们写动画的时候如果用height
margin
padding
left
等会触发重排的属性,相较于只用transform
或者opacity
会带来更多的性能开销,一旦这个计算时长超过 1 个动画帧 (一般是 60 帧每秒, 也就是说超过 16.7ms), 那么这帧动画将不会绘制,产生页面卡顿。FLIP
技术,就是一种让动画只利用到transform
或者opacity
的技巧,FLIP 是 First, Last, Invert, Play 的简称。
对应动画的 Start 阶段,用 element.getBoundingClientRect()
记录初始位置。