基本概念
-
60fps
60fps是指GPU渲染画面的频率。Hz代表显示器刷新屏幕的频率。
HZ <==> fps
60fps是一个最理想的状态,在日常对页面性能的测试中,60fps也是一个重要的指标,the closer the better!
低于30fps将会明显卡顿! -
浏览器渲染原理
- Main Thread 主线程
- 主线程主要运行js,计算样式,将位图交给绘制线程绘制
- Compositor Thread 绘制线程
- 绘制线程主要通过GPU将位图绘制到屏幕上
- Main Thread 主线程
如果长时间的执行 JS 会阻塞主线程,页面就会出现各种的卡顿。而绘制线程会尽量的去响应用户的交互,页面发生变化时,绘制线程会以每秒60帧(因为每秒60帧是最适合人眼的交互,小于30就会明显感觉到卡顿)的间隔不断重绘页面。
浏览器接收到页面文档后,会将文档中的标记语言解析为DOM树。DOM树和CSS结合后形成浏览器构建页面的渲染树
div {
height: 100px;
transition: height 1s linear;
}
div:hover {
height: 200px;
}
因为每一帧的变化浏览器都在进行布局、绘制、把新的位图交给 GPU 内存(这恰好是我们上面提到的GPU的短板)
div {
transform: scale(0.5);
transition: transform 1s linear;
}
div:hover {
transform: scale(1.0);
}
transform 属性不会改变自己和他周围元素的布局,他会对元素的整体产生影响。
why?
由于JavaScript运行时需要耗费时间,而JavaScript又是单线程的,所以如果一个定时器如果比较耗时的话,是会阻塞下一个定时器的执行。所以即使你这里设置了1000 / 60每秒60帧的帧率,在不同的浏览器平台的差异也会导致实际上你的没有60fps的帧率。
Best Pratics
tips1
硬件加速,强制使用GPU渲染元素。
创建一个新的复合图层,图层在GPU中 transform是不会触发 repaint 的,这一点非常类似3D绘图功能。
- 3D 或者 CSS transform
- <video>和 <canvas>标签
- CSS filters opacity
- 元素覆盖时,比如使用了 z-index属性
tips2
NO JQuery
Javascript 动画很快,而 jQuery 动画很慢。尽管 jQuery 异常强大,但是它的设计目标并不是一个高效的动画引擎。
- jQuery 不能避免 layout thrashing (有人喜欢将其翻译为“布局颠簸”,会导致多余relayout/reflow),因为它的代码不仅仅用于动画,它还用于很多其他场景。
- jQuery的内存消耗较大,经常会触发垃圾回收。而垃圾回收触发时很容易让动画卡住。
- jQuery使用了setInterval而不是 reqeustAnimationFrame(RAF),因为 RAF 会在窗口失去焦点时停止触发,这会导致jQuery的bug。(目前jQuery已经使用了RAF)
内存:如果GPU加载了大量的纹理,那么很容易就会发生内容问题,这一点在移动端浏览器上尤为明显,所以,一定要牢记不要让页面的每个元素都使用硬件加速。