前提
1. 浏览器的两个主要线程
2. 两条线程负责的事宜
为什么会造成动画卡顿呢?
原因是主线程和合成线程调度不合理导致的。
当使用width、height、margin、padding作为transition的值时,会造成浏览器主线程的工作量较重。比如left:20px渲染到left:40px。主线程需要计算样式left:21px,left:22px,left:23px,一直到left:40px,而且每一次主线程计算样式后,合成进程都需要绘制到GPU然后再渲染到屏幕上。前后总共进行20次主线程的渲染,20次合成线程渲染,总共40次。
而如果使用transform的话,从transform:translate(0,0)到transform:translate(20px,0)。主线程只需要进行一次transform:translate(0,0)到transform:translate(20px,0),然后合成线程依次将0转换成20px。总共需要21次计算。
例子
从截图可以看出52fps,我们知道当fps大于60秒时候我们才不会感到卡顿,但是52fps必然会有卡顿的感觉。下面是各个阶段耗时:
其中有354ms在运行script,如果此时有其他的js需要执行呢,是不是就会造成阻塞?
另一种实现:
可以看到但使用这种方法时,fps是60,这样用户就没有卡顿的视觉感受了。
各个阶段耗时:
两个图对比,会发现 scripting相差巨大,使用transform各阶段耗时都大大减少。
还有就是使用的时候可以使用translate3d(40px,0,0);因为translat3d会弃用GPU加速。
当代码非常简单的时候,可能不会感觉有什么影响,但是当代码复杂,需要大量的计算时候,一点点的小小细节都是非常重要的。
参考:https://github.com/ljianshu/Blog/issues/51