隨筆-193  評論-715  文章-1  trackbacks-0

          同事寫了段JQuey的代碼,在某些機器上,會出現(xiàn)IE假死的性能問題。

          我測試了一下代碼花費的時間,在我的機器上,會花費600多毫秒,但在某些機器上會花費6秒多(10倍的增長),這樣就導致了IE的假死。而且發(fā)現(xiàn)與IE版本無關(guān),在大多數(shù)機器上會都只需要600多毫秒,不過CPU會有10%以上的瞬間提長。

          先來看看出問題的代碼:

          $(".eXtremeTable").replaceWith($(html).find(".eXtremeTable"));
          $(
          "#levelGroup").replaceWith($(html).find("#levelGroup"));
          $(
          "#scriptDiv").replaceWith($(html).find("#scriptDiv"));
          其實這段代碼很簡潔,只是將用AJAX取過來的數(shù)據(jù)替換一部分當前頁面的數(shù)據(jù),但性能確實不夠好。

          開始找原因,看看到底是什么慢?
          $(".eXtremeTable").replaceWith($(html).find(".eXtremeTable"));
          將此行代碼分拆,逐元素去分析各自花費的時間:
          $(".eXtremeTable")  花費20毫秒左右;
          $(html).find(".eXtremeTable")  花費200毫秒左右;
          replaceWith()  花費10毫秒左右;
          不難定位到是由于$(html).find(".eXtremeTable")這種方式引起的。
          (這都是在我機器上的測試結(jié)果,而且每次可能不完全一樣)

          簡單的可以這樣優(yōu)化:
          var newPage=$(html);
          $(
          ".eXtremeTable").replaceWith(newPage.find(".eXtremeTable"));
          $(
          "#levelGroup").replaceWith(newPage.find("#levelGroup"));
          $(
          "#scriptDiv").replaceWith(newPage.find("#scriptDiv"));
          但仔細想想,這樣仍然會造成在某些機器上2秒以上的時間消耗,照樣是不可接受的。

          遂采用比較原始的辦法,修改源程序如下:
               var tab='<span id=\"data\">';
                      
          var pos=html.indexOf(tab)
                      
          var content=html.substr(pos+tab.length);
                      
          var pos2=content.indexOf('</span>');
                      
          var content=content.substr(0,pos2);
                      document.getElementById(
          "data").innerHTML=content;
                     
          // $(".eXtremeTable").replaceWith($(html).find(".eXtremeTable"));
                    
                      var counter='<td id=\"counter\" align=\"right\" width=\"300\">';
                      pos
          =html.indexOf(counter)
                      content
          =html.substr(pos+counter.length);
                      pos2
          =content.indexOf('</table>');
                      
          var content=content.substr(0,pos2+'</table>'.length);
                      document.getElementById(
          "counter").innerHTML=content;
                     
          // $("#levelGroup").replaceWith($(html).find("#levelGroup"));

                      var sel='<div id=\"scriptDiv\" style=\"display:none;\">'
                      pos
          =html.indexOf(sel)
                      content
          =html.substr(pos+sel.length);
                      pos2
          =content.indexOf('</div>');
                      
          var content=content.substr(0,pos2+'</div>'.length);
                      document.getElementById(
          "scriptDiv").innerHTML=content;            
                     
          // $("#scriptDiv").replaceWith($(html).find("#scriptDiv"));
          現(xiàn)在此段代碼花費的時間幾乎為0毫秒。

          OK,IE再也不假死了。

          問題分析:
          原因應該就出在jQuery(html)這個方法上,官方文檔解釋如下:
          根據(jù)提供的原始 HTML 標記字符串,動態(tài)創(chuàng)建由 jQuery 對象包裝的 DOM 元素。 
          你可以傳遞一個手寫的 HTML 字符串,或者由某些模板引擎或插件創(chuàng)建的字符串,也可以是通過 AJAX 加載過來的字符串。但是在你創(chuàng)建 input 元素的時會有限制,可以參考第二個示例。當然這個字符串可以包含斜杠 (比如一個圖像地址),還有反斜杠。當你創(chuàng)建單個元素時,請使用閉合標簽或 XHTML 格式。例如,創(chuàng)建一個 span ,可以用 $(
          "<span/>") 或 $("<span></span>") ,但不推薦 $("<span>"
          --------------------------------------------------------------------------------
          Create DOM elements on
          -the-fly from the provided String of raw HTML. 
          You can pass 
          in plain HTML Strings written by hand, create them using some template engine or plugin, or load them via AJAX. There are limitations when creating input elements, see the second example. Also when passing strings that may include slashes (such as an image path), escape the slashes. When creating single elements use the closing tag or XHTML format. For example, to create a span use $("<span/>") or $("<span></span>") instead of without the closing slash/tag. 
          因為要構(gòu)建一個完整的DOM,所以需要花費較長的時間。

          至于為何在某些機器上出現(xiàn)高達6秒多的時間消耗,百思不得其解,請高手指點!

          特別提示:
          本Blog所有內(nèi)容不得隨意轉(zhuǎn)載,版權(quán)屬于作者所有。如需轉(zhuǎn)載請與作者聯(lián)系(
          fastzch@163.com)。未經(jīng)許可的轉(zhuǎn)載,本人保留一切法律權(quán)益。
          posted on 2009-06-14 14:39 Robin's Programming World 閱讀(2659) 評論(7)  編輯  收藏 所屬分類: 其它

          評論:
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2009-06-15 09:16 | HiMagic!
          那你修改后,在別的機器上也是6秒?如果時間還很長,看一下ajax的反應速度。  回復  更多評論
            
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2009-06-15 09:50 | usherlight
          會不會和jquery的版本有關(guān)?據(jù)說1.3之后的版本改進了dom  回復  更多評論
            
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2009-06-15 10:07 | Robin's Java World
          @HiMagic!
          修改后所有的機器都可以達到幾乎0秒!
          因為不需要構(gòu)建DOM了。  回復  更多評論
            
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2009-06-15 11:02 | kane
          不需要構(gòu)造dom卻使用了構(gòu)造dom的方法,而沒有預料到構(gòu)造dom是很耗時的操作。所以說我們使用工具,只有深入了解其特性才能正確地使用  回復  更多評論
            
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2009-06-15 14:43 | Robin's Java World
          @kane
          說得很有道理。  回復  更多評論
            
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2009-06-15 15:47 | metadmin
          真?zhèn)€頁面是DOM嗎?如果是,這無法接受。我更傾向于gwt那樣,在某個div里面嵌入ajax。


          ---------------------------------
          解開權(quán)限與業(yè)務耦合,提高開發(fā)效率
          細粒度權(quán)限管理軟件 試用版下載
          http://www.metadmin.com

            回復  更多評論
            
          # re: 一次JQuery性能優(yōu)化實戰(zhàn) 2016-01-04 17:42 | bns
          不需要構(gòu)建DOM  回復  更多評論
            
          主站蜘蛛池模板: 曲阳县| 夏邑县| 当雄县| 仪征市| 临安市| 浑源县| 吉安市| 韩城市| 桐城市| 绵阳市| 师宗县| 岳普湖县| 贵德县| 襄汾县| 河东区| 平江县| 临安市| 翁牛特旗| 成安县| 盐津县| 合江县| 五大连池市| 沈丘县| 依安县| 施甸县| 双鸭山市| 阿克| 锦屏县| 浦城县| 尚义县| 潜江市| 抚远县| 宜宾县| 深水埗区| 寿宁县| 湘乡市| 佛坪县| 靖边县| 万荣县| 河东区| 二手房|