再談ServerPush,Push or Not Push

html

互聯網工程任務組(IETF)於2014年12月將HTTP/2標準提議遞交至互聯網工程指導組(IESG)進行討論,於2015年2月17日被批准,於2015年5月以RFC 7540正式發表。-維基百科前端

回過頭來看,距離HTTP/2標準發佈已通過去了五年。這五年,前端發生了技術翻天覆地的變化: IE瀏覽器逐漸式微,MVVM框架的興起和繁盛,WebAssembly的萌芽。nginx

這五年,HTTP/2 的普及和推開也無比迅速。面試

根據最新的數據,HTTP/2的瀏覽器支持程度已經來到了使人振奮的96%瀏覽器

再看HTTP/2

緩存

HTTP/2 相較於 HTTP1.x 有哪些改進?性能優化

上面這個問題已經成爲前端面試的必考題。二進制分幀、多路複用、頭部壓縮、服務端推送這幾個關鍵詞你們已經熟的不能再熟。服務器

HTTP/2帶來了顯而易見的性能提高,又有着如此高的瀏覽器支持度,和極低的使用成本,不用簡直天理難容。目前中國各大網站都使用 HTTP/2 提高網站加載性能和用戶體驗。markdown

但咱們再看HTTP/2的幾大特性,二進制分幀、多路複用、頭部壓縮這幾個自沒必要多說,只要開啓了HTTP/2,就可使用這些特性,給網站帶來性能優化。那麼,Server Push去哪了?cookie

咱們找遍了中國各大門戶網站,都沒有看到Server Push的身影。問題出在哪?

Why not Push

簡單回顧一下Server Push的概念:

服務器推送(server push)指的是,尚未收到瀏覽器的請求,服務器就把各類資源推送給瀏覽器。

上面這張圖片看起來很美妙,當使用Server Push時,CSS和HTML一塊兒返回,從而減小了一個RTT的時間

讓咱們試着解決第一個問題:

爲何Server Push沒有獲得普遍的應用?

須要配置?

ServerPush是HTTP/2 協議裏面惟一一個須要開發者本身配置的功能,其餘功能都是服務器和瀏覽器自動實現,不須要開發者關心。

是不是由於須要配置,才使得Server Push難以推廣?

Nginx和Apache等網關早已支持Server Push功能,只須要簡單配置後,在HTML的Response的Header中帶上:

Link: ; rel=preload; as=style
複製代碼

即可以輕鬆實現ServerPush😁。

一兩句簡單的配置,沒法阻擋開發者對於極致性能的追求,那麼還有其餘緣由嗎?

CDN帶來的痛

上圖中Without Push和With Push對比只是最簡單的場景,基本不可用於實際的生產中。

在實際的場景中,爲了提高加載速度和減輕服務器的負載,通常會使用CDN進行資源的加載。因而乎,咱們的加載時序圖就會變成這樣:

彷佛也不復雜,只要咱們的CDN支持Server Push,同Nginx同樣,帶上相應的Header,即可以實現ServerPush。

繼續研究一下 ServerPush CDN的支持狀況:在2016年4月28日,國外最大的提供商cloudflare宣佈支持ServerPush。

而反觀國內,各大CDN廠商彷彿對ServerPush這一HTTP/2特性熟視無睹。騰訊雲、阿里雲兩大雲廠商CDN產品文檔都沒有相關說明。只有一家小廠」又拍雲「在2018年出過一篇PR文章:

讓互聯網更快,Server Push 特性及開啓方式詳解

通過重重查找,咱們發現了一些端倪:

騰訊雲+社區的一篇文章在開頭指出,騰訊雲已經支持ServerPush,而且進行了相關的性能測試。

萬事俱備,只欠東風。然而,歷史包袱是沉重的。靜態資源和HTML不一樣域讓CDN ServerPush成爲了夢。

以常見的一個源站與CDN不一樣域的頁面爲例,HTML做爲Web請求的入口,爲了不CDN Cache致使用戶沒法即時更新應用,通常選擇不走CDN,直接解析到Origin的Nginx上。

而JS、CSS、IMG等靜態資源,則是走CDN的域名。

HTML和CSS不在同一個域下,根本沒法Push

訪問一下國內的各大網站,發現基本上都是用了這種靜態資源與HTML不一樣域的方案,要實現ServerPush,就要推進CDN主域化

CDN主域化是一個複雜、充滿風險的工程,尤爲是在業務高速運轉時進行,無異於高速路上換輪胎。其方案要通過層層設計,本文在此就不作研究。

假設咱們已經實現了CDN主域化,Server Push是否是能夠立刻提高性能呢?

未知不是武器:Push Cache

現階段,Server沒法得知Client是否有Cache

若是Client已經有該資源的Cache,那麼Push的靜態資源會毫無心義地浪費帶寬。雖然瀏覽器能夠經過RST_STREAM阻止Server繼續向Client發送資源,可是一部分資源已經在網絡中進行傳輸。

一些探索

Push CGI

餓了麼的這篇文章:

淺談HTTP/2 Server Push

給咱們帶來的比較好的啓示,文章中提到, 爲了不靜態資源和HTML不一樣域、Push Cache這兩大問題,選擇了不Push靜態資源,而是Push CGI請求。

相較於Preload CGI邏輯,ServerPush CGI請求可以減小1個RTT時間,而且不用考慮Cache的問題,從而穩定地帶來性能上的提高。

Cache Digests(draft)

目前,IETF已經有相關草案在進行討論,使用Cache Digests,請求帶上客戶端的緩存狀況供服務器識別,從而解決ServerPush的Push Cache問題。

103 Early Hints(draft)

目前 103 Early Hints 信息狀態響應碼也一樣處於草案階段,經過簡單的HTTP回包來容許用戶在服務器還在準備響應數據的時候預加載一些資源。

相較於Server Push,它避免了Push Cache的問題,但性能上沒有Server Push極致。

性能數據

理論性能數據

下圖總結了各類方案(Preload、103 Early Hints、Server Push、Server Push + Cache Digests)的性能:

(注:不考慮HTTPS TLS握手的RTT)

能夠看到,Server Push + Cache Digests在性能上擁有很大的優點。但願它能儘快成爲規範。

實測數據

Nginx Team對Server Push在實際場景下首次加載作了一次benchmark,以下所示:

原文:Introducing HTTP/2 Server Push with NGINX 1.13.9

Server Push在這種場景下也能帶來必定性能提高。

When Push?

在什麼狀況下,咱們應該使用Server Push?

RTT過長的狀況

毫無疑問,當Client與Server的過長而帶寬十分充足時,ServerPush節省的一個RTT能帶來很好的優化。

一個新的問題是:RTT多長時,該使用ServerPush?

Google Chrome小組的一篇文章給出了計算公式:

Rules of Thumb for HTTP/2 Push

翻譯以下:

遺憾的是,咱們沒法正常得知用戶的帶寬和RTT時間。

第一訪問的用戶

爲了不Push Cache這一問題,咱們能夠只爲第一次訪問的用戶進行Push。

能夠考慮使用Cookie來鑑別是否爲第一次訪問的用戶,但也須要注意Cookie並不能完整的描述全部靜態資源Cache的狀況,舉個例子:

Client Cookie沒有失效,可是CSS資源的Cache已經失效,此時Server由於Client有Cookie而選擇不進行Push。

固然,也能夠設計更復雜的方案在Cookie中作標記,告訴Server Push的時機。

還好已經有方案來實現:

H2O 服務器提供了一個叫做 cache-aware server push的方案,原理就是將全部緩存過的資源都記錄在 cookie 裏,這樣服務器就知道哪些資源不須要被推送了。

不過,在 cookie 裏記錄全部的資源路徑會佔用不少的空間,所以還須要將路徑壓縮一下。

這裏能夠考慮使用bloom filter來減小cookie數據量,能夠點擊查看這篇文章:

NGINX 支持 HTTP/2 server push 了

Client端渲染的狀況

若是應用使用了SSR,Push靜態資源可能會佔用加載HTML的帶寬,從而增長首屏時間。CSR的場景更適合Server Push。

在網絡空閒時進行PUSH,只PUSH當前頁面

因爲Server Push可能會佔據Client端本就窄小不充裕的帶寬,在某些場景下,可能會起到拔苗助長的效果。

另外一個緣由是Server Push使用冷TCP鏈接,TCP的慢啓動致使加載資源的效率比熱TCP連接更慢

而下一個頁面的資源由Service Worker來主動fetch相較來講要更爲合適。


參考文章

Introducing HTTP/2 Server Push with NGINX 1.13.9

Rules of Thumb for HTTP/2 Push

淺談 HTTP/2 Server Push

讓互聯網更快,Server Push 特性及開啓方式詳解

HTTP/2之服務器推送(Server Push)最佳實踐

To push, or not to push?! - The future of HTTP/2 server push - Patrick Hamann - JSConf EU 2018

相關文章
相關標籤/搜索