天天看點

記一複雜頁面的前端優化(1) - 不一樣的延遲加載

頁面介紹:

  該頁面是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個彈出視窗,代碼大概如下(并不是完整代碼,不能直接運作):

<code>&lt;</code><code>script</code><code>&gt;</code>

<code>    </code><code>var loaded = new Object();  // 記錄哪些html已經append到body中</code>

<code>   </code><code>/**</code>

<code>    </code><code>* 加載html,該html已經以注釋的方式嵌入的html中,eg:</code>

<code>    </code><code>* &lt;</code><code>div</code> <code>id="fast_model_lazy"&gt;</code>

<code>    </code><code>* </code><code>&lt;!--[lazy]&gt;</code>

<code>    </code><code>*  sass</code>

<code>    </code><code>*  &lt;![endlazy]--&gt;</code>

<code>    </code><code>* &lt;/</code><code>div</code><code>&gt;</code>

<code>    </code><code>*/</code>

<code>   </code><code>function loadHtml(id){</code>

<code>       </code><code>// 已經加載過,不再加載</code>

<code>       </code><code>if(loaded[id])</code>

<code>           </code><code>return false;</code>

<code>       </code> 

<code>       </code><code>var html = $.trim(document.getElementById(id).innerHTML);</code>

<code>       </code><code>// 去掉注釋開頭(11位)和結尾(14位)</code>

<code>       </code><code>html = html.substring(11,html.length-14);</code>

<code>       </code><code>$(document.body).append($(html));</code>

<code>       </code><code>loaded[id]=1;</code>

<code>       </code><code>return true;</code>

<code>   </code><code>}</code>

<code>   </code><code>function click1(){</code>

<code>       </code><code>loadHtml("fast_model_lazy");</code>

<code>       </code><code>// 彈出視窗</code>

<code>       </code><code>$("#fast_model_lazy").showDialog();</code>

<code>   </code><code>function click2(){</code>

<code>       </code><code>loadHtml("fast_model2_lazy");</code>

<code>       </code><code>$("#fast_model2_lazy").showDialog();</code>

<code>&lt;/</code><code>script</code><code>&gt;</code>

<code>&lt;</code><code>button</code> <code>click="click1()"&gt;彈出第一視窗&lt;/</code><code>button</code><code>&gt;</code>

<code>&lt;</code><code>button</code> <code>click="click2()"&gt;彈出第二視窗&lt;/</code><code>button</code><code>&gt;</code>

<code>&lt;</code><code>div</code> <code>id="fast_model_lazy"&gt;</code>

<code>  </code><code>&lt;!--[lazy]&gt;</code>

<code>  </code><code>&lt;div id="fast_model" class="model"&gt;</code>

<code>       </code><code>....這裡省略html</code>

<code>  </code><code>&lt;/div&gt;</code>

<code> </code><code>&lt;![endlazy]--&gt;</code>

<code>&lt;/</code><code>div</code><code>&gt;</code>

<code>&lt;</code><code>div</code> <code>id="fast_model2_lazy"&gt;</code>

<code>  </code><code>&lt;div id="fast_model2" class="model"&gt;</code>

總結:

 這種延遲加載的方式,主要用于延遲圖檔的加載,css的應用,js的解析和執行等等,并不是為了延遲加載html。如果是大量的html代碼,比如分頁的資料,

使用這種方式就不太合适。個人覺的這種加載方式還可以在很多地方用的到的。

後語:

 今天就寫這些,下次再寫寫對該頁面的其他的一些優化。

本文轉自BearRui(AK-47)部落格園部落格,原文連結:http://www.cnblogs.com/BearsTaR/archive/2010/07/14/Tally_Optimization.html    ,如需轉載請自行聯系原作者

繼續閱讀