一、背景:
智能终端的普及改变了人们对互联网的使用习惯,终端环境对页面性能有更高的要求,接下来以一张图来分析:1s内渲染一个移动页面
网络整体消耗来分析:
1、服务器响应应该小于200ms
2、尽量少的重定向
3、尽量少的第一次渲染的请求
4、避免过多堵塞的js和css堵塞
js执行效率和渲染效率:
1、给浏览器留的200ms渲染时间
2、优化我们的js执行效率和渲染时间
二、主要的web性能优化
页面请求:DNS Lookup、减少重定向、并行请求、压缩、缓存、按需加载、前端模块化
运行环境:交互、动画、滚动、内存和GC、FPS
三、渲染问题的思考
1)智能终端与pc的性能差异巨大
x86的性能是ARM的5倍以上甚至更多,原先存在的许多性能问题被掩盖,终端市场爆发后,问题随之而来,表现在下面一些情况:
-用户所持的终端CPU优劣差异巨大
-运行速度慢
-用户操作卡顿
-内存不足
-本地存储空间不足
-可控的资源有限
-...
2)IOS与Android硬件对比
早期为何大家会觉得iphone比android手机好用?
流畅性:流畅的动画和滑动
节能:省电
稳定:很少crash
操作系统 | 型号 | CPU | RAM |
iphone | 4s | 双核A5 800MHZ | 512M |
iphone | 4 | A4 800MHZ | 512M |
iphone | 3GS | S5PC100 600MHZ | 256M |
Android | Glaxy Note | Exynos 双核 1.4GHZ | 1G |
Android | Nexus One | 高通 1GHZ | 512M |
Android | MOTO XT615 | 高通 800MHZ | 512M |
Android | HTC Legend | 高通 600MHZ | 384M |
四、性能优化度量
一切性能优化都建立在可衡量的数据分析基础之上,不能去优化那些不能衡量的东西
1)判断渲染性能的标准
帧数:
-显示设备通常的刷新率,一般是50~60HZ
- 1000ms/60 = 16.6ms (1毫秒的优化意味着6%的性能提升)
2)浏览器渲染引擎:在FF中,Layout的过程叫reflow,Painting过程叫repaint
3)浏览器渲染的丢帧现象
4)性能调试工具:chrome调试器的Timeline,Timeline有两个常用的模式。
Events模式,如图:
Frames(chrome特有)模式,如图
小提示:
a) Timeline记录行为的快捷键是ctrl + E(Mac: Cmd + E)
b) 灰色区域是非渲染引擎发生的渲染行为
c) 透明的线框,是在两次显示器刷新周期中的等待时间
5)避免常见的重复渲染:保证每帧最多只发生2次“更新渲染树”行为
6)避免重复的布局计算:requestAnimationFrame(后面简称RAF)
a) 小提示:Timeout和raf其实是工作在同一个线程,当CPU非常繁忙的时候RAF的执行同样被堵塞。
b) event行为与RAF控制的区别如下:
直接通过event行为触发渲染浪费的渲染帧,不会被硬件帧最终显示
通过RAF控制渲染频次,合并了大量event的计算,减少了无效的渲染次数
7)导致页面重绘
糟糕的DOM操作
小提示:chromium的源码中,updateLayoutIgnorePendingStylesheets()方法就是用来忽略备用的样式重新计算布局
良好的DOM操作
小提示:缓存需要使用的Dom属性,可以更好的进行读写分离
7)避免重复的渲染行为
a) 使用RAF来控制动画在合理的刷新时间内
b) 保证渲染引擎的原子操作,批量dom进行读写分离
c) 不同样式在渲染模式的不同表现,如下图
五、实现平滑的动画
1)DOM动画的四大神器
位移:transform: translate(npx, npx);
缩放:transform: scale(n);
旋转:transform: rotate(ndeg);
透明:opacity: 0 ~ 1;
六、交互动画优化
1)GPU加速(Composite):GPU在浏览器中是如何工作的?
高端浏览器中(webkit, chrome),Painting行为是CPU为GPU准备纹理素材。
小提示:chrome调试器中可以开启show composited layer borders查看图片纹理素材
2)可以利用的GPU优势:纹理缓存和图形层
GPU Hack:
a)、-webkit-transform: translate3D(0px, 0px, 0px); // 创建Layout,并且在GPU中进行图层移动。
b)、强制把需要进行动画行为的dom对象,在GPU中创建Layout缓存
-webkit-transform: translateZ(0); // 创建Layout,并缓存。
-webkit-backfface-visibility: hidden;
常见的属性有如下:translateZ、Perspective、backface-visibility、scaleZ、RotateZ、RotateX、RotateY、Translate3D、Scale3D、Rotate3D
3)合理使用GPU加速
a)、使用GPU加速,其实是利用了GPU层的缓存,让渲染资源可以重复利用。
b)、GPU加速是把双刃剑,过多的GPU层同样会带来性能开销,请留意Composite Layouts是否超出了16ms。
c)、只在用户行为和动画需要的场景去创建GPU层,但是需要及时回收。
4)css3动画的一些注意事项
a) 单独使用translate2D并不会独立产生GPU层,不会在GPU中进行合成。
b) CSS的补间动画配合translate2D,可以在GPU中产生一次临时的层以进行运算,但是遇到“布局计算”的变化则无效。
c) CSS3动画通常是不被阻塞的。你可以获得独立的线程进行绘制
小技巧:
1、如果需要完全避免渲染树的计算,可以考虑Canvas
2、使用classList代替className,不过在chrome33 dev普通的"className="已经可以同名判断,来减少样式的重复渲染