標籤:

HTTP/2 對現在的網頁訪問,有什麼大的優化呢?體現在什麼地方?

近日,互聯網工程任務組(Internet Engineering Task Force ,IETF)對HTTP/2做了最後修整,並準備正式發布HTTP/2。HTTP/2是新一代的HTTP協議,它是由IETF的httpbis工作組開發,基於SPDY協議,目標是在保持與HTTP 1.1語義向後兼容性的情況下,減小網路傳輸延遲,並簡化伺服器向瀏覽器傳輸內容的過程。

http://mp.weixin.qq.com/s?__biz=MjM5MDE0Mjc4MA==mid=201005383idx=1sn=e8b0ee4f39d94982b334add02420780a#rd


毫無疑問,Web 性能的終極目標是減少到用戶端的延遲,讓用戶能夠儘快的打開前端網頁並進行相關交互。

就 HTTP 而言,理想的協議應該看起來是這樣的:

而對於客戶端來說,應該儘可能發送少的數據給伺服器,從服務端下載儘可能少的數據,儘可能減少往返 (Round Trips) ,客戶端與伺服器無論是哪一邊,額外的數據流都會帶來額外的延遲開銷,與此同時也更容易出現擁塞和丟包問題,這無疑嚴重影響了性能。
多餘的 Round Trip 同樣會增加延遲,尤其是在移動網路下(100ms 是讓用戶感覺到系統立即做出響應的時間上限)
那麼究竟理想中的 HTTP 是什麼樣的,而我們又該如何去優化?

HTTP/1.1

HTTP/1.1 這個協議本身有很多的優點,不幸的是性能並不在其中
一個典型的頁面請求是這樣的:

顯然這並不理想

HTTP/1 是 chatty 類的協議 ,因為需要不斷的去向伺服器請求新東西,首先是 HTML 其次是 CSS 和 JavaScript,每一次的交換都增加了額外或者是更多的 Round Trip 延遲,明顯和「儘可能減少 Round Trips」的目標背道而馳。

其次,頁面上的請求增加了很多的數據,違背了「應該儘可能發送少的數據給伺服器」的原則,請求中增加了諸如 Referer、User-Agent 等啰嗦的首部,當然 Cookie 是每一次請求都要帶上的。

最後因為 HTTP/1 的線頭阻塞 (Head of line blocking),使得過去合併多個請求為一個請求成為公共實踐,諸如 CSS Sprite、inline image 等其他系列的實踐,看似華麗的 HTTP/1 性能優化,實則有一定的開銷。
它下載的數據遠遠超過客戶端展示頁面所需要的數據,違背了理想化的原則,意味著我們無法儘可能快速的展示頁面 ,好在 HTTP/1.1 也不是一無是處,在性能方面,它提供了緩存。這就使得你可以重用新鮮的緩存,而無需重新發起額外的請求,當緩存中存在不新鮮的 copy 時,能很好的避免傳輸大量的數據。

HTTP/2

HTTP/2 試圖從以下幾個方面,解決 HTTP/1.1 中的幾個歷史遺留問題:

多路復用 (Multiplexing)

多路復用意味著線頭阻塞將不在是一個問題,允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息,合併多個請求為一個的優化將不再適用。

首部壓縮 (Header Compression)

首部壓縮移除了請求中的一些啰嗦首部,你可以通過很少的 IP package,承載數十個乃至上百個的請求,更符合最小數據量的理想化原則。

服務端推送(Server Push)

伺服器可以向客戶端推送所需要的資源,避免不必要的 Round Trips,所以一個典型的 HTTP/2 請求交互是這樣的:

&這裡你會發現,服務端會向客戶端發送 CSS,JavaScript 以及圖片文件,而無需通知客戶端,服務端知道客戶端可能會需要什麼。所以它使用 Server Push 發送多個響應給客戶端。節省了 Round Trip ,此時就變成了一個

這裡你會發現,服務端會向客戶端發送 CSS,JavaScript 以及圖片文件,而無需通知客戶端,服務端知道客戶端可能會需要什麼。所以它使用 Server Push 發送多個響應給客戶端。節省了 Round Trip ,此時就變成了一個 Less chatty 的協議,同時也充分的利用了網路資源。

友情提示,並不是說這些都已經是唾手可得很容易的,關於 HTTP/2 依舊是有許多的問題,尤其是何時去 Push,我會分段在後期進行解釋。

HTTP/2 緩存策略 + Cache Digests

關於 Server Push ,一個常見的問題是:

「如果客戶端早已在緩存中有了一份 copy 怎麼辦?」

因為 Push 本身具有投機性,所以肯定會出現推送過去的東西瀏覽器不需要的情況。

這種情況下,HTTP/2 允許客戶端通過 RESET_STREAM 主動取消 Push ,然而這樣的話,原本可以用於更好方向的 Push 就白白的浪費掉數據往返的價值。

對此,一個推薦的解決方案是,客戶端使用一個簡潔的 Cache Digest 來告訴伺服器,哪些東西已經在緩存,因此伺服器也就會知道哪些是客戶端所需要的。

因為 Cache Digest 使用的是 Golumb Compressed Sets,瀏覽器客戶端可以通過一個連接發送少於 1K 位元組的 Packets 給服務端,通知哪些是已經在緩存中存在的。

現在,我們已經解決了 chattiness、額外的 Round Trip 開銷、啰嗦首部的數據浪費、inline 以及過去的其他優化行為、最後則是 Push 重複資源帶來數據浪費,這和我們理想化的目標越來越近了。

Cache Digests 只是其中一個提案之一, 在 HTTP 社區有著更多其他的解決方案,我們也希望在不久的將來看到他們的身影。

TCP

至此,我還沒有談到的其他協議對瀏覽器載入網頁時的性能影響。在 HTTP 開始之前 TCP 需要進行三次握手,來協商新連接的參數。這意味著在建立連接的時候,一個最簡單的 HTTP 請求也需要 2 個 Round-Trip Time 才能完成 。

TCP Fast Open 允許應用在 TCP 握手期間(SYN 和 SYN+ACK packets)交換數據,這樣可以減少一次 RTT,不幸的是目前只支持 Linux 以及 OSX,未來 TFO 在 HTTP上將會有更多巧妙的運用。

TFO 不保證與 SYN 數據包發送的數據將只出現一次;這是容易重複(由於重傳),甚至被惡意的重放攻擊。 因此,在一個 TFO 連接上使用 HTTP POST 並不是建立第一個請求的好主意。 並且,使用 GET 也依然會有很大的副作用,瀏覽器也沒有好的辦法來檢測哪個 URL 可以做到這一點的。

TLS

在傳輸應用數據之前,客戶端必須與服務端協商密鑰、加密演算法等信息,服務端還要把自己的證書發給客戶端表明其身份,這些環節構成 TLS 握手過程,還沒把客戶端和服務端處理時間算進去。光是 TLS 握手就需要消耗兩個 RTT(Round-Trip Time,往返時間)

而 Session Tickets 可以將 TLS 握手所需 RTT 減少到 1 個:

不久的未來,TLS 1.3 將會支持 Zero Round Trip 握手,HTTP 可以在第一個 Round Trip 就發送數據。

註:

本文翻譯自 Mark Nottingham 的博客,Mark 是 IETF HTTP Working Group 的主席,Akamai 公司的首席架構師。

原標題:Ideal HTTP Performance


介紹HTTP/2的技術文章網上一大堆啊,不如自己體驗一下。

http://pan.baidu.com/s/1pK1ASOj

下載上面的壓縮包,裡面是我用Photoshop生成的測試頁,將一幅圖片分割成2500塊,也就是說,要完整載入圖片需要獲取2500個小文件,然後再拼成一幅圖。可以放到web伺服器做測試,下面是我這邊的測試結果。

未啟用HTTP/2,完整載入總耗時58.59秒。

啟用HTTP/2,完整載入只需耗時6.25秒。

可見,呈現完整頁面需要載入的文件越多優勢就越明顯,HTTP/1.1隻能靠多域名突破瀏覽器對並發連接數的限制,而HTTP/2則單域名單次鏈接已經實現並發,當然大多數的站點都幾乎不會同時載入2500個文件那麼變態,像淘寶(SPDY)首頁只有70個。


HTTP/2 的出現, 相比於 HTTP 1,大幅提升了 web 性能,減少網路延遲。

HTTP/2: the Future of the Internet 這個鏈接是一個演示Demo,用來比較 HTTP/2 與 HTTP/1.1 在性能上的差異。

相比 HTTP/1.x,HTTP/2 在底層傳輸做了很大的改動和優化:

  • 二進位分幀:HTTP/2 採用二進位格式傳輸數據,而非 HTTP/1.x 的文本格式。 HTTP/2 中,同域名下所有通信都在單個連接上完成,該連接可以承載任意數量的雙向數據流。每個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間可以亂序發送,根據幀首部的流標識可以重新組裝。

  • 頭部壓縮:HTTP/2 對消息頭採用 HPACK 進行壓縮傳輸,能夠節省消息頭佔用的網路的流量。而 HTTP/1.x 每次請求,都會攜帶大量冗餘頭信息,浪費了很多帶寬資源。頭壓縮能夠很好的解決該問題。

1. HTTP/2在客戶端和伺服器端使用「首部表」來跟蹤和存儲之前發送的鍵-值對,對於相同的數據,不再通過每次請求和響應發送;

2. 首部表在HTTP/2的連接存續期內始終存在,由客戶端和伺服器共同漸進地更新;

3. 每個新的首部鍵-值對要麼被追加到當前表的末尾,要麼替換表中之前的值。

  • 多路復用:直白的說就是所有的請求都是通過一個 TCP 連接並發完成。HTTP/1.x 雖然通過 pipeline 也能並發請求,但是多個請求之間的響應會被阻塞的,所以 pipeline 至今也沒有被普及應用,而 HTTP/2 做到了真正的並發請求。同時,流還支持優先順序和流量控制。當流並發時,就會涉及到流的優先順序和依賴。優先順序高的流會被優先發送。圖片請求的優先順序要低於 CSS 和 SCRIPT,這個設計可以確保重要的東西可以被優先載入完。

△HTTP1中,請求就因域名鏈接數已超過限制,而被掛起等待了一段時間

  • Server Push:服務端能夠更快的把資源推送給客戶端。例如服務端可以主動把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 再發送這些請求。當客戶端需要的時候,它已經在客戶端了。

又拍雲CDN 在 HTTPS 協議的基礎上已實現全平台支持 HTTP/2。

推薦閱讀:一文讀懂 HTTP/2 特性 - 知乎專欄


主要優化倒不是在網頁本身,而是在HTTP層的數據交互上,主要有server push、multiplexing、header compression等優化手段


https://docs.google.com/presentation/d/1l9c9ROjLTD8clOL0yFufAOMbxNC0D-19zCiXMgqtY-M/present?slide=id.p19 這個屁屁疼可以看下


吃貨小棧 - 一個吃貨的分享博客明月學習筆記Blog - 折騰LNMP的記錄微博客

個人感覺HTTP/2主要的性能表現還是在伺服器端的,客戶端主要還是看客戶端的支持情況了!一個不支持HTTP/2的瀏覽器可以說是不會有任何效果的!


在一定程度上緩解了head of line blocking,下一代協議QUIC會更好的解決這個問題。


推薦閱讀:

既然說 HTTP 是明文傳輸,為什麼沒聽說哪個著名的網站因為採用 http 協議而暴露了用戶的密碼?
用 http 數據加密和 https 有什麼區別?
http協議請求響應頭中參數的疑問??
HTTP 在什麼情況下會請求超時?
怎樣把 ssh、http 和 https 放到同一埠?

TAG:HTTP | HTTP2 |