此贴接着上面的进行介绍。主要介绍:
1.浏览器自身所作的优化 
2.如何优化你的脚本来减少repaint/reflow? 一.浏览器优化
浏览器对于每一个渲染动作并不是立即执行,而是维护了一个渲染任务队列,浏览器会根据具体的需要分批集中执行其中的任务。除了浏览器自身维护的定期调度之外,脚本中的某些操作会导致浏览器立即执行渲染任务,例如读取元素的Layout属性。
var bodystyle = document.body.style;
var computed;
if (document.body.currentStyle) {
  computed = document.body.currentStyle;
} else {
  computed = document.defaultView.getComputedStyle(document.body, '');
}//每次都读取bodystyle.color = 'red';
bodystyle.padding = '1px';
tmp = computed.backgroundColor;
bodystyle.color = 'white';
bodystyle.padding = '2px';
tmp = computed.backgroundImage;
bodystyle.color = 'green';
bodystyle.padding = '3px';
tmp = computed.backgroundAttachment;//最后再读取bodystyle.color = 'yellow';
bodystyle.padding = '4px';
bodystyle.color = 'pink';
bodystyle.padding = '5px';
bodystyle.color = 'blue';
bodystyle.padding = '6px';
tmp = computed.backgroundColor;
tmp = computed.backgroundImage;
tmp = computed.backgroundAttachment;
每次读取的渲染图:
 
最后读取的渲染图:
 
二、如何优化你的脚本来减少reflow/repaint?
1. 避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行,具体的方法包括但不完全包括以下几种:
(1). 先将元素从document中删除,完成修改后再把元素放回原来的位置
(2). 将元素的display设置为”none”,完成修改后再把display修改为原来的值
(3). 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document
function appendEveryTime(){
    for( var i = 5000; i--; ){
        var n = document.createElement('div');
        n.innerHTML = 'node ' + i;
        document.body.appendChild(n);/*每次创建的新节点都append到文档*/
    }
}function appendLast(){
     var frag = document.createDocumentFragment();
     for( var i = 5000; i--; ){
         var n = document.createElement('div');
         n.innerHTML = 'node ' + i;
         frag.appendChild(n);/*每次创建的节点先放入DocumentFragment中*/
     }
     document.body.appendChild(frag);
}
用dynaTrace观察的结果如下,appendLast的性能无论是在Javascript的执行时间以及浏览器渲染时间方面都优于appendEveryTime。
appendEveryTime:
 
appendLast:
 
2. 集中修改样式
(1). 尽可能少的修改元素style上的属性
(2). 尽量通过修改className来修改样式
(3). 通过cssText属性来设置样式值
如下的代码中,每一次赋值都会造成浏览器重新渲染,可以采用cssText或者className的方式
el.style.color = 'red;
el.style.height = '100px';
el.style.fontSize = '12px';
el.style.backgroundColor = 'white';
3. 缓存Layout属性值
对于Layout属性中非引用类型的值(数字型),如果需要多次访问则可以在一次访问时先存储到局部变量中,之后都使用局部变量,这样可以避免每次读取属性时造成浏览器的渲染。
var width = el.offsetWidth;
var scrollLeft = el.scrollLeft;
4. 设置元素的position为absolute或fixed
在元素的position为static和relative时,元素处于DOM树结构当中,当对元素的某个操作需要重新渲染时,浏览器会渲染整个页面。将元素的position设置为absolute和fixed可以使元素从DOM树结构中脱离出来独立的存在,而浏览器在需要渲染时只需要渲染该元素以及位于该元素下方的元素,从而在某种程度上缩短浏览器渲染时间,这在当今越来越多的Javascript动画方面尤其值得考虑。
HTML代码:
Animation Here
Javascript代码:
var t = $('test');
~function(){
t.style.left = t.offsetLeft + 5 + 'px';
t.style.height = t.offsetHeight + 5 + 'px';
setTimeout(arguments.callee,500);
}();
通过修改#test元素的postion为relative和postion分别得到如下两个测试结果
position: relative
 
position: absolute
 
在postion:relative的测试当中,浏览器在重新渲染时做的工作比position:absolute多了不少。

解决方案 »

  1.   

    var bodystyle = document.body.style;
    var computed;
    if (document.body.currentStyle) {
      computed = document.body.currentStyle;
    } else {
      computed = document.defaultView.getComputedStyle(document.body, '');
    }//每次都读取bodystyle.color = 'red';
    bodystyle.padding = '1px';
    tmp = computed.backgroundColor;
    bodystyle.color = 'white';
    bodystyle.padding = '2px';
    tmp = computed.backgroundImage;
    bodystyle.color = 'green';
    bodystyle.padding = '3px';
    tmp = computed.backgroundAttachment;//最后再读取bodystyle.color = 'yellow';
    bodystyle.padding = '4px';
    bodystyle.color = 'pink';
    bodystyle.padding = '5px';
    bodystyle.color = 'blue';
    bodystyle.padding = '6px';
    tmp = computed.backgroundColor;
    tmp = computed.backgroundImage;
    tmp = computed.backgroundAttachment;
    每次读取的渲染图:
     
    最后读取的渲染图:
     
    二、如何优化你的脚本来减少reflow/repaint?
    1. 避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行,具体的方法包括但不完全包括以下几种:
    (1). 先将元素从document中删除,完成修改后再把元素放回原来的位置
    (2). 将元素的display设置为”none”,完成修改后再把display修改为原来的值
    (3). 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document
    function appendEveryTime(){
      for( var i = 5000; i--; ){
      var n = document.createElement('div');
      n.innerHTML = 'node ' + i;
      document.body.appendChild(n);/*每次创建的新节点都append到文档*/
      }
    }function appendLast(){
      var frag = document.createDocumentFragment();
      for( var i = 5000; i--; ){
      var n = document.createElement('div');
      n.innerHTML = 'node ' + i;
      frag.appendChild(n);/*每次创建的节点先放入DocumentFragment中*/
      }
      document.body.appendChild(frag);
    }
      

  2.   

    fans....          学习。。         
      

  3.   

    配置:
         硬盘:15G
         内存:256M
         IP  :  1个 HK出口(可以提供电信/网通/国际出口)
         Hot backup : 1
    PBS VPS刚买的时候有点担心,因为一个月180块,如果买便宜的VPS,可以买好多个。在买之前我联系了他们试用了两天,打消了我的疑虑。我主要看中了有HK的出口,还有hot backup的功能,而且那里的NOC团队也给我了很大的帮助。在试用的两天,我装了几次系统和遇到了几个问题,他们的NOC团队总是能给我最好的解决。我让我HK和美国的朋友测试一下到我的网站速度,他们的感觉都是好快的。这点我是比较满意的。
    有点不满意的是他们那里提供的VPS只有CentOS版的,我原本想要RHEL版的,不过他那里没有,不过都是相通的,就用了CentOS了。
    好了,大家也可以去试试PBS VPS,有想了解的,可以站内发短信给我。
      

  4.   

    append last 方案有严重的内存泄漏!
      

  5.   

    good, 看来我到习惯是好到:)