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

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

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

          先來看看出問題的代碼:

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

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

          簡單的可以這樣優化:
          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"));
          現在此段代碼花費的時間幾乎為0毫秒。

          OK,IE再也不假死了。

          問題分析:
          原因應該就出在jQuery(html)這個方法上,官方文檔解釋如下:
          根據提供的原始 HTML 標記字符串,動態創建由 jQuery 對象包裝的 DOM 元素。 
          你可以傳遞一個手寫的 HTML 字符串,或者由某些模板引擎或插件創建的字符串,也可以是通過 AJAX 加載過來的字符串。但是在你創建 input 元素的時會有限制,可以參考第二個示例。當然這個字符串可以包含斜杠 (比如一個圖像地址),還有反斜杠。當你創建單個元素時,請使用閉合標簽或 XHTML 格式。例如,創建一個 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. 
          因為要構建一個完整的DOM,所以需要花費較長的時間。

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

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

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


          ---------------------------------
          解開權限與業務耦合,提高開發效率
          細粒度權限管理軟件 試用版下載
          http://www.metadmin.com

            回復  更多評論
            
          # re: 一次JQuery性能優化實戰 2016-01-04 17:42 | bns
          不需要構建DOM  回復  更多評論
            
          主站蜘蛛池模板: 安福县| 漳浦县| 新化县| 沁源县| 乌恰县| 江门市| 石河子市| 治县。| 太原市| 漠河县| 萍乡市| 新蔡县| 海阳市| 沂源县| 铜山县| 西城区| 高碑店市| 广河县| 鹤壁市| 乐清市| 策勒县| 临邑县| 宜兴市| 西吉县| 武穴市| 青冈县| 安宁市| 丰城市| 绥阳县| 梅河口市| 桂阳县| 恭城| 靖江市| 济南市| 左贡县| 类乌齐县| 中阳县| 青田县| 虹口区| 三门县| 尚志市|