崩溃之后面对的是迟钝
上一章我们解决了网页崩溃问题,接下来发现网页中的动画在电脑上顺利执行,IPhone上执行起来有点钝,而在部分入门型Android上非常Lag,接下来让我们找看看问题发生的原因吧
比较运行耗能
我们这次透过 Google Chrome 的 Performance Monitor查看动画运行时的CPU状况
动画準备播放时(左边电脑MacBook Pro, 右边小米s4)
电脑也大概2%, 手机约在15%~25%
动画开始播放(左边电脑MacBook Pro, 右边小米s4)
电脑也大概15%~35%, 手机约在90%~100% 疯狂Lag
由此可知动画耗能过高,电脑其实已经不太正常,但开发用的电脑配备较高所以运作起来顺畅
这个问题在开发电脑版网页时一直没发现,直到现在运行在手机上,问题就爆出来了~
寻找效能消耗点
接下来我们透过Google Chrome Performance 录製了一段耗能状况
在观察FPS较低与CPU使用率较高的片段中发现
原来效能大部分耗费在计算画面更新上
寻找问题得根本
经过测试与寻找,终于找到高耗能的主要问题在这段程式
<style> .effect.is-play { animation: effect-keyframes 6.1s step-end infinite paused; animation-play-state: running; } @keyframes effect-keyframes { 0% background-position-y: 0px; 5% background-position-y: 422px; ....... }</style>
问题其实就出在animation的过程中, 我们变更了background-position-y的位置
详细原因可查看Google Developers
下面简单说明一下
Animations And Performance
浏览器布局的流程大概是这样变更JavaScript/CSS => 计算样式(style) => 布局(Layout) => 绘製(Paint) => 渲染层合併(Composite)
当你变更一个属性(例如: height, width, background-position-y)触发Layout时,浏览器会检查哪些元素需要重新布局,然后对整个页面发送一个reflow(重排), 并完成重新布局
reflow引发重绘,这对于Web的效能影响是极大的
但如果你修改一个DOM元素的“Paint Only”属性(例如:opacity, transform),此属性不影响布局,因此只会触发Repaint的流程,变更本身,然后合併渲染变更JavaScript/CSS => 计算样式(style) => 绘製(Paint) => 渲染层合併(Composite)
只触发Repaint 对效能有极大帮助
解决方法
现在知道问题了,keyframes在动画过程中,不断改变background-position-y,整个画面不停reflow,导致手机的CPU被吃光光,为解决效能问题,下一章节将使用transform取代background-position-y, top, left等等,与使用 opacity来取代display:none
补充知识点
你知道哪些属性是Paint Only吗?
而同一个属性,在各浏览器核心的行为实际上还不一样喔
可透过以下网址查看你的属性是那种
CSS Triggers