自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HTTP/2 與 WEB 性能優(yōu)化(一)

網(wǎng)絡 網(wǎng)絡優(yōu)化 網(wǎng)絡運維
今年二月份,Google 宣布將在 16 年初放棄對 SPDY 的支持,隨后 Google 自家支持 SPDY 協(xié)議的服務都切到了 HTTP/2。今年 5 月 14 日,HTTP/2 以 RFC 7540 正式發(fā)布。目前,瀏覽器方面,Chrome 40+ 和 Firefox 36+ 都正式支持了 HTTP/2;服務器方面,著名的 Nginx 表示會在今年底正式支持 HTTP/2。

今年二月份,Google 宣布將在 16 年初放棄對 SPDY 的支持,隨后 Google 自家支持 SPDY 協(xié)議的服務都切到了 HTTP/2。今年 5 月 14 日,HTTP/2 以 RFC 7540 正式發(fā)布。目前,瀏覽器方面,Chrome 40+ 和 Firefox 36+ 都正式支持了 HTTP/2;服務器方面,著名的 Nginx 表示會在今年底正式支持 HTTP/2。

不得不說這幾年 WEB 技術一直在突飛猛進,爆炸式發(fā)展。昨天還覺得 HTTP/2 很遙遠,今天已經(jīng)遍地都是了。對于新鮮事物,有些人不愿意接受,覺得好端端為什么又要折騰;有些人會盲目崇拜,認為它是能拯救一切的救世主。HTTP/2 究竟會給前端帶來什么,什么都不是?還是像某些人說的「讓前端那些優(yōu)化小伎倆直接退休」?我打算通過寫一系列文章來嘗試回答這個問題,今天是***篇。

提出問題

我們知道,一個頁面通常由一個 HTML 文檔和多個資源組成。有一些很重要的資源,例如頭部的 CSS、關鍵的 JS,如果遲遲沒有加載完,會阻塞頁面渲染或導致用戶無法交互,體驗很差。如何讓重要的資源更快加載完是我本文要討論的問題。

HTTP/1

分析

我們先來考慮資源外鏈的情況。通常,外鏈資源都會部署在 CDN 上,這樣用戶就可以從離自己最近的節(jié)點上獲取數(shù)據(jù)。一般文本文件都會采用 gzip 壓縮,實際傳輸大小是文件大小的幾分之一。服務端托管靜態(tài)資源的效率通常非常高,服務端處理時間幾乎可以忽略。在忽略網(wǎng)絡因素、傳輸大小以及服務端處理時間之后,用戶何時能加載完外鏈資源,很大程度上取決于請求何時能發(fā)出去,這主要受下面三個因素影響:

瀏覽器阻塞(Stalled):瀏覽器會因為一些原因阻塞請求。例如在 rfc2616 中規(guī)定瀏覽器對于一個域名,同時只能有 2 個連接(HTTP/1.1 的修訂版中去掉了這個限制,詳見 rfc7230,因為后來瀏覽器實際上都放寬了限制),超過瀏覽器***連接數(shù)限制,后續(xù)請求就會被阻塞。再例如現(xiàn)代瀏覽器在加載同一域名多個 HTTPS 資源時,會有意等***個 TLS 連接建立完成再請求其他資源;

DNS 查詢(DNS Lookup):瀏覽器需要知道目標服務器的 IP 才能建立連接。將域名解析為 IP 的這個系統(tǒng)就是 DNS。DNS 查詢結果通常會被緩存一段時間,但***次訪問或者緩存失效時,還是可能耗費幾十到幾百毫秒;

建立連接(Initial connection):HTTP 是基于 TCP 協(xié)議的,瀏覽器最快也要在第三次握手時才能捎帶 HTTP 請求報文。這個過程通常也要耗費幾百毫秒;

當然我們一般都會給靜態(tài)資源設置一個很長時間的緩存頭。只要用戶不清除瀏覽器緩存也不刷新,第二次訪問我們網(wǎng)頁時,靜態(tài)資源會直接從本地緩存獲取,并不產(chǎn)生網(wǎng)絡請求;如果用戶只是普通刷新而不是強刷,瀏覽器會在請求頭帶上協(xié)商字段 If-Modified-Since 或 If-None-Match,服務端對沒有變化的資源會響應 304 狀態(tài)碼,告知瀏覽器從本地緩存獲取資源。304 請求沒有正文,非常小。

也就是說資源外鏈的特點是,***次慢,第二次快。

再來看看資源內(nèi)聯(lián)的情況。把 CSS、JS 文件內(nèi)容直接內(nèi)聯(lián)在 HTML 中的方案,毫無疑問會在用戶***次訪問時有速度優(yōu)勢。但通常我們很少緩存 HTML 頁面,這種方案會導致內(nèi)聯(lián)的資源沒辦法利用瀏覽器緩存,后續(xù)每次訪問都是一種浪費。

解決

很早之前,就有網(wǎng)站開始針對***次訪問的用戶將資源內(nèi)聯(lián),并在頁面加載完之后異步加載這些資源的外鏈版本,同時記錄一個 Cookie 標記表示用戶來過。用戶再次訪問這個頁面時,服務端就可以輸出只有外鏈版本的頁面,減小體積。

這個方案除了有點浪費流量之外(一份資源,內(nèi)聯(lián)外鏈加載了兩次),基本上能達到更快加載重要資源的效果。但是在流量更加寶貴的移動端,我們需要繼續(xù)改進這個方案。

考慮到移動端瀏覽器都支持 localStorage,可以將***次內(nèi)聯(lián)引入的資源緩存起來后續(xù)使用。緩存更新機制可以通過在 Cookie 中存放版本號來實現(xiàn)。這樣,服務端收到請求后,首先要檢查 Cookie 頭中的版本標記:

如果標記不存在或者版本不匹配,就將資源內(nèi)聯(lián)輸出,并提供當前版本標記。頁面執(zhí)行時,會把內(nèi)聯(lián)資源存入 localStorage,并將資源版本標記存入 Cookie;

如果標記匹配,就輸出 JavaScript 片段,用來從 localStorage 讀取并使用資源;

由于 Cookie 內(nèi)容需要盡可能的少,所以一般只存總的版本號。這會導致頁面任何一處資源變動,都會改變總版本號,進而忽略客戶端所有 localStorage 緩存。要解決這個問題可以繼續(xù)改進我們的方案:Cookie 中只存放用戶唯一標識,用戶和資源對應關系存在服務端。服務端收到請求后根據(jù)用戶標識,計算出哪些資源需要更新,從而輸出更有針對性的 HTML 文檔。

這套方案要投入實際使用,要處理一系列異常情況,例如 JS / Cookie / localStorage 被禁用;localStorage 被寫滿;localStorage 內(nèi)容損壞或丟失等等??紤]成本和實際收益,推薦只在移動項目中使用這種方案。

HTTP/2

對于 HTTP/2 來說,要解決前面這個問題簡直就太容易了,開啟「Server Push」即可。HTTP/2 的多路復用特性,使得可以在一個連接上同時打開多個流,雙向傳輸數(shù)據(jù)。Server Push,意味著服務端可以在發(fā)送頁面 HTML 時主動推送其它資源,而不用等到瀏覽器解析到相應位置,發(fā)起請求再響應。另外,服務端主動推送的資源不是被內(nèi)聯(lián)在頁面里,它們有自己獨立的 URL,可以被瀏覽器緩存,當然也可以給其他頁面使用。

服務端可以主動推送,客戶端也有權利選擇接收與否。如果服務端推送的資源已經(jīng)被瀏覽器緩存過,瀏覽器可以通過發(fā)送 RST_STREAM 幀來拒收。

可以看到,HTTP/2 的 Server Push 能夠很好地解決「如何讓重要資源盡快加載」這個問題,一旦普及開來,可以取代前面介紹過的 HTTP/1 時代優(yōu)化方案。

責任編輯:何妍 來源: Jerry Qu的小站
相關推薦

2015-09-15 10:54:54

HTTP2 WEB 性能優(yōu)化

2015-09-15 10:46:29

2024-02-29 18:06:39

HTTP性能優(yōu)化

2014-12-10 10:12:02

Web

2022-08-01 14:59:57

Web前端后端

2022-03-02 11:13:50

Web前端開發(fā)

2023-09-06 12:01:50

HTTP協(xié)議信息

2016-02-17 10:11:35

HTTP2Web性能

2015-06-23 16:36:11

Web性能優(yōu)化

2012-01-10 16:22:25

Web

2015-08-17 10:35:56

Web性能優(yōu)化

2013-01-22 15:27:23

WebWeb前端

2012-12-24 09:55:15

JavaJava WebJava優(yōu)化

2010-05-28 10:23:59

JavaScriptWeb

2014-03-19 14:34:06

JQuery高性能

2017-10-10 12:17:55

HTTPGo.NET Core

2016-11-01 10:59:04

web代理緩存

2019-03-06 10:25:30

Web圖片優(yōu)化命令

2019-03-14 15:38:19

ReactJavascript前端

2018-10-09 09:28:12

HTTPHTTP協(xié)作服務器
點贊
收藏

51CTO技術棧公眾號