[关闭]
@duanyubin 2016-03-15T01:43:16.000000Z 字数 1875 阅读 417

移动性能优化

移动开发


网页生成的过程

网页生成过程

  1. HTML代码转化成DOM
  2. CSS代码转化成CSSOM(CSS Object Model)
  3. 结合DOM和CSSOM,生成一棵渲染树(包含每个节点的视觉信息)
  4. 生成布局(layout),即将所有渲染树的所有节点进行平面合成
  5. 将布局绘制(paint)在屏幕上

重排(reflow)和重绘(repaint)

导致页面重新渲染的三种情况:

repaint不一定需要reflow 如: 改变某个元素的背景颜色
reflow必然导致repaint 如: 改变元素的大小

导致reflow的操作:

导致repaint的操作

刷新率(fps)

一般的网页动画,需要达到每秒30帧到60帧的频率,才能比较流畅。
demo

要做到每秒60帧,意味着一秒之内60次重新渲染,每次渲染的时间不超过16.66ms
此处输入图片的描述

提高性能的技巧

提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染

1. DOM多个读操作,应该放在一起。不要在两个读操作之间,加入一个写操作

demo

  1. // Bad
  2. var els = document.querySelectorAll('section>div>div');
  3. function animjs(){
  4. for(var i=0; i<len; i++){
  5. els[i].style.left = els[i].offsetLeft+1+'px';
  6. }
  7. }
  8. // Good
  9. function animjs(){
  10. var lefts = [];
  11. for(var i=0; i<len; i++){
  12. lefts.push(els[i].offsetLeft);
  13. }
  14. for(var i=0; i<len; i++){
  15. els[i].style.cssText = 'left:'+lefts[i]+1+'px';
  16. }
  17. }

2. 缓存需要通过reflow才能得到的值

3. 不要一条一条的改变样式,尽量通过改变class或者cssText,一次性改变样式

  1. // bad
  2. var left = 10;
  3. var top = 10;
  4. el.style.left = left + "px";
  5. el.style.top = top + "px";
  6. // good
  7. el.className += " theclassname";
  8. // good
  9. el.style.cssText += "; left: " + left + "px; top: " + top + "px;";

4. 不要改变真实的DOM,尽量使用离线DOM,完成后将此DOM插入到页面中

比如,使用 cloneNode() 方法,在克隆的节点上进行操作,然后再用克隆的节点替换原始节点。

5. 操作display: none的元素不会导致reflow和repaint, visibility: hidden会对repaint有影响

6. position为fixed或absolute的元素,重绘时不会影响父元素,开销较小,为动画的元素增加此属性可提高性能

7. 给动画元素增加transform: translate3d(0)或者will-change

8. 使用window.requestAnimationFrame()调节重新渲染,将某些代码放到下一次重新渲染时执行

  1. // Bad 读操作跟着一个写操作,短时间内触发大量的重新渲染
  2. function doubleHeight(element) {
  3. var currentHeight = element.clientHeight;
  4. element.style.height = (currentHeight * 2) + 'px';
  5. }
  6. elements.forEach(doubleHeight);
  7. // Good 读写分离,把所有的写操作放到下一次渲染
  8. function doubleHeight(element) {
  9. var currentHeight = element.clientHeight;
  10. window.requestAnimationFrame(function () {
  11. element.style.height = (currentHeight * 2) + 'px';
  12. });
  13. }
  14. elements.forEach(doubleHeight);

如何使用Timeline panel

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注