2012-07-07 29 views
5

說,我有一個我想用Javascript處理的HTML文件。例如:用於DOM修改的高效Javascript

  • 添加一些DOM元素,如spandiv包裝。
  • 更改文件樣式有點像基本字體大小,行高等。
  • 使用一個接力器來添加­實體。

什麼是最有效的方法來做到這一點,即我想用最少量的迴流做到這一點。

理想的情況是讓JS代碼在第一個佈局之前運行。這可能嗎?我知道,在頁面顯示之前執行昂貴的腳本通常是一個糟糕的主意,這會使頁面看起來空白一段時間,這是一個非常糟糕的體驗。但是,我需要這樣才能脫機工作,這對我的項目來說不是問題。

或者,是否有一種方法可以完成所有dom修改,即所有修改完成後觸發的迴流?

回答

6

有幾種方法。他們的主要目標是最終導致單個或至少儘可能少的迴流/重繪。

關-DOM元素

你可以用要素工作,無需追加到DOM,一旦一切都設置然後就追加一切融合在一起。

唯一的問題是如果您的代碼需要引用偏移量維度,因爲尚未在DOM中的元素沒有任何。

var container = document.createElement('section'); //not in the DOM yet 
//do some extensive work here to prepare the doc 
document.body.appendChild(container); //now we go to the DOM, causing a single re-paint 

文件片段

的更正式的,和可能的改進,對這一主題的變化將是document fragments,這帶來性能上的好處(顯然)。它們實際上是第二個獨立的DOM,沒有顯示。

字符串

可能最快所有這些將是你的文檔建立一個字符串。明顯的含義是你不能使用它的DOM方法,但如果你喜歡字符串處理和REGEX'ing(當然不是理想的HTML),可能值得考慮。最後,如果速度至關重要,並且您有很多計算或字符串處理工作要做,那麼您可能希望利用網絡工作人員。這些不能直接與DOM對話,但可以將任務外包給他們,而且關鍵是,他們在一個單獨的線程上異步工作。

0

我認爲這取決於瀏覽器決定然後重新排列內容。在腳本執行完成之前,他們儘量不要這樣做。這裏需要注意的是,例如,當您將div附加到文檔主體時,會導致DOM重新計算。爲此,您可以使用documentFragment來追加元素,然後將其自身分解到正文。雖然如果你的情況發生,你需要將1個元素添加到不同的容器,它不會有太大的幫助。

上的DocumentFragment附加讀:http://ejohn.org/blog/dom-documentfragments/

-1

我覺得你不能在樣式或DOM元素加載頁面之前工作。 首先加載然後你開始調整頁面。 我會隱藏地調整它並顯示加載頁面。 方法來隱藏:

  1. 一切加載外屏X/Y座標,然後ü把它0,0
  2. DIV其內容的頁面數據有風情:display:none或visibility:hidden的http://www.w3schools.com/css/css_display_visibility.asp檢查這裏細節。
  3. 它可以加載頁面內1像素的iframe,你作爲父頁面擁有者控制子頁面。調整大小調整iframe後,隱藏其框架。
  4. 使用Z索引並放入不透明DIV黑色或白色,隱藏所有內容。當你準備好的時候將它刪除

選擇更適合你的風格。

+0

即使這是真的老了答案,我還是建議不要鏈接到w3schools.com因爲這樣:http://www.w3fools.com/ :) – 2015-06-10 09:44:49

3

document中刪除documentElement,對其進行修改並將其添加回document

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
     <title>...</title>   
    </head> 
    <body> 
     <script type='text/javascript'> 
var docElem = document.documentElement, 
    parentNode = docElem.parentNode, 
    nextSibling = docElem.nextSibling; 
parentNode.removeChild(docElem); // reflow 
// ... 
docElem.lastChild.appendChild(docElem.ownerDocument.createElement('hr')); 
// ... 
parentNode.insertBefore(docElem, nextSibling); // reflow 
     </script> 
    </body> 
</html> 

這觸發兩個迴流和零到兩個額外的重繪。

jsFiddle