剛剛做完1個復雜頁面的前端性能優化,這里的優化是針對這個頁面具體的需求單獨做的優化,所以這里不會談那些減少http請求,合并壓縮js,css,圖片合并等等。因為這些是所有頁面都需要做的,如果需要了解這些,可以參考我這篇文章:web高性能開發系列隨筆
頁面介紹:
該頁面是1個記賬類的頁面,頁面如下:

頁面主要有4部分組成:
1. 上部的輸入部分(有5大不同的類型,每個類型都是1個單獨的tab,對應內容也不一樣)
2. 左邊的分類列表(默認顯示一級分類,點擊展開子類)
3. 右邊時間選擇區(按月,年,季,自定義時間過濾等等)
4. 右邊下半部分的數據列表(默認只顯示每條數據基本信息,點擊展開詳細信息)
可能看到這里大家不覺的這個頁面會很大,那就再細說下,該頁面包含記賬的所有的功能(添加、刪除,修改,分拆,上傳圖片,顯示數據,數據排序),而且每種下拉列表前面都有個"加號"(見輸入部分的下列列表),點擊"加號"都會彈出類似如下的窗口進行添加(總共有8個左右的彈出窗口),所有的這些都是通過js來實現(js代碼總共寫了大概2000行,不含注釋):

問題
該頁面有一些用戶反映比較慢,經過測試也發現,因為頁面比較復雜,js也比較多,所以在IE下速度會比較慢(特別是IE6),而chrome和firefox速度還是可以的,所以這次的優化主要針對IE,當然優化后的其他瀏覽器肯定也會受益。
優化1:彈出窗口的延遲加載
本來第1個優化不應該寫這個,因為這個優化效果并不是最明顯的。把它放在第一位,是因為個人覺得這種延遲加載的想法還不錯,比較有新意(目前還沒見過網上有人介紹過這種延遲加載)。
入正題,上面說到,該頁面總共有8個彈出窗口,而且每個彈出窗口的都使用了不同的圖片(不少是png),監控發現這些彈出窗口用的png圖片雖然設置了緩存頭(也使用了document.execCommand("BackgroundImageCache", false, true);),但是在IE6下每次都不直接使用緩存,而是發生1個請求,并得到304狀態回應(原因我估計跟使用DD_belatedPNG來處理png圖片有關,因為時間關系還沒深入研究),監控圖如下:

從圖中可以看出這幾個圖片很影響加載速度,其實一開始我們根本用不上這些彈出窗口的圖片,因為默認都是隱藏的,而且這些彈出窗口,一般用戶都用的比較少。理所當然,我們想到了延遲加載。
想到延遲加載,第一想到就是先不加載彈出窗口的html代碼,這樣就不會加載對應的圖片了,當用戶點擊彈出按鈕的時候,再去后臺加載對應的html代碼。但這樣就有個問題,當用戶點擊"加號"按鈕,用ajax去加載html代碼,用戶明顯就會感覺到半天窗口還沒彈出來,就會連續的點擊,這種用戶體驗肯定是失敗的。
我們想要的延遲加載是先加載html代碼,但不加載html代碼使用的圖片。但用戶點擊"加號"的時候,直接彈出窗口并加載圖片,這樣用戶一點擊就可以看到窗口。那如何實現這種功能了,于是我想到了html的注釋。我們先把所有彈出窗口的html代碼放進注釋中(這樣就不會加載圖片),當用戶點擊"加號"時,用js讀取注釋中的html插入到body中(不需要ajax),然后彈出窗口。
比如有2個彈出窗口,代碼大概如下(并不是完整代碼,不能直接運行):
<script>
var loaded = new Object(); // 記錄哪些html已經append到body中
/**
* 加載html,該html已經以注釋的方式嵌入的html中,eg:
* <div id="fast_model_lazy">
* <!--[lazy]>
* sass
* <![endlazy]-->
* </div>
*/
function loadHtml(id){
// 已經加載過,不再加載
if(loaded[id])
return false;
var html = $.trim(document.getElementById(id).innerHTML);
// 去掉注釋開頭(11位)和結尾(14位)
html = html.substring(11,html.length-14);
$(document.body).append($(html));
loaded[id]=1;
return true;
}
function click1(){
loadHtml("fast_model_lazy");
// 彈出窗口
$("#fast_model_lazy").showDialog();
}
function click2(){
loadHtml("fast_model2_lazy");
// 彈出窗口
$("#fast_model2_lazy").showDialog();
}
</script>
<button click="click1()">彈出第一窗口</button>
<button click="click2()">彈出第二窗口</button>
<div id="fast_model_lazy">
<!--[lazy]>
<div id="fast_model" class="model">
....這里省略html
</div>
<![endlazy]-->
</div>
<div id="fast_model2_lazy">
<!--[lazy]>
<div id="fast_model2" class="model">
....這里省略html
</div>
<![endlazy]-->
</div>
總結:
這種延遲加載的方式,主要用于延遲圖片的加載,css的應用,js的解析和執行等等,并不是為了延遲加載html。如果是大量的html代碼,比如分頁的數據,
使用這種方式就不太合適。個人覺的這種加載方式還可以在很多地方用的到的。
后語:
今天就寫這些,下次再寫寫對該頁面的其他的一些優化。