微軟的開發周期中很重要的一塊是調整產品的性能。性能調整也是開發者應當留心的關鍵部分之一。 經過多年發展,業界對於如何優化Win32程序性能已經有非常多的了解。
現在開發者遇到的問題之一是不太清楚是什麼導致DTHML和HTML頁面運行快或者慢。當然,有一些很簡單的方法——比如不要使用2MB大的圖片。我們曾經使用過另外一些有趣的技巧提高了DHTML頁面的性能,希望它們能幫助你改善自己的頁面性能。
這裡我使用了一個建立Table的程序例子。其中用document.createElement()和element.insertBefore()方法創建了1000行(Row)的表(Table)。每行有一列(Cell)。Cell中包含的內容稱為"Text"。這段代碼能有多糟呢?這麼小的程序又能有多大調整余地呢?請看介紹。
一開始我寫了一段自認為會很快的程序,我盡量避免一些低級問題----像沒有顯式定義變量、或者在一個頁面中同時使用VBScript和javascript。程序如下:
<html>
<body>
<script>
var tbl, tbody, tr, td, text, i, max;
max = 1000;
tbl = document.createElement("TABLE");
tbl.border = "1";
tbody = document.createElement("TBODY");
tbl.insertBefore(tbody, null);
document.body.insertBefore(tbl, null);
for (i=0; i<max; i++) {
tr = document.createElement("TR");
td = document.createElement("TD");
text = document.createTextNode("Text");
td.insertBefore(text, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
</script>
</body>
</html>
在PII233/64MB內存/NT4.0/IE5.0的機器上運行這段程序。頁面從本機上裝載。從開始裝載頁面到頁面完全安靜下來(所有的事件均已經運行,屏幕顯示完成)的時間為2328毫秒,這也是本次測試的基線(我稱之為Test1)。
這個頁面中,一個很耗時的操作是頻繁引用全局對象,如“document”、“body”、“window”等。引用所有這些類似的全局變量遠比引用一個本地變量代價高昂。
因此我作了第一次改進嘗試:緩存(Cache)document.body 到本地變量“theBody”中:
增加了如下代碼:
var theBody = document.body;
然後修改這一行:
document.body.insertBefore(tbl, null);
將之改為:
theBody.insertBefore(tbl, null);
View the second sample.
這次修改並沒有太大影響到整體時間,它只縮短了3 ms。但它已經表明,如果在循環中也有document.body對象而對其引用做出修改,帶來的好處將是可觀的。
隨後,我緩存了document對象----在我們這個測試中,document對象共被引用了3002次。修改後代碼如下:
<html>
<body>
<script>
var tbl, tbody, tr, td, text, i, max;
max = 1000;
var theDoc = document;
var theBody = theDoc.body;
tbl = theDoc.createElement("TABLE");
tbl.border = "1";
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
for (i=0; i<max; i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Text");
td.insertBefore(text, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
</script>
</body>
</html>
View the third sample.
此次運行時間只有2100ms,節約了大約10%的時間。使用本地變量而不是直接引用document對象平均每次節約了0.4毫秒。
一個常用的優化性能的方法是:當腳本不需要立即運行時,在<SCRIPT>標簽中設置“defer”屬性。 (立即腳本沒有被包含在一個function塊中,因此會在加載過程中執行。) 設置“defer”屬性後,IE就不必等待該腳本裝載和執行完畢。這樣頁面加載會更快。一般來說,這也表明立即腳本最好放在function塊中,並在document或者body對象的onload 句柄中處理該函數。在有一些腳本需要依賴用戶操作而執行時----例如點擊按鈕,或者移動鼠標到某個區域----使用該屬性非常有用。但當有一些腳本需要在頁面加載過程中或加載完成後執行,使用defer屬性得到的好處就不太大。
下面是使用了defer屬性修改後的代碼版本:
<html>
<body >
<script defer>
function init() {
var tbl, tbody, tr, td, text, i, max;
max = 1000;
var theDoc = document;
var theBody = theDoc.body;
tbl = theDoc.creat