HTTP/2 從零到一

什麼是 HTTP/2?

在談到 HTTP/2 之前,讓我們先回顧一下整個 HTTP 發展的歷史。

1989 年,Berners Lee 提出了 World Wide Web (WWW) 這個 project,成為了世界上第一版的網路,而剛誕生的網路只存在一種 HTTP Method,即是 GET,當時所有的 server response 全都是靜態的 HTML。

一直到了 1996 年,HTTP/1.0 進入人們的世界中。隔年,我們至今仍四處可見的 HTTP/1.1 便誕生了,我們至今熟悉的 HTTP Method、Status Code、Header 等等也都在這些時候出現。

而 HTTP/2 本身可以說是起源於 SPDY Protocol,由一群來自 Google 的 engineers 所研發。雖然最後 SPDY 並沒有成為 HTTP/2,但是有很大一部分的設計理念都來自於此。

在 2015 年 5 月,HTTP/2 被正式介紹給世界,而這將近 20 年的歷史中,我們終於有能更貼近現代傳輸需求的 protcol,可以更大幅度提升使用者體驗。

為什麼我們需要 HTTP/2?

HTTP 基本上是一個 request <-> response 的 protocol,當時的設計主要是用於 browser 跟 server 之間進行 plain text 一次性的傳輸。

而後來的 HTTP/1.0 引入了其他多媒體類型,例如圖片。而 HTTP/1.1 除非明確指定,不然將預設 persist connection,所以多個 requests 可以重複使用相同的 connection 而減少使用者的等待時間。

這些都是很不錯的進步,讓使用者能有更好的體驗。然而,在 2000 年以後,網頁技術開始有飛躍性地進步,從 AJAX、jQuery、CSS3、HTML 5 到後來的 Angular、React、Vue 等等,都讓工程師能用更簡單的方法完成更複雜的前端應用程式,這也同時意味著 client 跟 server 端會容易有更多的互動。

左: 2010 ~ 2019 網頁渲染所需下載 kb / 右: 2010 ~ 2019 網頁渲染所需 requests 數 / Source: https://httparchive.org/reports/state-of-the-web

從上圖中可以看出,網頁所需要的數據大小或是請求數都是不斷上升地。
HTTP/1.x 仍有一些基礎上的限制,像是純文字傳輸、缺少 server 主動推送資料的能力 等等,讓我們沒辦法進一步提高效能。而這一些 HTTP/2 才具備的優勢,會在下面詳細介紹。

HTTP/2 比 HTTP/1.x 好在哪?

先用一個清單列出使用 HTTP/2 的好處,針對某些優點,我們下面會有更詳細的解釋。

  • 與 HTTP/1.x 的許多標準相容(method, status code, etc.)
  • Header Compression(頭部壓縮)
  • Binary Protocol(二進位協定)
  • HTTP/2 Server Push(伺服器推送)
  • TCP Multiplexing(多路複用)
  • No HOL blocking

HTTP/1.x 一直以來都有 Head-of-Line blocking 的問題,意即當一個 request 下載的內容過大時,會阻塞其他 request。雖然 HTTP/1.1 出現了 pipelining 試圖解決這個問題,但因實作細節上的難度,沒有被大多數 browser 支援,且因為要求 request 的 response 要有序,所以若任何一個 request 太大或太慢時,依然會有 blocking 的問題。

而 HTTP/2允許 client 透過同一個 TCP connection 同步發送多個 requests 給 server,而 server 也能用同一個 TCP connection 同步回傳,進而減少額外的 RTT (round trip time)

HTTP/2 利用 HPACK 進行壓縮,其中包含 1. 靜態字典 2. 動態字典 3. 霍夫曼編碼三種方式,將大量重複的 Header key:value 壓縮成 1 ~ 2 bytes。
在許多 modern web,初始頁面渲染常常要 80 甚至 100 個 requests,Header Compression 在節省流量上有顯著的效益。

HTTP/2 在傳輸時是以 Binary 為主,這大大減輕了實作上的負擔,而且 Binary 的 Parsing 遠遠比 Text 還要來得有效率。
在 HTTP/1.1,為了正確處理純文字的 parsing(換行、空行、空白等等都是需要特別處理),定義了四種方法,而在 HTTP/2 中只需要一種處理方式。

以一般的 web 為例,傳統 HTTP/1.x 要等到 browser 收到 HTML 之後,再根據上面指定的網址去索取對應的 CSS 跟 JavaScript。
而透過 Server Push,server 可以在 client 提出後續請求之前,主動將這些已知會被接著請求的檔案推送給 client。

HTTP 2 在各大 browser 的支援度

https://caniuse.com/#feat=http2
Source: https://caniuse.com/#feat=http2

Edge / Firefox / Chrome / Opera 皆在 2015 年起就支援 HTTP/2。
基本上不需要太擔心主流瀏覽器的支援性問題,

如何在 Node.js 中使用 HTTP/2

Node.js 本身就有 http2 的 module 可以直接使用,完全不需要 install 其他 lib 就可以體驗 HTTP/2

當然透過 Web Framework 的支援除了能使用 HTTP/2 之外,也能擁有其他 Framework 的優點

最後從 Chrome Inspector 中可以看到 Protocol 皆為 h2,而除了 html 外的圖片檔案的 Initiator 皆為 Push

詳細的 Source Code 請參考 https://github.com/hieven/node-http2

參考

--

--

--

目前在英國倫敦的台灣人軟體工程師,曾經待過台灣、新加坡、荷蘭。希望透過分享,來產生更多思維碰撞💥 | LinkedIn: @hieven

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Even Chang

Even Chang

目前在英國倫敦的台灣人軟體工程師,曾經待過台灣、新加坡、荷蘭。希望透過分享,來產生更多思維碰撞💥 | LinkedIn: @hieven

More from Medium

Creating ExtJS applications with coon.js — Part 2: Packages and Configuration Options

How to Fix Your Security Vulnerabilities with NPM Overrides

My gloriest bug — Node.js Event-Loop

Fix React start command Connection Refused on Docker-Compose