背景

目前提升H5應用載入速度的方式有很多,比如快取、cdn加速、程式碼壓縮合並和圖片壓縮等技術。這些方法相信大夥如數家珍,然而這些招用完後,是否還有優化空間呢?現在我們祭出大殺器——HTTP 2.0 
相信大家聽說過HTTP 2.0,那麼它和HTTP 1.X相比效果到底如何呢?請看療效: 

單次頁面載入速度對比

實踐出真知,有請DEMO先生出場——一個網頁,載入了8張圖片,圖片大小合計10MB

  • http 1.x:

DOMContentLoaded: 215ms,  Load: 549ms

  • http2.0:

DOMContentLoaded:156ms, Load:491ms

從資料中大家可以看到,對於這個DEMO頁,HTTP 1.X需要花費549ms,而使用HTTP 2.0則可以減少60ms左右的等待。
Emmmm……才60ms,貌似沒想像中改善那麼大,60ms使用者應該無感吧?
確實對單次使用者訪問來說,改善不大,但是使用者瀏覽一個網站,不是一次就結束了,他會在接下來的時間裡與網站產生多次互動。如果每個請求我們都能節省一點點時間,那麼在使用者的多次互動中,累加起來的時間應該比較可觀了。


若是在大併發請求下,效果又當如何呢?上!壓!測!

壓測資料對比

模擬1,000,000 次請求壓測資料如下:

http不同協議請求引數對比

請求協議型別請求花費時間(s)每秒請求數每一請求花費時間交換速率(kb/s)
http1.1144.0356942.750.8647328.87
https-spdy128.1337804.360.7698238.4
https145.8836854.820.8757236.05
https with h2116.138611.280.6868140.8

從上表可以看到http2.0和http1.1相比,節省30s左右的時間,沒有對比沒有傷害。
(壓測方法可見文末附錄二)


網路表現不錯,我們再來看看伺服器資源消耗情況。

cpu 使用情況

我們將相關資料製成了圖表,方便大家比對

us: 使用者空間佔用cpu時間
sy:系統空間佔用cpu時間
hi: 硬碟中斷

si: 軟體中斷

http1.1

cpu(us+sy)平均:82.51%

http2.0

cpu(us+sy)平均:63.09%

療效相當不錯,看官們是否動心了呢?接下來為你呈上運用之道。

http 協議發展

使用http2.0的必備條件

預設https支援http2.0(2015年提出)
瀏覽器支援ALPN
 

檢視是否支援http2.0的三種方法

使用openssl測試

終端輸入:echo | openssl s_client -alpn h2 –connect 域名:443

通過Chrome瀏覽器的屬性檢視

輸入框鍵入 chrome://net-internals/#http2

通過Chrome的debug工具檢視

protocol為h2

http1.1與http2.0的區別

協議型別傳輸格式多路複用報頭壓縮服務端主動推送請求優先順序
http1.1文字      X       X              X        X
http2.0二進位制幀      √      √              √       √

報頭壓縮

通過h2load 命令訪問

多路複用

http1.1

http1.1 without pipelining: 通過tcp連線上一個請求相應完後,下一個請求才能發出

http1.1 with pipelining: 通過tcp連線,上一個請求發出,下一個請求不需要等待,但是返回是同一順序。

HTTP 1.X的網路載入情況,同一域名,最多支援6個Tcp連線,載入效果如同“正三角形”,看得我強迫症都犯了……

http2.0

在TCP連線上傳輸的是幀,客戶端會將要傳輸的資料拆分為不同的幀,並標記對應的資料流ID,非同步發出,服務端接收到幀集合根據資料流ID拼湊起來即為客戶端傳送來的資料。同理,服務端也是將資料拆分為不同幀返回。
 

每個請求通過tcp連線發出不需要等待其他請求返回, 所有的資料返回沒有順序。

HTTP 2.0的網路載入情況,同一時刻,可以發出30以上的資料幀且無序,感覺很舒服有沒有??

我們不妨以貨物運輸來再現http1.1與http2.0的請求場景。

A地與C地之間相隔一條河流,貨物運輸需要途徑橋樑。假定現有橫跨A,C兩地的6座橋樑(類似Chrome同一域名最大支援6個TCP通道),以其中一座雙向路線橋樑b1為例,

http1.1的過程:

一輛運輸車輛從A地出發,通過橋樑b1,到達C地,然而只有在該車輛從C地取貨並返回後,另一輛車才能出發。如此有序往返...

http2.0的過程:

所有的車輛無序上橋,取貨後返回,根據車輛牌照解除安裝對應取貨物品。

顯而易見,第二種方式,橋樑利用率高,車輛運輸貨物多。

請求優先順序

http1.1 不支援請求優先順序,在統一域名大量請求同時傳送時,瀏覽器支援6個請求,由於沒有優先順序,載入的時候會出現javascript資源阻塞情況。


http2.0, 瀏覽器通過headers和priority攜帶優先順序資訊,伺服器生成優先順序樹,指導資源的分配(記憶體,cpu時間,頻寬)。


優先順序最高:  主要的html
優先順序高:   CSS檔案
優先順序中:   js檔案

優先順序低:   圖片

服務端主動推送

http1.1:在訪問頁面時,瀏覽器識別html頁面上的link連結,然後請求對應的資源,瀏覽器開始識別到請求需要一定時間。


http2.0: 在訪問頁面時,伺服器主動推動資源下載,讓瀏覽器直接請求link資源。

目前nginx1.13.9版本支援push功能

附錄一: nginx安裝配置http2.0

軟體要求

nginx 版本1.9.5以上 nginx 下載頁

安裝過程

//下載nginx/1.10.3 source包
tar xvgf nginx-1.10.3.tar.gz
cd nginx-1.10.3
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/usr/local/openssl-1.0.2h --with-http_v2_module

make -j4
make install

配置http2.0

listen   443 ssl http2;

...
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;

    gzip  on;

    server {
        listen       80;
        server_name  172.16.37.66;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

    # HTTPS server
    #
    server {
        listen   443 ssl http2;
        server_name  172.16.37.66;

        ssl_certificate     certs/cert.crt;
        ssl_certificate_key certs/cert.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

}

附錄二:壓測

壓測工具

對於http,https使用apache 的ab
對於http/2使用nghttp2的h2load

壓測http

ab -k -t 180 -c 6 -n 1000000 http://172.16.37.66/index.html

壓測http2.0

h2load -c 6 -T 180 -n 1000000 https://172.16.37.66/index.html

附錄三:http協議

定義

Hyper Text Transfer Protocol(超文字傳輸協議)的縮寫,是用於從全球資訊網(WWW:World Wide Web )伺服器傳輸超文字到本地瀏覽器的傳送協議

組成

請求行+請求頭+請求正文+返回頭部+返回正文

請求行 

method Request-URI  Http Version

GET /index.html HTTP/1.1

請求頭部

Host: 172.16.37.66
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
If-None-Match: "5aae859e-34b"
If-Modified-Since: Sun, 18 Mar 2018 15:28:30 GMT

請求正文

請求是form表單資料或application/json 格式資料

返回頭部

Server: nginx/1.10.3
Date: Wed, 21 Mar 2018 21:26:19 GMT
Last-Modified: Sun, 18 Mar 2018 15:28:30 GMT
Connection: keep-alive
ETag: "5aae859e-34b"
Access-Control-Allow-Origin: *

返回正文

服務端返回的結果

TCP握手

SYN---->SYN-ACK---->ACK

附錄四: https協議

定義

https是一個在網路上改寫的超文字安全通訊傳輸協議。
在原有的TCP三次握手基礎上,還有一次握手服務端下發ssl證書(所有者,域名公鑰,數字簽名,證書時間等),客戶端驗證證書。

證書

自簽名證書或CA頒發

加密

對稱加密和非對稱加密

附錄五:SPDY與ALPN

SPDY :是speedy的縮寫,由Google開發實現,現已被棄用,它的目的是減少頁面載入延遲,提高網站安全,主要是通過壓縮,多路複用,優先順序減少延遲。
 

ALPN:Application-Layer Protocol Negotiation, 它允許應用層商議在一個安全的連線上那種協議執行,為了避免循迴繞行。

在與http2.0一起使用時,可以提高頁面壓縮率,減少網路延遲。