web前端效能最佳化

來源:互聯網
上載者:User

標籤:阻塞   超過   專用   第一個   而且   copyto   cdn   元素   效果   

 網站的劃分一般為二:前端和後台。我們可以理解成後台是用來實現網站的功能的,比如:實現使用者註冊,使用者能夠為文章發表評論等等。而前端呢?其實應該是屬於功能的表現。並且影響使用者訪問體驗的絕大部分來自前端頁面。

        而我們建設網站的目的是什麼呢?不就是為了讓目標人群來訪問嗎?所以我們可以理解成前端才是真正和使用者接觸的。除了後台需要在效能上做最佳化外,其實前端的頁面更需要在效能最佳化上下功夫,只有這樣才能給我們的使用者帶來更好的使用者體驗。就好像,好多人問,男人在找女朋友的時候是不是只看外表,一些智慧的男人給出了這樣的回答:臉蛋和身材決定了我是否想去瞭解她的思想,思想決定了我是否會一票否決她的臉蛋和身材。同理,網站也是這樣,網站前端的使用者體驗決定了使用者是否想要去使用網站的功能,而網站的功能決定了使用者是否會一票否決前端體驗

        不僅僅如此,如果前端最佳化得好,他不僅可以為企業節約成本,他還能給使用者帶來更多的使用者,因為增強使用者體驗。說了這麼多,那麼我們應該如何對我們前端的頁面進行效能最佳化呢?

        一般說來,web前端指網站商務邏輯之前的部分,包括瀏覽器載入、網站視圖模型、圖片服務、CDN服務等,主要最佳化手段有瀏覽器訪問、使用反向 Proxy才、CDN等。

瀏覽器訪問最佳化

瀏覽器請求處理流程如:


1、減少http請求,合理設定 HTTP緩衝

        http協議是無狀態的應用程式層協議,意味著每次http請求都需要建立通訊鏈路、進行資料轉送,而在伺服器端,每個http都需要啟動獨立的線程去處理。這些通訊和服務的開銷都很昂貴,減少http請求的數目可有效提高訪問效能。

        減少http的主要手段是合并CSS、合并JavaScript、合并圖片。將瀏覽器一次訪問需要的javascript和CSS合并成一個檔案,這樣瀏覽器就只需要一次請求。圖片也可以合并,多張圖片合并成一張,如果每張圖片都有不同的超連結,可通過CSS位移響應滑鼠點擊操作,構造不同的URL。
         緩衝的力量是強大的,恰當的緩衝設定可以大大的減少 HTTP請求。假設某網站首頁,當瀏覽器沒有緩衝的時候訪問一共會發出 78個請求,共 600多 K資料,而當第二次訪問即瀏覽器已緩衝之後訪問則僅有 10個請求,共 20多 K資料。 (這裡需要說明的是,如果直接 F5重新整理頁面的話效果是不一樣的,這種情況下請求數還是一樣,不過被緩衝資源的請求伺服器是 304響應,只有 Header沒有Body,可以節省頻寬 )

        怎樣才算合理設定 ?原則很簡單,能緩衝越多越好,能緩衝越久越好。例如,很少變化的圖片資源可以直接通過 HTTP Header中的Expires設定一個很長的到期頭 ;變化不頻繁而又可能會變的資源可以使用 Last-Modifed來做請求驗證。儘可能的讓資源能夠在緩衝中待得更久。關於 HTTP緩衝的具體設定和原理此處就不再詳述了。

2、使用瀏覽器緩衝

        對一個網站而言,CSS、javascript、logo、表徵圖這些靜態資源檔案更新的頻率都比較低,而這些檔案又幾乎是每次http請求都需要的,如果將這些檔案快取在瀏覽器中,可以極好的改善效能。通過設定http頭中的cache-control和expires的屬性,可設定瀏覽器緩衝,緩衝時間可以是數天,甚至是幾個月。

        在某些時候,靜態資源檔案變化需要及時應用到用戶端瀏覽器,這種情況,可通過改變檔案名稱實現,即更新javascript檔案並不是更新javascript檔案內容,而是產生一個新的js檔案並更新HTML檔案中的引用。
        使用瀏覽器緩衝策略的網站在更新靜態資源時,應採用逐量更新的方法,比如需要更新10個表徵圖檔案,不宜把10個檔案一次全部更新,而是應該一個檔案一個檔案逐步更新,並有一定的間隔時間,以免使用者瀏覽器忽然大量緩衝失效,集中更新緩衝,造成伺服器負載驟增、網路堵塞的情況。

3、啟用壓縮

        在伺服器端對檔案進行壓縮,在瀏覽器端對檔案解壓縮,可有效減少通訊傳輸的資料量。如果可以的話,儘可能的將外部的指令碼、樣式進行合并,多個合為一個。文字檔的壓縮效率可達到80%以上,因此HTML、CSS、javascript檔案啟用GZip壓縮可達到較好的效果。但是壓縮對伺服器和瀏覽器產生一定的壓力,在通訊頻寬良好,而伺服器資源不足的情況下要權衡考慮。

4、CSS Sprites

合并 CSS圖片,減少請求數的又一個好辦法。

5、LazyLoad Images

        這條策略實際上並不一定能減少 HTTP請求數,但是卻能在某些條件下或者頁面剛載入時減少 HTTP請求數。對於圖片而言,在頁面剛載入的時候可以只載入第一屏,當使用者繼續往後滾屏的時候才載入後續的圖片。這樣一來,假如使用者只對第一屏的內容感興趣時,那剩餘的圖片請求就都節省了。

6、CSS放在頁面最上部,javascript放在頁面最下面

       瀏覽器會在下載完成全部CSS之後才對整個頁面進行渲染,因此最好的做法是將CSS放在頁面最上面,讓瀏覽器儘快下載CSS。如果將 CSS放在其他地方比如 BODY中,則瀏覽器有可能還未下載和解析到 CSS就已經開始渲染頁面了,這就導致頁面由無 CSS狀態跳轉到 CSS狀態,使用者體驗比較糟糕,所以可以考慮將CSS放在HEAD中。

        Javascript則相反,瀏覽器在載入javascript後立即執行,有可能會阻塞整個頁面,造成頁面顯示緩慢,因此javascript最好放在頁面最下面。但如果頁面解析時就需要用到javascript,這時放到底部就不合適了。

        Lazy Load Javascript(只有在需要載入的時候載入,在一般情況下並不載入資訊內容。)隨著 Javascript架構的流行,越來越多的網站也使用起了架構。不過,一個架構往往包括了很多的功能實現,這些功能並不是每一個頁面都需要的,如果下載了不需要的指令碼則算得上是一種資源浪費 -既浪費了頻寬又浪費了執行花費的時間。目前的做法大概有兩種,一種是為那些流量特別大的頁面專門定製一個專用的 mini版架構,另一種則是 Lazy Load。

7、非同步請求Callback(就是將一些行為樣式提取出來,慢慢的載入資訊的內容)

在某些頁面中可能存在這樣一種需求,需要使用 script標籤來非同步請求資料。類似:

[javascript] view plain copy print?
  1. <span style="font-size:14px;">/*Callback 函數*/  
  2.     function myCallback(info){   
  3.         //do something here   
  4.     }   
  5.  HTML:  
  6.   Callback返回的內容 :  
  7.    myCallback(‘Hello world!‘);  
  8. </span>  

像以上這種方式直接在頁面上寫 <script> 對頁面的效能也是有影響的,即增加了頁面首次載入的負擔,延遲了 DOMLoaded和window.onload 事件的觸發時機。如果時效性允許的話,可以考慮在 DOMLoaded事件觸發的時候載入,或者使用 setTimeout方式來靈活的控制載入的時機。

8、減少cookie傳輸

        一方面,cookie包含在每次請求和響應中,太大的cookie會嚴重影響資料轉送,因此哪些資料需要寫入cookie需要謹慎考慮,盡量減少cookie中傳輸的資料量。另一方面,對於某些靜態資源的訪問,如CSS、script等,發送cookie沒有意義,可以考慮靜態資源使用獨立網域名稱訪問,避免請求靜態資源時發送cookie,減少cookie傳輸次數。

9、Javascript代碼最佳化

(1). DOM  

a.HTML Collection(HTML收集器,返回的是一個數組內容資訊) 
  在指令碼中 document.images、document.forms、getElementsByTagName()返回的都是HTMLCollection類型的集合,在平時使用的時候大多將它作為數組來使用,因為它有 length屬性,也可以使用索引訪問每一個元素。不過在訪問效能上則比數組要差很多,原因是這個集合并不是一個靜態結果,它表示的僅僅是一個特定的查詢,每次訪問該集合時都會重新執行這個查詢從而更新查詢結果。所謂的“訪問集合” 包括讀取集合的 length屬性、訪問集合中的元素。 
  因此,當你需要遍曆 HTML Collection的時候,盡量將它轉為數組後再訪問,以提高效能。即使不轉換為數組,也請儘可能少的訪問它,例如在遍曆的時候可以將 length屬性、成員儲存到局部變數後再使用局部變數。   
b. Reflow & Repaint   
  除了上面一點之外, DOM操作還需要考慮瀏覽器的Reflow和Repaint ,因為這些都是需要消耗資源的。

(2). 慎用 with 

with(obj){ p = 1};代碼塊的行為實際上是修改了代碼塊中的執行環境 ,將obj放在了其範圍鏈的最前端,在 with代碼塊中訪問非局部變數是都是先從 obj上開始尋找,如果沒有再依次按範圍鏈向上尋找,因此使用 with相當於增加了範圍鏈長度。而每次尋找範圍鏈都是要消耗時間的,過長的範圍鏈會導致尋找效能下降。 
  因此,除非你能肯定在 with代碼中只訪問 obj中的屬性,否則慎用 with,替代的可以使用局部變數緩衝需要訪問的屬性。

(3). 避免使用 eval和 Function

每次 eval或Function 建構函式作用於字串表示的原始碼時,指令碼引擎都需要將原始碼轉換成可執行代碼。這是很消耗資源的操作 —— 通常比簡單的函數調用慢 100倍以上。 
  eval 函數效率特別低,由於事先無法知曉傳給 eval 的字串中的內容,eval在其上下文中解釋要處理的代碼,也就是說編譯器無法最佳化上下文,因此只能有瀏覽器在運行時解釋代碼。這對效能影響很大。 
  Function 建構函式比 eval略好,因為使用此代碼不會影響周圍代碼 ;但其速度仍很慢。 
  此外,使用 eval和 Function也不利於Javascript 壓縮公用程式執行壓縮。

(4). 減少範圍鏈尋找

前文談到了範圍鏈尋找問題,這一點在迴圈中是尤其需要注意的問題。如果在迴圈中需要訪問非本範圍下的變數時請在遍曆之前用局部變數緩衝該變數,並在遍曆結束後再重寫那個變數,這一點對全域變數尤其重要,因為全域變數處於範圍鏈的最頂端,訪問時的尋找次數是最多的。 
低效率的寫法:

[javascript] view plain copy print?
  1. <span style="font-size:14px;">// 全域變數   
  2. var globalVar = 1;   
  3. function myCallback(info){   
  4.     for( var i = 100000; i--;){   
  5.         //每次訪問 globalVar 都需要尋找到範圍鏈最頂端,本例中需要訪問 100000 次   
  6.         globalVar += i;   
  7.     }  
  8. }   
  9. </span>  


更高效的寫法:

[javascript] view plain copy print?
  1. <span style="font-size:14px;">// 全域變數   
  2. var globalVar = 1;   
  3. function myCallback(info){   
  4.     //局部變數緩衝全域變數   
  5.     var localVar = globalVar;   
  6.     for( var i = 100000; i--;){   
  7.     //訪問局部變數是最快的   
  8.     localVar += i;   
  9.     }   
  10.     //本例中只需要訪問 2次全域變數  
  11.     在函數中只需要將 globalVar中內容的值賦給localVar 中  
  12.     globalVar = localVar;   
  13. }  
  14. </span>  


此外,要減少範圍鏈尋找還應該減少閉包的使用。

(5). 資料訪問

  Javascript中的資料訪問包括直接量 (字串、Regex )、變數、對象屬性以及數組,其中對直接量和局部變數的訪問是最快的,對對象屬性以及數組的訪問需要更大的開銷。當出現以下情況時,建議將資料放入局部變數: 
  a. 對任何對象屬性的訪問超過 1次 
  b. 對任何數群組成員的訪問次數超過 1次 
  另外,還應當儘可能的減少對對象以及數組深度尋找。

(6). 字串拼接

在 Javascript中使用”+”號來拼接字串效率是比較低的,因為每次運行都會開闢新的記憶體並產生新的字串變數,然後將拼接結果賦值給新變數。與之相比更為高效的做法是使用數組的 join方法,即將需要拼接的字串放在數組中最後調用其 join方法得到結果。不過由於使用數組也有一定的開銷,因此當需要拼接的字串較多的時候可以考慮用此方法。

10、CSS選擇符最佳化

在大多數人的觀念中,都覺得瀏覽器對 CSS選擇符的解析式從左往右進行的,例如 
#toc A { color: #444; }這樣一個選擇符,如果是從右往左解析則效率會很高,因為第一個 ID選擇基本上就把尋找的範圍限定了,但實際上瀏覽器對選擇符的解析是從右往左進行的。如上面的選擇符,瀏覽器必須遍曆尋找每一個 A標籤的祖先節點,效率並不像之前想象的那樣高。根據瀏覽器的這一行為特點,在寫選擇符的時候需要注意很多事項,有興趣的童鞋可以去瞭解一下。

CDN加速

CDN(contentdistribute network,內容分髮網絡)的本質仍然是一個緩衝,而且將資料緩衝在離使用者最近的地方,使使用者以最快速度擷取資料,即所謂網路訪問第一跳,如。

由於CDN部署在網路電訊廠商的機房,這些電訊廠商又是終端使用者的網路服務供應商,因此使用者請求路由的第一跳就到達了CDN伺服器,當CDN中存在瀏覽器請求的資源時,從CDN直接返回給瀏覽器,最短路徑返迴響應,加快使用者訪問速度,減少資料中心負載壓力。 
CDN緩衝的一般是靜態資源,片、檔案、CSS、script指令碼、靜態網頁等,但是這些檔案訪問頻度很高,將其緩衝在CDN可極大改善網頁的開啟速度。

反向 Proxy

傳統Proxy 伺服器位於瀏覽器一側,代理瀏覽器將http請求發送到互連網上,而反向 Proxy伺服器位於網站機房一側,代理網站web伺服器接收http請求。如所示:

論壇網站,把熱門詞條、文章、部落格緩衝在反向 Proxy伺服器上加速使用者訪問速度,當這些動態內容有變化時,通過內部通知機制通知反向 Proxy緩衝失效,反向 Proxy會重新載入最新的動態內容再次緩衝起來。

此外,反向 Proxy也可以實現負載平衡的功能,而通過負載平衡構建的應用叢集可以提高系統總體處理能力,進而改善網站高並發情況下的效能

web前端效能最佳化

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.