通過效能測速和分析,我們基本可以獲取收集到頁面上大部分的具體效能資料,如何根據這些資料採取適當的方法和手段對當前的頁面進行優化呢?目前來看,前端優化的策略很多,如YSlow(YSlow是Yahoo釋出的一款Firefox外掛,可以對網站的頁面效能進行分析,提出對該頁面效能優化的建議)原則等,總結起來主要包括網路載入類、頁面渲染類、CSS優化類、JavaScript執行類、快取類、圖片類、架構協議類等幾類,下面逐一介紹。
一、 網路載入類
1.減少HTTP資源請求次數
在前端頁面中,通常建議儘可能合併靜態資源圖片、JavaScript或CSS程式碼,減少頁面請求數和資源請求消耗,這樣可以縮短頁面首次訪問的使用者等待時間。通過構建工具合併雪碧圖、CSS、JavaScript檔案等都是為了減少HTTP資源請求次數。另外也要儘量避免重複的資源,防止增加多餘請求。
2.減小HTTP請求大小
除了減少HTTP資源請求次數,也要儘量減小每個HTTP請求的大小。如減少沒必要的圖片、JavaScript、CSS及HTML程式碼,對檔案進行壓縮優化,或者使用gzip壓縮傳輸內容等都可以用來減小檔案大小,縮短網路傳輸等待時延。前面我們使用構建工具來壓縮靜態圖片資源以及移除程式碼中的註釋並壓縮,目的都是為了減小HTTP請求的大小。
3.將CSS或JavaScript放到外部檔案中,避免使用或
標籤直接引入
在HTML檔案中引用外部資源可以有效利用瀏覽器的靜態資源快取,但有時候在移動端頁面CSS或JavaScript比較簡單的情況下為了減少請求,也會將CSS或JavaScript直接寫到HTML裡面,具體要根據CSS或JavaScript檔案的大小和業務的場景來分析。如果CSS或JavaScript檔案內容較多,業務邏輯較複雜,建議放到外部檔案引入。
1 2 |
<link rel="stylesheet" href="//cdn.domain.com/path/main.css"> <script src="//cdn.domain.com/path/main.js"></script> |
4.避免頁面中空的href和src
當標籤的href屬性為空,或<script>
、<img>
、<iframe>
標籤的src屬性為空時,瀏覽器在渲染的過程中仍會將href屬性或src屬性中的空內容進行載入,直至載入失敗,這樣就阻塞了頁面中其他資源的下載程式,而且最終載入到的內容是無效的,因此要儘量避免。
1 2 3 |
<!-- 不推薦 --> <img src="" alt="photo"> <a href="">點選連結</a> |
5.為HTML指定Cache-Control或Expires
為HTML內容設定Cache-Control 或Expires可以將HTML內容快取起來,避免頻繁向伺服器端傳送請求。前面講到,在頁面Cache-Control或Expires頭部有效時,瀏覽器將直接從快取中讀取內容,不向伺服器端傳送請求。
1 2 |
<meta http-equiv="Cache-Control" content="max-age=7200"/> <meta http-equiv="Expires" content="Mon, 20 Jul 2016 23:00:00 GMT"/> |
6.合理設定Etag和Last-Modified
合理設定Etag和Last-Modified使用瀏覽器快取,對於未修改的檔案,靜態資源伺服器會向瀏覽器端返回304,讓瀏覽器從快取中讀取檔案,減少Web資源下載的頻寬消耗並降低伺服器負載。
1 |
<meta http-equiv="last-modified" content="Mon, 03 Oct 2016 17:45:57 GMT"/> |
7. 減少頁面重定向
頁面每次重定向都會延長頁面內容返回的等待延時,一次重定向大約需要600毫秒的時間開銷,為了保證使用者儘快看到頁面內容,要儘量避免頁面重定向。
8.使用靜態資源分域存放來增加下載並行數
瀏覽器在同一時刻向同一個域名請求檔案的並行下載數是有限的,因此可以利用多個域名的主機來存放不同的靜態資源,增大頁面載入時資源的並行下載數,縮短頁面資源載入的時間。通常根據多個域名來分別儲存JavaScript、CSS和圖片檔案。
1 2 |
<link rel="stylesheet" href="//cdn1.domain.com/path/main.css"/> <script src="//cdn2.domain.com/path/main.js"/> |
9.使用靜態資源CDN來儲存檔案
如果條件允許,可以利用CDN網路加快同一個地理區域內重複靜態資原始檔的響應下載速度,縮短資源請求時間。
10.使用CDN Combo下載傳輸內容
CDN Combo是在CDN伺服器端將多個檔案請求打包成一個檔案的形式來返回的技術,這樣可以實現HTTP連線傳輸的一次性複用,減少瀏覽器的HTTP請求數,加快資源下載速度。例如同一個域名CDN伺服器上的a.js,b.js,c.js就可以按如下方式在一個請求中下載。
1 |
<script src="//cdn.domain.com/path/a.js,b.js,c.js"/> |
11.使用可快取的AJAX
對於返回內容相同的請求,沒必要每次都直接從服務端拉取,合理使用AJAX快取能加快AJAX響應速度並減輕伺服器壓力。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$.ajax({ url: url, type: 'get', cache: true, // 推薦使用快取 data: {} success(){ // ... }, error(){ // ... } }); |
12.使用GET來完成AJAX請求
使用XMLHttpRequest時,瀏覽器中的POST方法傳送請求首先傳送檔案頭,然後傳送HTTP正文資料。而使用GET時只傳送頭部,所以在拉取服務端資料時使用GET請求效率更高。
1 2 3 4 5 6 7 8 9 10 11 12 |
$.ajax({ url: url, type: 'get', // 推薦使用get完成請求 data: {} success(){ // ... }, error(){ // ... } }); |
13.減少Cookie的大小並進行Cookie隔離
HTTP請求通常預設帶上瀏覽器端的Cookie一起傳送給伺服器,所以在非必要的情況下,要儘量減少Cookie來減小HTTP請求的大小。對於靜態資源,儘量使用不同的域名來存放,因為Cookie預設是不能跨域的,這樣就做到了不同域名下靜態資源請求的Cookie隔離。
14.縮小favicon.ico並快取
有利於favicon.ico的重複載入,因為一般一個Web應用的favicon.ico是很少改變的。
15.推薦使用非同步JavaScript資源
非同步的JavaScript資源不會阻塞文件解析,所以允許在瀏覽器中優先渲染頁面,延後載入指令碼執行。例如JavaScript的引用可以如下設定,也可以使用模組化載入機制來實現。
1 2 |
<script src="main.js" defer="defer"/> <script src="main.js" async=""/> |
使用async時,載入和渲染後續文件元素的過程和main.js的載入與執行是並行的。使用defer時,載入後續文件元素的過程和main.js的載入是並行的,但是main.js的執行要在頁面所有元素解析完成之後才開始執行。
16.消除阻塞渲染的CSS及JavaScript
對於頁面中載入時間過長的CSS或JavaScript檔案,需要進行合理拆分或延後載入,保證關鍵路徑的資源能快速載入完成。
17.避免使用CSS import引用載入CSS
CSS中的@import可以從另一個樣式檔案中引入樣式,但應該避免這種用法,因為這樣會增加CSS資源載入的關鍵路徑長度,帶有@import的CSS樣式需要在CSS檔案序列解析到@import時才會載入另外的CSS檔案,大大延後CSS渲染完成的時間。
1 2 3 4 5 6 7 |
<!-- 不推薦 --> <style> @import "path/main.css"; </style> <!-- 推薦 --> <link rel="stylesheet" href="//cdn1.domain.com/path/main.css"> |
二、 頁面渲染類
1.把CSS資源引用放到HTML檔案頂部
一般推薦將所有CSS資源儘早指定在HTML文件中,這樣瀏覽器可以優先下載CSS並儘早完成頁面渲染。
2.JavaScript資源引用放到HTML檔案底部
JavaScript資源放到HTML文件底部可以防止JavaScript的載入和解析執行對頁面渲染造成阻塞。由於JavaScript資源預設是解析阻塞的,除非被標記為非同步或者通過其他的非同步方式載入,否則會阻塞HTML DOM解析和CSS渲染的過程。
3.不要在HTML中直接縮放圖片
在HTML中直接縮放圖片會導致頁面內容的重排重繪,此時可能會使頁面中的其他操作產生卡頓,因此要儘量減少在頁面中直接進行圖片縮放。
4.減少DOM元素數量和深度
HTML中標籤元素越多,標籤的層級越深,瀏覽器解析DOM並繪製到瀏覽器中所花的時間就越長,所以應儘可能保持DOM元素簡潔和層級較少。
1 2 3 4 5 6 7 8 9 10 11 |
<!-- 不推薦 --> <div> <span> <a href="javascript: void(0);"> <img src="./path/photo.jpg" alt="圖片"> </a> </span> </div> <!-- 推薦 --> <img src="./path/photo.jpg" alt="圖片"> |
5.儘量避免使用<table>、<iframe>等慢元素
內容的渲染是將table的DOM渲染樹全部生成完並一次性繪製到頁面上的,所以在長表格渲染時很耗效能,應該儘量避免使用它,可以考慮使用列表元素代替。儘量使用非同步的方式動態新增iframe,因為iframe內資源的下載程式會阻塞父頁面靜態資源的下載與CSS及HTML DOM的解析。
6.避免執行耗時的JavaScript
長時間執行的JavaScript會阻塞瀏覽器構建DOM樹、DOM渲染樹、渲染頁面。所以,任何與頁面初次渲染無關的邏輯功能都應該延遲載入執行,這和JavaScript資源的非同步載入思路是一致的。
7.避免使用CSS表示式或CSS濾鏡
CSS表示式或CSS濾鏡的解析渲染速度是比較慢的,在有其他解決方案的情況下應該儘量避免使用。
1 2 3 4 |
// 不推薦 .opacity{ filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50); } |