現在網上也有很多關於前端檔案載入的效能優化,我相信大部分的前端程式猿,應該都聽說過雅虎的14條優化原則
1. 儘可能的減少 HTTP 的請求數 content
2. 使用 CDN(Content Delivery Network) server
3. 新增 Expires 頭(或者 Cache-control ) server
4. Gzip 元件 server
5. 將 CSS 樣式放在頁面的上方 css
6. 將指令碼移動到底部(包括內聯的) javascript
7. 避免使用 CSS 中的 Expressions css
8. 將 JavaScript 和 CSS 獨立成外部檔案 javascript css
9. 減少 DNS 查詢 content
10. 壓縮 JavaScript 和 CSS (包括內聯的) javascript css
11. 避免重定向 server
12. 移除重複的指令碼 javascript
13. 配置實體標籤(ETags) css
14. 使 AJAX 快取複製程式碼
有些人通過這14個規則總結了一下:
優化方向 | 優化手段 |
---|---|
請求數量 | 合併指令碼和樣式表,CSS Sprites,拆分初始化負載,劃分主域,字型圖示,雪碧圖片等 |
請求頻寬 | 開啟伺服器GZip,精簡JavaScript,移除重複指令碼,影像優化(包括圖片大小kb) |
快取利用 | 使用CDN,使用外部JavaScript和CSS,新增Expires頭,減少DNS查詢,配置ETag,使AjaX可快取 |
頁面結構 | 將樣式表放在頂部,將指令碼放在底部,儘早重新整理文件的輸出 |
程式碼校驗 | 避免CSS表示式,避免重定向 |
前端資源的優化
今個主要說一下資源部署和優化的一些方案,也借鑑了好多人的理解和圖來說一下
1、資源的預載入(prebrowsing)
預載入是瀏覽器對將來可能被使用資源的一種暗示,一些資源可以在當前頁面使用到,一些可能在將來的某些頁面中被使用。作為開發人員,我們比瀏覽器更加了解我們的應用,所以我們可以對我們的核心資源使用該技術。
我們可以使用該技術來預先告知瀏覽器某些資源可能在未來會被使用。
DNS 預解析dns-prefetch
Head頭部裡面加入: <link rel="dns-prefetch"href="//example.com"> # 請求這個域名下的檔案時就不需要等待DNS查詢了,也就是說在瀏覽器請求資源時,DNS查詢就已經準備好了 # 該技術對使用第三方資源特別有用,比如jquery等複製程式碼
預連線 Preconnect
# 與 DNS 預解析類似,preconnect 不僅完成 DNS 預解析,同時還將進行 TCP 握手和建立傳輸層協議 <link rel="preconnect" href="http://example.com">複製程式碼
現代瀏覽器都試著預測網站將來需要哪些連線,然後預先建立 socket 連線,從而消除昂貴的 DNS 查詢、TCP 握手和 TLS 往返開銷。然而,瀏覽器還不夠聰明,並不能準確預測每個網站的所有預連結目標。好在,在 Firefox 39+ 和 Chrome 46+ 中我們可以使用 preconnect 告訴瀏覽器我們需要進行哪些預連線。
預獲取 Prefetching
# 顧名思義,提前載入資源(未用到),首先要確定這個資源一定會在未來用到,然後提前載入,放入瀏覽器快取中 <link rel="prefetch" href="image.png">複製程式碼
prefetch很適用於優化webfonts的效能,但預獲取還依賴於一些條件,某些預獲取可能會被瀏覽器忽略,例如從一個非常緩慢的網路中獲取一個龐大的字型檔案。並且,Firefox 只會在瀏覽器閒置時進行資源預獲取。
優先順序Subresource
這個也是預獲取方式,只是不同的是,指定的預獲取資源具有最高的優先順序,在所有 prefetch 項之前進行<link rel="subresource" href="styles.css">複製程式碼
預渲染 Prerender
# Prerender 預先載入的資原始檔,也就是說可以讓瀏覽器提前載入指定頁面的所有資源 <link rel="prerender" href="http://example.com/index.html">複製程式碼
未來 Preload
以上是預載入的基本解釋,詳細檢視詳解文章# Preload 建議允許始終預載入某些資源,不像prefetch有可能被瀏覽器忽略,瀏覽器必須請求preload標記的資源 <link rel="preload" href="http://example.com/image.png"> # 存在相容性複製程式碼
2、利用304本地快取資原始檔
我們大家都知道,正常的網路請求的返回狀態是200,如果我們每次訪問頁面之後,都要去載入,這樣就會浪費頻寬,影響頁面的效能,那麼我們現在就需要304來讓瀏覽器使用本地快取
HTTP 304
- 使用者首次請求該檔案的時候,通過HTTP HEAD的Last-Modified欄位將該檔案的最後修改日期傳送到客戶端,讓客戶端知道該檔案的版本
- 瀏覽器再次請求該檔案的時候,會自動將該時間作為請求的HTTP HEAD的If-Modified-Since欄位內容
- 服務端根據If-Modified-Since欄位的內容(如果存在該欄位)來判斷客戶端的檔案是否已經過期,如果已經過期,則重新返回新的檔案,如果沒有,則只需要返回304狀態碼,不需要返回檔案內容。檔案是否過期可以從Cache-Control設定max-age值,那麼在此值內的時間裡就不會重新訪問伺服器
- 對於靜態檔案,例如:CSS、圖片,伺服器會自動完成 Last Modified 和 If Modified Since 的比較,完成快取或者更新
- 對於動態頁面,就是動態產生的頁面,往往沒有包含 Last Modified 資訊,這樣瀏覽器、閘道器等都不會做快取,也就是在每次請求的時候都完成一個 200 的請求。因此,對於動態頁面做快取加速,首先要在 Response 的 HTTP Header 中增加 Last Modified 定義,其次根據 Request 中的 If Modified Since 和被請求內容的更新時間來返回 200 或者 304 。雖然在返回 304 的時候已經做了一次資料庫查詢,但是可以避免接下來更多的資料庫查詢,並且沒有返回頁面內容而只是一個 HTTP Header,從而大大的降低頻寬的消耗,對於使用者的感覺也是提高。
如果想清除快取檔案,可以按CTRL-F5 (有時稱之為“強刷-hard refresh”),這時候會發現瀏覽器省略了If-Modified-Since和If-None-Match請求頭,也就是無條件的請求頁面中的每個資源.
如果伺服器資源更新了,前端還在使用快取檔案,如果想讓頁面更新快取檔案怎麼辦?不可能讓使用者自己去清除自己的快取吧?
下面我們來說一種快取更新的檔案
3、版本號更新資原始檔
<link href="./static/css/main.css?v=1.0.0" rel="stylesheet">
或
<link href="./static/css/main.css?time=1245639" rel="stylesheet">複製程式碼
如果我們更新了main.css
檔案,那麼只需要更改v=
後面的版本號即可重新載入main.css資原始檔,其實也可以用hash值來表示
<link href="./static/css/main_88f0972.css" rel="stylesheet">複製程式碼
還有一種情況就是,如果我有n個檔案,但是我只更新了其中一個檔案,這個時候我不想其他的檔案更新的話,那麼我們就需要做到一點,只改變我要更新的檔案的版本號或者其他的值即可更新此資原始檔
4、CDN靜態資源部署
也就是說,把靜態資原始檔和動態網頁分叢集部署,靜態資源會被部署到CDN節點上,網頁中引用的資源也會變成對應的部署路徑
原理:不同地區的使用者會訪問到離自己最近的相同網路線路上的
CDN
節點,當請求達到CDN
節點後,節點會判斷自己的內容快取是否有效,如果有效,則立即響應快取內容給使用者,從而加快響應速度。如果CDN
節點的快取失效,它會根據服務配置去我們的內容源伺服器獲取最新的資源響應給使用者,並將內容快取下來以便響應給後續訪問的使用者。因此,一個地區內只要有一個使用者先載入資源,在CDN中建立了快取,該地區的其他後續使用者都能因此而受益。不同地區的使用者訪問同一個域名卻能得到不同
CDN
節點的IP
地址,這要依賴於CDN
服務商提供的智慧域名解析服務,瀏覽器發起域名查詢時,這種智慧DNS
服務會根據使用者IP
計算並返回離它最近的同網路CDN
節點IP
,引導瀏覽器與此節點建立連線以獲取資源。
也有一些第三方的CDN: 前端公共庫CDN加速
5、非覆蓋式釋出資源
目前很多更新自由檔案都是覆蓋式的釋出,但是覆蓋式的釋出會造成一些問題
用
待發布資源
覆蓋已釋出資源
,無論是先上線頁面
,還是先上線靜態資源
都會在部署過程中發生頁面錯亂的問題。所以就需要非覆蓋式釋出
,用檔案的雜湊值
來對資原始檔進行重新命名,把雜湊字串放到資原始檔釋出路徑中,這樣,內容有修改的資源就變成了一個新的檔案釋出到線上,不會覆蓋已有的資原始檔,這樣使用者在訪問的時候就不會出現錯亂的問題。
這種資源很多,不止css,包括js,圖片路徑,字型圖示庫等
<link href="./static/css/main_88f0972.css" rel="stylesheet">複製程式碼
下面借鑑一個圖來示例一下,很容易看懂:
這種方法雖然優化了資原始檔,但是它無法通過手動來維護,需要一些工具來支援,
推薦幾個構建工具:
還有其他的就不說了,自己可以google一下,好多的內容我也是看了很多篇的講資源優化的方案總結出來的,有不對的地方可以請批評指出,上面有些講解我也是在做筆記的時候記錄的,來源我沒有標記,感謝那些人的精彩講解,大家共同學習
來源:blog.csdn.net/xllily_11/a…
或者www.zhihu.com/question/20…
原文來自我的blog:codehtml