2010-09-16 61 views
1

因此,我構建了這個類似於郵件程序的HTML查看器(沒有真正的電子郵件,只是從用戶到用戶的一些消息)。它基本上就像Windows資源管理器一樣,在頂部有標籤,文件可以按日期或按字母順序排序。 每個消息是這樣的:優化dom-heavy JS排序

<div class="mail_msg" d_id="363"> 
    <div class="done"><img src="../"></div> 
    <div class="absender">demo</div> 
    <div class="subject">subject</div> 
    <div class="name">name</div> 
    <div class="date">16.09.2010</div> 
</div> 

頂上所有這些消息,有一個酒吧按字母順序或按日期排序。 (使用prototypejs)

$$('.absender_label','.subject_label', '.bname_label').each(function(el){ 
    el.observe('click', function(){ 

     /* ... */ 

     var tar = el.className.split('_')[0]; 
     var els = $('widget_mail_'+target).select('.mail_msg'), 
      sortedEls = els.sort(function(x, y) { 
       var a = x.down('.'+tar).innerHTML.toLowerCase(), 
        b = y.down('.'+tar).innerHTML.toLowerCase(); 

       return a < b ? -1 : a > b ? 1 : 0; 
      }); 

     $('widget_mail_'+target).select('.mail_msg').invoke('remove'); 
     sortedEls.each(function(x){ 
      if(dir=='bottom') { 
       $('widget_mail_'+target).insert({bottom:x}); 
      } else if(dir=='top') { 
       $('widget_mail_'+target).down('.mail_msg_label').insert({after:x}); 
      } 
     }); 
    }); 
}); 

我知道有太多的DOM操作正在進行。我選擇所有相關的div,對它們進行排序,丟棄所有舊的未排序的消息,並在頂部或底部插入排序的消息(先從A-Z單擊,再從Z-A單擊)。

它仍然適用於數百條消息,但需要2或3秒。我以JSON的形式接收消息並從中解析HTML,因此使用this這樣的表格排序腳本在這一點上不是一種選擇。

如何優化此排序?

+1

如果不知道性能瓶頸在哪裏,不能真正說出來。這個「2或3」秒花費的時間大多是從服務器重新獲取數據,處理這些數據,呈現HTML?你有沒有嘗試在Firebug/Chrome/Safari中使用分析器? – MooGoo 2010-09-16 15:04:48

回答

3

每次用戶排序,您都對數據集進行排序。
然後,每次使用innerHTML將它們呈現爲HTML。

您可以使用JavaScript模板引擎要做到這一點(我造成PURE但也有很多目前可用引擎)

如果一個模板引擎是你矯枉過正,您可以:

  • 字符串化你的HTML上面
  • 爲您的數據每條記錄,建行字符串中填充一些佔位符
  • 拼接線
  • 最後使用的innerHTML
  • 排序數據注入串並重新啓動

雖然它似乎更重,這將是比所有的DOM操作速度更快。

+0

我認爲對JSON進行排序和構建HTML模板並不會產生很大的區別,而不是按現在的方式排序。但是,對HTML進行串聯並對其進行排序是一個有趣的想法。聽起來很奇怪,但速度可能會更快。 – koko 2010-09-17 09:30:09

+0

@koko:不要從HTML開始。從數據開始,然後生成足夠的HTML單元格來保存數據。然後分類並填充單元格。 – 2010-09-17 15:32:03

+0

@koko,這裏是我的模板引擎的例子,但是您應該獲得相同的速度,對數據進行排序並使用字符串:http://gist.github.com/584717 – Mic 2010-09-17 18:40:35

2

您可以使用.detach()從DOM中移除元素,對其進行排序然後顯示它。也許這會加速你的腳本。

+0

我在想同樣的事情。儘管如此,我認爲這不是唯一需要完成的事情;我認爲瀏覽器在儘可能少地迴流方面越來越好。 – strager 2010-09-16 16:23:05

+0

好吧,我沒有使用jQuery。 detach()看起來相當不錯,但是那裏有一個prototypejs等價物嗎? – koko 2010-09-17 09:18:31

+0

我發現這個頁面http://bytes.com/topic/javascript/answers/448176-detach-dom-element – jcubic 2010-09-17 10:30:23

1

你可以通過CSS給元素絕對位置,只是改變它們的位置,而不是操縱DOM。

+1

然而,這完全毀了選擇,並且必然會打破例如當窗口大小發生變化時(在這種情況下,您需要更多*代碼來處理這種情況,從而導致更多的手動迴流)。 – strager 2010-09-16 16:22:01

+0

@strager:好點。這確實不是一個理想的解決方案。 – 2010-09-17 15:28:37

1

向您的JSON數據集添加一個字段,如:相關的DOMElement位置或DOMElement引用。

mail_msg["dom_el_ref"] = createRelatedDomEL(mail_msg); 

做所有排序和比較的東西與JSON數據集。然後按照DOM列表中的順序製作。