我是FE,也是Fe

          前端來源于不斷的點(diǎn)滴積累。我一直在努力。

          統(tǒng)計(jì)

          留言簿(15)

          閱讀排行榜

          評(píng)論排行榜

          datagrid性能(一):性能問題何來?

          使用javascript封裝的一個(gè)datagrid控件時(shí),可能會(huì)提出這個(gè)問題,在datagrid里面顯示1000條數(shù)據(jù),而且需要綁定其click,hover,dblclick事件。(可能你會(huì)覺得這個(gè)需求有點(diǎn)無(wú)聊。為什么要顯示1000行數(shù)據(jù),可以分頁(yè)的。我最開始也這么想,但是分頁(yè)有些問題解決不了,比如,我們需要選中多條數(shù)據(jù)做一個(gè)操作,可能我要選的記錄在第一頁(yè),第n頁(yè)。這樣還需要記錄行選中狀態(tài)。而且可能在分頁(yè)查詢的時(shí)候數(shù)據(jù)已經(jīng)發(fā)生了更改。比如當(dāng)你翻頁(yè)到第二頁(yè)的時(shí)候,第一頁(yè)選中的數(shù)據(jù)已經(jīng)刪除了。這樣選中的數(shù)據(jù)已經(jīng)是“臟數(shù)據(jù)”了。)


          javascript執(zhí)行很慢的時(shí)候?yàn)g覽器會(huì)提示腳本執(zhí)行過慢甚至假死(還是要鄙視一下IE6執(zhí)行js的速度)。但是上面的問題很有可能就會(huì)出現(xiàn)瀏覽器奔潰的情況。所以在實(shí)現(xiàn)這個(gè)功能,不得不審視一下現(xiàn)在的實(shí)現(xiàn)。

          看看下面的jQuery代碼,類似于現(xiàn)有的寫法:

          $(function(){
                      
          var arr = [];

                      
          var date1 =(new Date()).getTime();
                      
          for (var i=0;i<1000 ; i++){
                          arr.push(
          "<tr><td>"+(new Date())+"</td><td>"+(new Date())+"</td><td>"+(new Date())+"</td><td>"+(new Date())+"</td><td>"+(new Date())+"</td></tr>");
                      }
                      
          var $rows= $(arr.join("")).appendTo("#tablebody");
                      
          var date2 =(new Date()).getTime();
                      
          //date2-date1 =453ms
                      
                      
          //事件處理 406ms
                      $rows.click(function(){
                          $(
          "#tablebody .highlight").removeClass("highlight");
                          
          this.className="highlight";
                      }).hover(
          function(){
                          
          this.className="hover";
                      },
          function(){
                          
          this.className="";
                      }).dblclick(
          function(){
                          alert(
          "dblclick");
                      });
                      
          var date3 =(new Date()).getTime();

                      alert((date2
          -date1)+"\n"+(date3-date2));
                  });

          這段代碼在table中新增1000行,然后把監(jiān)聽每行的click,hover,dblclick事件。這個(gè)代碼在IE8上執(zhí)行時(shí)間是0.95s左右(具體時(shí)間因環(huán)境而異)。0.95的時(shí)間去顯示數(shù)據(jù)確實(shí)是讓人難以接受。這個(gè)時(shí)間可能是后臺(tái)數(shù)據(jù)庫(kù)查詢的時(shí)間。這個(gè)時(shí)間其實(shí)還有優(yōu)化的空間。

          第一部分的DOM操作已經(jīng)是比較快的了。這個(gè)時(shí)間會(huì)跟cell中顯示的內(nèi)容直接相關(guān),能夠的做的性能優(yōu)化貌似都做了。jQuery中的appendTo在DOM操作性能上應(yīng)該難以超越了。令我驚訝的是,綁定事件的時(shí)間竟然會(huì)有406ms。與DOM操作時(shí)間同一個(gè)量級(jí)。我用了幾種方法做了對(duì)比:

          //第一種情況:復(fù)雜的事件處理 406ms
                      $rows.click(function(){
                          $(
          "#tablebody .highlight").removeClass("highlight");
                          
          this.className="highlight";
                      }).hover(
          function(){
                          
          this.className="hover";
                      },
          function(){
                          
          this.className="";
                      }).dblclick(
          function(){
                          alert(
          "dblclick");
                      });

          //第二種情況:簡(jiǎn)單事件處理 141ms
                      $rows.click(function(){
                          alert(
          "clicked");
                      }).dblclick(
          function(){
                          alert(
          "dblclick");
                      });


          //第三種情況:使用原生的javascript事件綁定 62ms
                      var rows= document.getElementById("tablebody").getElementsByTagName("tr");
                      
          for (var i=0;i<rows.length ; i++){
                          (
          function (row){
                              row.onclick
          = function(){
                                  alert(
          "clicked");
                              };
                              row.ondblclick
          = function(){
                                  alert(
          "dblclicked");
                              };
                          })(rows[i]);
                      }


          //第四種情況:只是用jquery做選擇器 47ms
                      $rows.each(function(){
                          
          this.onclick= function(){
                              alert(
          "clicked");
                          };
                          
          this.ondblclick= function(){
                              alert(
          "dblclicked");
                          };
                      });

          第一種情況與第二種情況的對(duì)比可以發(fā)現(xiàn)事件綁定的越少,時(shí)間越短。
          第二種情況與第三種情況的對(duì)比可以發(fā)現(xiàn)使用原生的javascript事件綁定會(huì)比jQuery時(shí)間短。這個(gè)貌似有點(diǎn)不好解釋,jQuery封裝的目的可能更在于減少代碼量。jQuery的事件綁定比原生的事件綁定會(huì)有這么大的差別也是讓我驚訝的。
          第三種情況其實(shí)多做了一次DOM選擇,因?yàn)?rows其實(shí)就是新增行jQuery對(duì)象。所以直接用each方法遍歷綁定事件,時(shí)間是最短的。

          總的來說,性能問題不僅僅在于我們理解的DOM操作上面,事件的綁定其實(shí)也是很關(guān)乎性能的。大家平時(shí)是怎么解決這種問題了,歡迎交流。上面的代碼下載

          posted on 2011-01-18 10:25 衡鋒 閱讀(2237) 評(píng)論(5)  編輯  收藏 所屬分類: javascriptJqueryWeb開發(fā)

          評(píng)論

          # re: datagrid性能(一):性能問題何來? 2011-01-18 12:16 凌晨風(fēng)

          其實(shí)沒必要那么較真,一般大數(shù)據(jù)量的業(yè)務(wù)操作很少,現(xiàn)實(shí)中也是很少,分頁(yè)就是解決這個(gè)的,而且你完全可以說服客戶分頁(yè)的好處  回復(fù)  更多評(píng)論   

          # re: datagrid性能(一):性能問題何來? 2011-01-18 12:26 陽(yáng)衡鋒

          @凌晨風(fēng)
          大多數(shù)還是分頁(yè)。有些地方還是不方便。期待下文吧。呵呵  回復(fù)  更多評(píng)論   

          # re: datagrid性能(一):性能問題何來? 2011-01-18 12:29 凌晨風(fēng)

          @陽(yáng)衡鋒
          哈哈 ,期待下文!其實(shí)還有一種分頁(yè)方式就是判斷滾動(dòng)條的距離,完全可以解決大數(shù)據(jù)量的問題  回復(fù)  更多評(píng)論   

          # re: datagrid性能(一):性能問題何來? 2011-02-28 17:39 wjk

          看下jQuery的源碼不久知道了 jQuery為了方便開發(fā)做了很多額外的事情  回復(fù)  更多評(píng)論   

          # re: datagrid性能(一):性能問題何來? 2011-09-16 08:24 tb

          恩 比較不錯(cuò) 值得學(xué)習(xí)   回復(fù)  更多評(píng)論   

          主站蜘蛛池模板: 拜城县| 藁城市| 衡山县| 八宿县| 焉耆| 布尔津县| 元江| 定州市| 乌鲁木齐县| 和田市| 肥城市| 缙云县| 勃利县| 尚志市| 会昌县| 德化县| 清涧县| 同心县| 化德县| 五峰| 漯河市| 武清区| 霍邱县| 长寿区| 嘉荫县| 泰州市| 天水市| 宁化县| 高雄县| 墨玉县| 金秀| 贵德县| 西宁市| 丹凤县| 晋宁县| 湄潭县| 开阳县| 乐昌市| 龙口市| 繁峙县| 大荔县|