加快DHTML 的一組技巧
作者:Eve Cole
更新時間:2009-06-20 16:59:57
動態HTML (DHTML )在Microsoft? Internet Explorer 4.0中的
引入,使Web作者和開發人員可以使用新的程式設計模型。此後,Web 作者充
分利用了這個強大的特性來提供動態內容、樣式和定位,讓網路使用者得以
體驗豐富的互動功能。 DHTML 的彈性使得通常會有多種方式可以實現
您的構思。瞭解Internet Explorer的HTML 分析和顯示元件如何處理請
求,可協助您確定完成工作的最佳方法。本文介紹了某些DHTML功能對性
能的重大影響,並提供了一些提高頁面效能的技巧。
成批處理DHTML 更改
在DHTML Web頁面上,提高效能最有效的方法是改善對頁面上HTML
內容的變更。有許多方法可以更新Web頁面,了解這一點非常重要。從客
戶的回饋來看,Web 筆者可以應用HTML 文字區塊,也可以透過使用DHTML
物件模型(英文)或W3C文件物件模型(DOM )(英文)來存取個別HTML
元素。無論何時變更HTML 內容,Internet Explorer 的HTML 分析與顯示
示元件都必須重新組織該頁面的內部表現形式,重新計算文檔佈局和文檔
流,並顯示這些變化。雖然實際效能由Web頁面的內容和您所做的更改決
定,但是這些操作代價都比較大。如果您套用HTML 文字區塊,而不是個別
存取元素,則必須呼叫HTML分析器,這將導致額外的效能開銷。接受HTML
文本的方法和屬性包括insertAdjacentHTML (英文)和pasteHTML(英
文)方法,以及innerHTML(英文)和outerHTML(英文)屬性。
技巧1:在一個腳本函數中對HTML 內容進行更改。如果您的設計使用
了多個事件處理程序(例如響應滑鼠移動),則應集中進行更
改。
HTML分析和顯示元件的另一個重要事實是:一旦腳本回傳控制(例如,
當腳本事件處理函數退出時,或呼叫setTimeout(英文)等方法時),
該元件將重新計算佈局並顯示Web頁面。現在您已經了解Internet Explorer
如何處理變化,以下將開始提升Web頁面的效能。
技巧2:建立一個HTML 字串並對文件進行一次更改,而不是進行多
次更新。如果HTML 內容不是必要的,可考慮使用
innerText(英文)屬性。
在下列範例中,速度較慢的方法每次設定innerHTML屬性時都會呼叫HTML
分析器。要提高效能,可以先建立一個字串,然後將其指派給innerHTML
屬性。
慢:
divUpdate.innerHTML = "";
for ( var i=0; i<100; i++ )
{
divUpdate.innerHTML += "這是一個較慢的方法!";
}
快:
var str="";
for ( var i=0; i<100; i++ )
{
str += "因為使用字串,此方法較快!";
}
divUpdate.innerHTML = str;
使用innerText
DHTML 物件模型透過innerText(英文)屬性存取HTML 元素的文本
內容,而W3C DOM則提供一個獨立的子文字節點。直接透過innerText屬
性更新元素的內容,比呼叫DOM createTextNode (英文)方法更快。
技巧3:使用innerText 屬性更新文字內容。
以下範例顯示如何使用innerText 屬性提高效能。
慢:
var node;
for (var i=0; i<100; i++)
{
node = document.createElement( "SPAN" );
node.appendChild( document.createTextNode( "使用createText
Node() ") );
divUpdate.appendChild( node );
}
快:
var node;
for (var i=0; i<100; i++)
{
node = document.createElement( "SPAN" );
node.innerText = "使用innerText 屬性";
divUpdate.appendChild( node );
}
使用DOM 新增單一元素
如前所述,應用HTML 文字的存取方法將導致呼叫HTML 分析器,從
而會降低性能。因此,使用createElement(英文)和insertAdjacent
Element(英文)方法加入元素比呼叫一次insertAdjacentHTML 方法快。
技巧4:呼叫createElement 和insertAdjacentElement 方法比調用
insertAdjacentHTML 方法快。
成批處理DHTML更新並呼叫一次insertAdjacentHTML 方法可以提高
效能,但是有時直接透過DOM創建元素效率更高。在下面的方案中,您可
以嘗試這兩種方法並確定哪一種更快。
慢:
for (var i=0; i<100; i++)
{
divUpdate.insertAdjacentHTML( "beforeEnd", " 使用insert
AdjacentHTML() " );
}
快:
var node;
for (var i=0; i<100; i++)
{
node = document.createElement( "SPAN" );
node.innerText = " 使用insertAdjacentElement() ";
divUpdate.insertAdjacentElement( "beforeEnd", node );
}
擴展SELECT 元素中的選項
對於上一條使用HTML 文字方法的規則來說,將大量OPTION(英文)
元素加入SELECT(英文)的情況是例外。這時候,使用innerHTML
屬性比呼叫createElement方法存取選項集合效率更高。
技巧5:使用innerHTML 將大量選項加入SELECT 元素中。
使用字串連接操作來建立SELECT 元素的HTML 文本,然後使用此
技巧設定innerHTML屬性。對於數量特別大的選項,字串連接操作也會
影響性能。在此情況下,請建立一個陣列並呼叫Microsoft JScript join
(英文)方法來執行OPTION 元素HTML 文字的最終連結。
慢:
var opt;
divUpdate.innerHTML = "〈SELECT ID='selUpdate'〉";
for (var i=0; i<1000; i++)
{
opt = document.createElement( "OPTION" );
selUpdate.options.add( opt );
opt.innerText = "第" + i + " 項";
}
快:
var str="〈SELECT ID='selUpdate'〉";
for (var i=0; i<1000; i++)
{
str += "〈OPTION〉第" + i + " 項〈/OPTION〉";
}
str += "";
divUpdate.innerHTML = str;
更快:
var arr = new Array(1000);
for (var i=0; i<1000; i++)
{
arr[i] = "〈OPTION〉第" + i + " 項〈/OPTION〉";
}
divUpdate.innerHTML = "〈SELECT ID='selUpdate'〉" + arr.join() + "
";
用DOM 更新表
使用DOM方法插入表格的行和儲存格比使用insertRow(英文)和insert
Cell(英文)方法(DHTML table 物件模型的一部分)效率更高。尤其在
創建大的表時,效率上的差異更加明顯。
技巧6:使用DOM 方法建立大表。
慢:
var row;
var cell;
for (var i=0; i<100; i++)
{
row = tblUpdate.insertRow();
for (var j=0; j<10; j++)
{
cell = row.insertCell();
cell.innerText = "第" + i + " 行,第" + j + " 儲存格";
}
}
快:
var row;
var cell;
var tbody = tblUpdate.childNodes[0];
tblUpdate.appendChild( tbody );
for (var i=0; i<100; i++)
{
row = document.createElement( "TR" );
tbody.appendChild( row );
for (var j=0; j<10; j++)
{
cell = document.createElement( "TD" );
row.appendChild( cell );
cell.innerText = "第" + i + " 行,第" + j + " 儲存格";
}
}
編寫一次,使用多次
如果您的Web網站使用腳本來執行一些常用操作,可以考慮將這些功
能放到獨立的文件中,以便可以由多個Web頁面重複使用。這樣做,不僅
可以改善程式碼的維護性,而且使該腳本檔案保留在瀏覽器的快取中,從而
只需要在使用者造訪網站時向本地下載一次。將常用的樣式規則放在獨立的
文件中也可以得到同樣的好處。
技巧7:透過將常用程式碼放到行為或獨立檔案中來重複使用腳本
若要更善用腳本重複使用功能,請將常用的腳本操作放到DHTML附加代
尺寸或元素行為(英文)中。行為提供了一個有效的方法,用於重複使用腳本和
建立從HTML 存取的元件,並使您可用自己的物件、方法、屬性和事件來
擴充DHTML物件模型。對於未使用viewlink (英文)功能的行為,可以
考慮使用Internet Explorer 5.5中的lightweight(英文)行為特性進
行更有效的程式碼封裝。另外,如果您的腳本程式碼在一個SCRIPT (英文)
塊中,會獲得更高的性能。
請勿過度使用動態屬性
動態屬性(英文)為Web作者提供了一種將表達式用作屬性值的方法。
表達式在運行時計算,其結果值將應用於屬性。這是一個強大的特性。此
特性可用於減少頁面上的腳本數量,但因為必須定時重算表達式,而且
這個表達式經常與其他屬性值相關,所以它會對效能帶來負面的影響。這種
情況對定位屬性尤其明顯。
技巧8:限制使用動態屬性。
資料綁定很有效
資料綁定(英文)是一個強大的功能,它使您可以將資料庫查詢的結
果實或XML資料島(英文)的內容,綁定至Web頁面上的HTML 元素。您無
需返回伺服器提取數據,就可以提供數據排序和過濾功能,以及不同的數
據視圖。設想一個Web頁面可以將公司的數據顯示為折線圖、長條圖或餅
圖,還具有將資料按辦公室、產品或銷售階段排序的按鈕,而且所有這些
功能只需要訪問一次伺服器就能實現。
技巧9:使用資料綁定來提供豐富的客戶端資料視圖。
不要在document 物件中設定expando 屬性
expando (英文)屬性可以新增至任何物件。此屬性非常有用,它可
以儲存目前Wed頁面內的信息,並提供了另一個擴展DHTML物件模型的方
法。例如,您可以為DHTML元素指定一個clicked屬性,用此屬性提示用
戶已經單擊了哪一個元素。在引發事件時,也可以使用expando屬性,向
事件處理函數提供更多的上下文資訊。無論您如何使用expando屬性,切
記不要在document (英文)物件上設定它們。如果您這樣做,則當您訪問
問該屬性時,文件必須執行額外的重算操作。
技巧10:在window(英文)物件上設定expando 屬性。
慢:
for (var i=0; i<1000; i++)
{
var tmp;
window.document.myProperty = "第" + i + " 項";
tmp = window.document.myProperty;
}
快:
for (var i=0; i<1000; i++)
{
var tmp;
window.myProperty = "第" + i + " 項";
tmp = window.myProperty;
}
避免切換類別和樣式規則
切換類別和樣式規則是一種代價非常高的操作,需要重新計算並調整整
個文檔的佈局。如果您的Web網站使用樣式表來提供內容的備用視圖,可
以考慮直接修改要更改的元素的style(英文)對象,而不是修改元素的
className (英文)屬性或與類別關聯的styleSheet (英文)物件。
技巧11:在更改內容的外觀時,直接修改style 物件。
在尋找父項之前,先折疊文字範圍
TextRange (英文)物件表示使用者選取或從HTML 元素中檢索的一個
文字區域,例如BODY (英文)。透過呼叫parentElement(英文)方法,
可以標識文字範圍的父項。對於複雜的文字範圍,在呼叫parentElement
方法之前,先呼叫collapse (英文)方法效率會更高。
技巧12:在存取parentElement 方法之前,先折疊文字範圍。
取自http://www.microsoft.com/china/msdn/?MSCOMTB=ICP_MSDN