天天看點

前端性能優化——桌面浏覽器前端優化政策

來源于https://my.oschina.net/zhangstephen/blog/1601382

摘要: 前端性能優化是一個很寬泛的概念,本書前面的部分也多多少少提到一些前端優化方法,這也是我們一直在關注的一件重要事情。配合各種方式、手段、輔助系統,前端優化的最終目的都是提升使用者體驗,改善頁面性能,我們常常竭盡全力進行前端頁面優化,但卻忽略了這樣做的效果和意義。先不急于探究前端優化具體可以怎樣去做,先看看什麼是前端性能,應該怎樣去了解和評價前端頁面的性能。

  

通過性能測速和分析,我們基本可以擷取收集到頁面上大部分的具體性能資料,如何根據這些資料采取适當的方法和手段對目前的頁面進行優化呢?目前來看,前端優化的政策很多,如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放到外部檔案中,避免使用<style>或<script>标簽直接引入

在HTML檔案中引用外部資源可以有效利用浏覽器的靜态資源緩存,但有時候在移動端頁面CSS或JavaScript比較簡單的情況下為了減少請求,也會将CSS或JavaScript直接寫到HTML裡面,具體要根據CSS或JavaScript檔案的大小和業務的場景來分析。如果CSS或JavaScript檔案内容較多,業務邏輯較複雜,建議放到外部檔案引入。

<link rel="stylesheet" href="//cdn.domain.com/path/main.css">

<script src="//cdn.domain.com/path/main.js"></script>

4.避免頁面中空的href和src

當<link>标簽的href屬性為空,或<script>、<img>、<iframe>标簽的src屬性為空時,浏覽器在渲染的過程中仍會将href屬性或src屬性中的空内容進行加載,直至加載失敗,這樣就阻塞了頁面中其他資源的下載下傳程序,而且最終加載到的内容是無效的,是以要盡量避免。

<!-- 不推薦 -->

<img src="" alt="photo">

<a rel="nofollow" href="">點選連結</a>

5.為HTML指定Cache-Control或Expires

為HTML内容設定Cache-Control 或Expires可以将HTML内容緩存起來,避免頻繁向伺服器端發送請求。前面講到,在頁面Cache-Control或Expires頭部有效時,浏覽器将直接從緩存中讀取内容,不向伺服器端發送請求。

<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資源下載下傳的帶寬消耗并降低伺服器負載。

<meta http-equiv="last-modified" content="Mon, 03 Oct 2016 17:45:57 GMT"/>

7. 減少頁面重定向

頁面每次重定向都會延長頁面内容傳回的等待延時,一次重定向大約需要600毫秒的時間開銷,為了保證使用者盡快看到頁面内容,要盡量避免頁面重定向。

8.使用靜态資源分域存放來增加下載下傳并行數

浏覽器在同一時刻向同一個域名請求檔案的并行下載下傳數是有限的,是以可以利用多個域名的主機來存放不同的靜态資源,增大頁面加載時資源的并行下載下傳數,縮短頁面資源加載的時間。通常根據多個域名來分别存儲JavaScript、CSS和圖檔檔案。

<link rel="stylesheet" href="//cdn1.domain.com/path/main.css">

<script src="//cdn2.domain.com/path/main.js"></script>

9.使用靜态資源CDN來存儲檔案

如果條件允許,可以利用CDN網絡加快同一個地理區域内重複靜态資源檔案的響應下載下傳速度,縮短資源請求時間。

10.使用CDN Combo下載下傳傳輸内容

CDN Combo是在CDN伺服器端将多個檔案請求打包成一個檔案的形式來傳回的技術,這樣可以實作HTTP連接配接傳輸的一次性複用,減少浏覽器的HTTP請求數,加快資源下載下傳速度。例如同一個域名CDN伺服器上的a.js,b.js,c.js就可以按如下方式在一個請求中下載下傳。

<script src="//cdn.domain.com/path/a.js,b.js,c.js"></script>

11.使用可緩存的AJAX

對于傳回内容相同的請求,沒必要每次都直接從服務端拉取,合理使用AJAX緩存能加快AJAX響應速度并減輕伺服器壓力。

$.ajax({

url: url,

type: 'get',

cache: true,    // 推薦使用緩存

data: {}

success(){

    // ...

},

error(){

    // ...

}           

});

12.使用GET來完成AJAX請求

使用XMLHttpRequest時,浏覽器中的POST方法發送請求首先發送檔案頭,然後發送HTTP正文資料。而使用GET時隻發送頭部,是以在拉取服務端資料時使用GET請求效率更高。

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的引用可以如下設定,也可以使用子產品化加載機制來實作。

<script src="main.js" defer></script>

<script src="main.js" async></script>

使用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渲染完成的時間。

<style>

@import "path/main.css";

</style>

<!-- 推薦 -->

二、 頁面渲染類

1.把CSS資源引用放到HTML檔案頂部

一般推薦将所有CSS資源盡早指定在HTML文檔<head>中,這樣浏覽器可以優先下載下傳CSS并盡早完成頁面渲染。

2.JavaScript資源引用放到HTML檔案底部

JavaScript資源放到HTML文檔底部可以防止JavaScript的加載和解析執行對頁面渲染造成阻塞。由于JavaScript資源預設是解析阻塞的,除非被标記為異步或者通過其他的異步方式加載,否則會阻塞HTML DOM解析和CSS渲染的過程。

3.不要在HTML中直接縮放圖檔

在HTML中直接縮放圖檔會導緻頁面内容的重排重繪,此時可能會使頁面中的其他操作産生卡頓,是以要盡量減少在頁面中直接進行圖檔縮放。

4.減少DOM元素數量和深度

HTML中标簽元素越多,标簽的層級越深,浏覽器解析DOM并繪制到浏覽器中所花的時間就越長,是以應盡可能保持DOM元素簡潔和層級較少。

<div>

<span>

    <a rel="nofollow" href="javascript: void(0);">

        <img src="./path/photo.jpg" alt="圖檔">

    </a>

</span>           

</div>

<img src="./path/photo.jpg" alt="圖檔">

5.盡量避免使用<table>、<iframe>等慢元素

<table>内容的渲染是将table的DOM渲染樹全部生成完并一次性繪制到頁面上的,是以在長表格渲染時很耗性能,應該盡量避免使用它,可以考慮使用清單元素<ul>代替。盡量使用異步的方式動态添加iframe,因為iframe内資源的下載下傳程序會阻塞父頁面靜态資源的下載下傳與CSS及HTML DOM的解析。

6.避免運作耗時的JavaScript

長時間運作的JavaScript會阻塞浏覽器建構DOM樹、DOM渲染樹、渲染頁面。是以,任何與頁面初次渲染無關的邏輯功能都應該延遲加載執行,這和JavaScript資源的異步加載思路是一緻的。

7.避免使用CSS表達式或CSS濾鏡

CSS表達式或CSS濾鏡的解析渲染速度是比較慢的,在有其他解決方案的情況下應該盡量避免使用。

filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50);