Benjamin發表於2015年3月18日html
互聯網工程任務組(IETF)於2015年2月經過了HTTP/2標準的提議。HTTP/2是HTTP協議自1999年HTTP 1.1發佈後的首個重要的更新。HTTP/2的主要目標是保持與HTTP/1.1的高度兼容性,同時減小延遲。換句話說,避免破壞Web,同時速度更快。git
自2009年末以來,谷歌一直在開發一種名爲SPDY的實驗性協議(發音爲speedy)。SPDY是Google的商標,而不是首字母縮略詞。HTTP/2最初基於SPDY進行實驗。其實,許多SPDY核心開發人員都參與了HTTP/2的開發。截至2015年2月,谷歌宣佈到2016年將徹底撤銷對SPDY的支持,轉而對HTTP/2進行支持。github
雖然HTTP/1.1自1999年發佈以來一直很好用,它是專爲當時的計算機和Web而設計的。毋庸置疑,HTTP早就應該進行更新了。爲了更好的描述HTTP/1的工做原理,以下圖所示。web
按照如下數字表示的步驟,首先從客戶端(或者Web瀏覽器)開始,在右側創建與服務器的HTTP/1鏈接。chrome
(2)客戶端/瀏覽器訪問網站的index.html頁面併發送了一個GET請求(HTTP方法)。瀏覽器
(3)第三步表示服務器響應請求的資源。緩存
(4-7)HTML文檔所需的CSS樣式和JS腳本的請求過程,和上面例子中的請求響應週期同樣。安全
(8)結束,HTTP/1鏈接關閉。bash
衆所周知,客戶端/瀏覽器花費大量時間等待每一個資源。因爲HTTP/1沒法經過單個鏈接發出併發請求,所以瀏覽器一般會嘗試經過打開多個鏈接來加快進程。服務器
從計算機網絡的角度來看,雖然多個鏈接是有幫助的,但每打開一個鏈接都很是昂貴。因此,現代瀏覽器將HTTP/1.1鏈接數限制爲最多6-8個。因爲許多網站如今須要80個或更多資源,所以這些限制會產生嚴重的性能瓶頸。
HTTP/1.1嘗試使用HTTP管線化的技術來糾正性能瓶頸。然而,當有一個大的或慢的響應的時候,它仍然會阻塞隨後的其餘響應(也就是說,仍是會出現線頭阻塞的現象)。HTTP管線化很難進行部署。沒有現代瀏覽器支持HTTP管線化,由於許多中介和服務器沒法正確處理它。
多路複用容許多個request-response消息同時在單個HTTP/2鏈接上傳輸。爲了演示HTTP/2鏈接的效率,以下圖,與HTTP/1進行了比較。即便在只有三個必需資源的簡單示例中,請注意網頁開始渲染的速度有多快。
將80種所需資源的常見狀況進行對比,能夠明顯的得出6-8個HTTP/1.1的鏈接開銷以及單個HTTP/2鏈接的效率。
除了多路複用,HTTP/2是二進制的,而不像HTTP/1是文本。與文本協議相比,二進制協議解析效率更高,在線上更嚴謹、不容易出錯。
HTTP/2還會經過壓縮headers來減小開銷,而HTTP/1則不會。
Server Push(服務器推送)是一種HTTP/2機制,用於在客戶端請求以前向客戶端發送數據。例如,若是你的主頁有請求,服務器可使用主頁以及徽標、樣式表進行響應,由於它知道客戶端須要這些資源。除了推送的資源能夠緩存外,這與在HTML文檔中內聯全部資源基本相同。
在客戶端已經緩存資源的狀況下,Server Push可能就會顯得冗餘。因此我建議使用Server Hints(服務器提示)。
在客戶端發現資源以前,Server Hints(服務器提示)告知客戶端即將須要的資源。服務器不發送資源的所有內容,而只發送URL。而後,客戶端能夠驗證其緩存,若是須要的話就正式請求資源。Server Hints對於HTTP/2並不陌生,但值得一提的是,它們不會受到服務器推送可能形成冗餘的缺陷的影響。
Server Hints是使用帶有HTTP的連接頭實現的,並與現有的連接預取語義重疊。例如,HTTP連接頭以下所示:
Link: <https://example.com/images/large-background.jpg>; rel=prefetch
複製代碼
若是HTML文檔在head標記中包含預取連接,則不須要服務器端實現。例如:
<link rel="prefetch" href="https://example.com/images/large-background.jpg">
複製代碼
想要了解有關rel =「prefetch」的更多信息,請參閱Mozilla關於連接預取的常見問題解答
預加載關係用於聲明資源和獲取屬性。此規範經過其餘處理策略擴展了功能,這些策略能夠有效地獲取下一個導航可能須要的資源。例如:
<!-- fetch and preprocess for next navigation -->
<link rel="preload" href="//example.com/next-page.html" as="html" loadpolicy="next">
<!-- fetch and do not preprocess for next navigation -->
<link rel="preload" href="//example.com/next-component.html" as="html" loadpolicy="next inert">
複製代碼
"next inert"至關於某些瀏覽器實現的rel = prefetch。「next」在語義上至關於某些瀏覽器實現的rel = prerender。該規範經過使附加功能標準化並擴展了之前的預取和預渲染功能。
要了解更多信息,請參閱由Ilya Grigorik發佈在W3C上的Resource Hints。
儘管HTTP/2的主要目標是使Web更快,可是因爲沒有強制對鏈接進行加密,它受到了很嚴厲的批評。並且,主要的瀏覽器製造商迄今拒絕對沒有加密的HTTP/2進行支持。因此HTTP/2經過代理來部署加密的鏈接。若是你認爲這不利於Web的將來,請查看個人文章:HTTPS Everywhere
譯者注: 這裏說HTTP/2沒有強制對鏈接進行加密。可是維基百科上提到針對加密的爭議時說:
一開始,以HTTP工做組某位主席爲首的成員在郵件列表建議引入強制使用TLS協議實現的HTTP/2.0(Mandatory TLS in HTTP/2.0),這招致了爭議。批評者認爲,加密增長了十分沒必要要的開銷,並且不少HTTP服務實際上無需加密,提供者也無心爲此花費更多的資源。而支持者認爲,實踐中TLS加密的開銷微不足道。
Poul-Henning Kamp 批評IETF在制定HTTP/2時,遵循了一個特定的「政治議程」(political agenda),壓縮了討論的空間。
強制加密議程的批評者認爲,其基於現有的證書框架,對於開源社區並不是新創造,亦不是獨特的。2013年,一位思科員工表示,現有證書模型與路由器一類的小型化設備並不兼容,由於現有的證書框架須要爲每張證書付出不可避免的成本,還須要進行每一年更新的流程。工做組最終未能在強制加密這一點上達成一致,可是大部分客戶端只實現了基於TLS的HTTP/2,使之成爲事實標準。
HTTP/2也被批評未能支持機會性加密,即相似SMTP中存在已久的STARTTLS同樣能抵禦被動監控的措施。 批評者指出,HTTP/2的提議違背了IETF自身制定的《最佳實踐 188》(BCP 188) 即 RFC 7258。這份文件指出,被動監控應被看成一種攻擊,IETF指定的標準應當設置抵禦這種攻擊的措施(例如機會性加密)。目前,已經有一系列機會性加密規範被提出,工做組也制定了 draft-ietf-httpbis-http2-encryption-01 這一官方版方案。
複製代碼
chrome://flags/#enable-spdy4
能夠在GitHub HTTP/2 wiki上找到HTTP/2的其餘已知實現。
正如咱們探討的那樣,HTTP/2是Web早就應該作的更新。隨着它在將來幾年被普遍採用,網站和其餘網絡服務將變得比以往更快,更強。感謝具備遠見的瀏覽器製造商,HTTP/2也將加強用戶隱私和安全性。雖然還有許多工做要作,但我以爲HTTP/2是整個Web的重要一步。
若是你對HTTP/2有任何問題或意見,能夠經過Twitter @BenjaminPatch 與我聯繫。
感謝Google的網絡性能工程師Ilya Grigorik對這篇HTTP/2文章的貢獻。Ilya仍是高性能瀏覽器網絡的做者,它是Web開發人員瞭解有關網絡和瀏覽器性能的很棒的資源。