2015 年 2 月,網際網路工程任務組(ietf)準許了 http/2 标準提案,1999 年 http/1.1 正式标準化 ,而 http/2 是自那時以來的首個重大更新。http/2 的主要目标是與 http/1.1 完全語義相容的基礎上,進一步減少網絡延遲。換句話說,http/2 要在不破壞原有 web 體系的基礎上使它變得更快。

<a target="_blank"></a>
自 2009 年底以來,google 一直在開發一個實驗性的協定,這個神秘的協定名叫 spdy(讀作 speedy)。spdy 并不是一個首字母縮略詞,其實,它是 google 注冊的一個商标,http/2 正是起源于這個 spdy 實驗。事實上,後來有許多曾經參與 spdy 項目的核心開發者同樣也加入到 http/2 的開發中去。在 2015 年 2 月,google正式宣布停止支援 spdy 計劃,全力支援 http/2 的開發,預計在 2016 年前實作全部功能。
自 1999 年以來,http/1.1 默默地為我們服務了十幾年,它是在當時那樣的計算機和網絡應用場景下被設計出來的。我不說你也知道,http 早就應該更新了。為了便于描述 http/1 是如何工作的,我在下面放了幾張圖解。根據序号的順序你就會看到,從用戶端開始(很可能是一個web浏覽器)與右方的伺服器建立一個 http/1 的連接配接。
(2) 用戶端/浏覽器随後發送一個 get 請求(http 方法)擷取 <code>index.html</code> 頁面。 (3) 伺服器響應用戶端請求的資源。 (4-7) 在我們這個簡單的示例中,這個不斷進行的 請求-響應循環過程 持續地擷取樣式表和腳本來完善整個 html 文檔。 (8) 最終,這個 http/1 連接配接斷開了。
http/1 請求/響應 循環
如你所見,用戶端/浏覽器 花費大量的時間等待每一個資源被響應。因為 http/1 不能在同一個連接配接上進行并發請求,浏覽器通常需要開啟多個連接配接來加速請求資源的過程。
即使開啟多個連接配接能有效提高資源的加載速度,但是從計算機網絡的角度來看,開啟每一個連接配接的代價都很高。是以,現代浏覽器通常都有最多 6-8 個 http/1.1 連接配接的限制,許多網站現在需要加載 80多個或者更多的資源,這些連接配接限制逐漸成為了整個 web 系統的性能瓶頸。
多路複用允許同時通過單一的 http/2 連接配接發起多重的請求-響應消息,為了向你們量化展示一個 http/2 連接配接到底快多少,我準備了一套并排的圖對比 http/2 與 http/1 的性能,在這個簡單的示例中隻請求 3 個資源,從 web 頁面開始渲染到加載結束,http/2 比 http/1 節省不少時間。
推而廣之,當 80 個資源複合請求時,與 http/1.1 相比,很明顯通過單一連接配接進行傳遞的 http/2 更高效!
http/1 與 http/2 作對比
除了多路複用,http/2 還是二進制的,與 http/1 這樣的文本協定相比,二進制協定解析起來更加高效。很顯然,二進制的協定更适合線上路進行傳輸,并且更不容易出錯。
http/2 同時也減少了壓縮頭部的開銷,這些在 http/1 裡都沒有實作。
在 http/2 中,伺服器推送是指在用戶端請求之前發送資料的機制。如果一個請求是由你的首頁發起的,伺服器很可能響應首頁内容、logo以及樣式表,因為它知道用戶端會用到這些東西。這相當于在一個 html 文檔内集合了所有的資源,不過與之相比,伺服器推送有一個很大的優勢:可以緩存!
當然這同時也是它的一個缺點,如果用戶端已經緩存了資料,此時會産生不必要的備援。這也是為什麼我推薦伺服器提示(server hints)的原因。
伺服器提示可以先于用戶端檢測到将要請求的資源,提前通知用戶端,伺服器不發送所有資源的實體,它隻發送資源的 url。用戶端接到提示後進一步驗證之前的緩存,如果發現需要這些資源,則正式發起請求。伺服器提示對 http/2 來說興許不是最新的,但非常值得在這裡順便一提,因為它沒有上文提到的伺服器推送備援的缺點。
伺服器提示是通過 http link header 和與已實作的 link prefetching 語義重疊的部分來實作的。舉個例子,一個 http link header 看起來是這樣的:
如果 html 文檔的 head 标簽中有一個 <code>prefetch</code> link标簽,不需要在服務端有額外的實作,舉個例子:
預加載關聯用于聲明一個資源和它的 fetch 屬性,這個規範通過額外的處理政策擴充了功能,有效地擷取在下一個導航可能需要請求的資源,舉個例子
一些浏覽器中,<code>loadpolicy="next inert"</code> 等同于 <code>rel=prefetch</code> 這樣的實作,<code>loadpolicy</code> 屬性的 <code>next</code> 值在語義上與 <code>rel=prerender</code> 相同,這個規範對預擷取和預渲染的功能進行了标準化,并且給他們擴充了額外的功能。
http/2 現在或者将來會被所有主流浏覽器支援。
chrome 40 支援 http/2 14 号草案,但是預設不開啟。http/2 17 号草案(也就是最終草案),現在可以在 chrome canary 43(開發者預覽版)裡使用了,目前隻有基于 tls(加密的)的 http/2 實作。 如需在 chrome 中啟用 http/2,通路: <code>chrome://flags/#enable-spdy4</code>
firefox 支援 http/2,在第 36 版中預設啟用,早在第 34 版中,就已經開始添加針對 http/2 的實驗性支援。目前也隻有基于 tls 的http/2 實作。
ie11 支援 http/2,但是隻在 windows 10 beta 版裡預設啟用。目前也隻有基于 tls 的 http/2 實作。
spartan 預計也會支援基于 tls 的 http/2,盡管微軟為 windows 10 打造的新浏覽器的有關細節尚未完全曝光。
safari 在 mac os x yosemite(10.10)和 ios 8 中預設支援 spdy,對于 http/2 的全支援預計在 2015 年底完成。
opera 預設支援 spdy。預計在 chrome 全部實作 http/2 最終草案的特性後全面支援 http/2。
iis(網際網路資訊服務)在 windows 10 beta 版中支援 http/2。
openlitespeed 1.3.8 和 1.4.5 支援 http/2 第 17 号草案。
apache 通過 mod_spdy 子產品支援老版本的 spdy,目前這個子產品已經停止開發。
litespeed web 伺服器目前支援 spdy/3.1。
nginx 通過一個子產品提供針對 spdy(draft 3.1) 的實驗性支援,計劃在 2015 年底支援 http/2。
lighttpd 在版本 1.x 中沒有支援 spdy 或 http/2 的計劃
正如我們所探索的,http/2 早就應該為更新 web 而出現,當它在接下來的幾年中被廣泛接受,網站和其它 web 服務将會變得更快,比以前任何時候更加能幹。感謝有遠見的浏覽器廠商們,http/2 将會增強使用者的隐私和安全。我認為對于整個 web 生态來說,http/2 是一次至關重要的飛躍,未來有許多新的事業正等着我們去開拓。
原文釋出時間:2015-03-27
本文來自雲栖合作夥伴“linux中國”