想要达到平滑的动画效果,浏览器需要避免复杂繁琐的工作,比如解析代码,构建渲染树,绘制,布局等等工作。庆幸的是,我们有GPU。 从一个简单例子说起。 假设现在有这样的需求,鼠标移上图标时,图片向右移动300个像素单位,效果大概是下面这样。 http://image98.360doc.com/DownloadImg/2016/07/2110/76297989_1.gif
很自然,人类的理所当然思维会指引我们进坑。
没问题,这能完成我们的任务。 https://dn-w3ctrain./smoother-animation-chrome-timeline1.jpg
(注意这是我故意放大很多倍图片的效果。) 绿色部分表示浏览器在执行Paint操作,我们都知道动画的刷新频率需要保持在60fps以上肉眼才会觉得很顺畅。低于30fps则会让用户感觉到明显卡顿。而这个实验中,浏览器略感吃力。为了能够按时完成任务,浏览器选择跳过部分帧,于是我们就看到走走停停的卡顿效果,这也通常被称为丢帧。 于是我又换成padding-left,jQuery animate方法,然而并没有改善。
https://dn-w3ctrain./smoother-animation-chrome-timeline2.jpg
我的天!质的飞跃有没有,相同动画下还能保持这个高的刷新频率。 查查资料。 reflow,repaint当我们在某个元素上执行动画时,浏览器需要每一帧都检测是否有元素受到影响,并调整他们的大小,位置,通常这种调整都是联动的,我们称为reflow。同样的,浏览器还需要监听元素的外观变化,通常是背景色,阴影,边框等可视元素,并进行重绘,我们称为repaint。每次reflow,repaint后浏览器还需要合并渲染层并输出到屏幕上。所有的这些都会是动画卡顿的原因。
你可以在csstrigger上查找某个css属性会触发什么事件。 CPU,GPU分工在没有GUP的年代,所有任务都是CPU来完成。庆幸的是,这篇文章一开始就说到,我们生活在有GPU的年代。GPU擅长图形计算,这是它的强项。 一个页面上来,浏览器会经过一番处理,生成相应的位图。然后把它们扔给GPU。GPU再拼接位图,合并渲染层,并把最终结果输出到屏幕。 问题根源在《你不知道的Z-Index》中有提到,如果某个元素处于以下状态:
那么就会产生一个新的渲染层(堆叠上下文),这时候执行动画,只需要GPU按照现有的位图,按照相应的变换在独立的渲染层中输出,然后再合并输出。这个过程并不需要主线程CPU的参与。 而当我们使用left,padding,margin,JavaScript,jQuery等方式来执行动画,那么流程就不一样了。 还是举上面的例子,CPU需要重新计算每一帧,元素的位置,外观,重新定位元素,repaint,然后才生成位图,传给GPU渲染。 所以当我们开启GPU渲染的时候,浏览器主线程就能空出来去响应用户输入了。 注意然而并不是所有浏览器默认都会开启GPU渲染,所以通常会用translate3d,translateZ,或者是opacity < 1等来强制开启。 请注意,GUP渲染并不是越多越好,首先它很占内存,在移动端比较耗电, 还可能会有坑。 联系前几天看了前端农民工的一篇文章《CSS3硬件加速也有坑!!!》,里面的Demo也是让我久久不能忘怀。 http://image98.360doc.com/DownloadImg/2016/07/2110/76297989_4.jpg 文中说到如果有一个元素,它的兄弟元素在复合层中渲染,而这个兄弟元素的z-index比较小,那么这个元素(不管是不是应用了硬件加速样式)也会被放到复合层中。
暂时还不是很懂,兄弟元素如何定义。特别是看了源码后稍稍有些困惑, 所以我
动画优化要点总结
关于排错 (12月15)TimeLine面板非常有用,如果你遇到很棘手的性能问题,肉眼看不错哪里有问题,你可以试试把有嫌疑的元素加个 TQ的H5动感影集性能分析非常棒! 推荐阅读
|
|