这篇文章记录了自己排查动画问题时的思路,最后的解决有一些侥幸,也是因为最近刚好学习了部分安卓代码,技术视野稍微开阔了些
我们在工作中经常会遇到一些动画卡顿的问题,往往是一些性能比较差的安卓手机,笔者最近就遇到了这样的情况,这里也记录下本次排查问题的过程。
因为页面并不复杂,所以看到页面动画卡顿之后,能够很快速的猜想到是哪些css属性引起的卡顿,通过注释掉代码后,就能够很快的验证自己的推论,这次排查的页面里,导致页面卡顿的是下面这两个属性。
代码语言:javascript复制bg-img {
filter: blur(10px);
}
btn {
animation: scaleAnimation linear 1.5s 1000 2s;
}
@keyframes scaleAnimation {
0% {
transform: scale(1);
}
12.5% {
transform: scale(1.05);
}
25% {
transform: scale(1);
}
37.5% {
transform: scale(1.05);
}
50% {
transform: scale(1);
}
62.5% {
transform: scale(1.3);
}
75% {
transform: scale(1);
}
87.5% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
一开始猜想可能是在1.5s中,定义不同阶段的动画间隔太短,导致了按钮的卡顿,
但是当我只保留了scaleAnimation
中的3个阶段后,发现动画还是能看出来卡顿,
因此应该不是scaleAnimation
的问题,同时我又将filter
样式注释掉后,发现动画变得流畅了。
那最初的结论就是因为
filter
样式导致了动画的卡顿。
那么浏览器filter是怎么实现的呢,为什么会造成这个卡顿呢?
后来就搜到了这篇文章, blur会根据周围像素的值,根据权重计算一个中心点的高斯模糊值,很显然,我们并不是要去优化这个算法,那只能换一个思路:
是否是因为动画,导致每次动画重新渲染时,也引发了背景图片的重绘? 在这个过程中,这篇文章介绍的很清楚, 样式优化会涉及到下面几个环节: style -> layout -> paint -> composite 一般会有下面3种方式的情况:
- 1.修改了一个DOM的layout (影响了布局),比如width,height,那么浏览器就会进行reflow(重排),然后再进行重绘。
-
- 修改了页面的"paint only",比如颜色,阴影这种,那么浏览器就会跳过布局,只会绘制和渲染层合并。
- 3.如果你修改一个非样式且非绘制的CSS属性,那么浏览器完成样式计算之后,会跳过布局和绘制的过程,直接进行渲染层合并。
从我们遇到的问题来看,我们需要优化的是第3种情况,也就是渲染层合并。那么有没有可能是因为我们的背景图片和按钮渲染在了同一渲染层,导致filter每次都要进行重新计算呢?
于是打开chrome的控制台发现,通过translate3d,目前的按钮已经是一个单独的图层了
因此这个按钮图层再触发repaint操作的时候是只会更新自己,不会影响我们的背景图片。 但是为什么开启了硬件加速的动画,会卡顿呢?
目前h5能做的优化内容看起来已经都做了,这个时候难道真的是安卓手机性能太差吗? 于是基本上已经放弃的我想做最后一次验证,就是客户端是否已经开启了硬件加速,因为跑在我们客户端的webview上,我们还是要确认下到底是否开启了硬件加速,不然h5做的这些优化都是白费。
也是最近刚好涉及了一些简单的客户端的开发,很快的在性能差的手机上构建了sdk demo, 再打开webview前加入了这一行代码
代码语言:javascript复制endCardLayout.isHardwareAccelerated();
发现返回居然是false,
看到android官网上介绍,下面这部分代码可以开启窗口级别的硬件加速
代码语言:javascript复制getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
查看android代码后,确实onBeforeCreate
已经开启了硬件加速,
但是看到我们继续定位到webview容器的layout时,发现调用了这么一行代码
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
原来客户端专门针对endcard这个view,关闭了硬件加速
so ga!!!! 成功破案
chrome devtool
- 1、Show paint rectangles 显示绘制矩形
- 2、Show composited layer borders 显示层的组合边界(注:蓝色的栅格表示的是分块)
- 3、Show FPS meter 显示 FPS 帧频
- 4、Enable continuous page repainting 开启持续绘制模式 并 检测页面绘制时间
- 5、Show potential scroll bottlenecks 显示潜在的滚动瓶颈