日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

引入任何一種新技術都是有原因和目的的。比如 HTTP keep-alive 允許客戶端和服務端用同一個 TCP 連接發送/接收多個請求/響應,減少了昂貴的 TCP 建立連接和斷開連接的過程;HTTP pipelining 允許客戶端在收到響應之前繼續發送冪等方法(GET 和 HEAD)的請求,提升在高延遲連接下頁面的加載速度;HTTP/2 更是定義了幀(frame)和流(stream),真正地復用了 TCP 連接,從而解決了 pipelining 不能解決的問題(例如「快」的響應被「慢」的響應阻塞的問題)。

Server push 的意義很簡單,說白了就是為了提前推送響應。這里面包含兩個問題——推什么和怎么推。

推什么?

使用 HTTP/1.x 協議時,由于連接不能完全被復用,許多站點為了減少連接數和請求數,會把樣式表和腳本內聯到 html 中。如果不考慮緩存,可以認為這是提前推送了樣式表和腳本的響應。許多介紹 server push 的文章也以推送這些靜態資源為例。

簡單聊聊HTTP2.0中的Server Push

 

上圖是我畫的一張示意圖。可以看到,使用 server push 后,兩個靜態資源文件隨著 HTML 一同被推了回來。主要省去了兩部分時間:一部分是接收和解析 HTML 的時間(不一定是接收和解析完整 HTML 的時間,瀏覽器很可能一發現引用了靜態資源文件,就發起請求);另一部分是請求靜態資源文件的時間。

但是,我個人認為現階段用 server push 推送靜態資源并不是一件有意義的事情,原因在于:

  1. HTML 文件通常不大,而且樣式表一般很靠前,瀏覽器發現這類靜態資源的時間幾乎可以忽略不計;
  2. HTTP/2 已經能夠復用 TCP 連接了,請求不再像以前那樣昂貴,請求的實際數據很小,發送請求的時間也幾乎可以忽略不計;
  3. 國內的 CDN 普遍不支持 server push,這意味著,如果要推送靜態資源,就必須耗費自己服務器的帶寬,同時也享受不到 CDN 的各種好處了;
  4. 靜態資源通常會被緩存很長時間,提前推送的話,在大多數情況下反而會浪費流量。

因此,我們推送的資源并不是靜態資源,而是 API

  1. 相比較靜態資源文件,瀏覽器更難發現 API 請求,必須等到接收和解析完 JS 文件,執行到相關語句,瀏覽器才會發送請求;
  2. API 一般不緩存,即便緩存,緩存的時間也比靜態資源短得多。

當然,server push 對要推送的資源是有限制的:其請求必須是可緩存的、安全的,而且不能帶有請求體。換句話說,server push 可以推 GET 和 HEAD 請求的響應。

怎么推?

Server push 的原理很簡單,本質上就是先替你請求再告訴你。

假設服務端接收到客戶端對 HTML 文件的請求,決定用 server push 推送一個樣式表文件。那么,服務端會構造一個請求,包括請求方法和請求頭,填充到一個 PUSH_PROMISE 幀里發送給客戶端,來告知客戶端它已經代勞發了這個請求??蛻舳丝梢愿鶕?PUSH_PROMISE 幀里提供的 Promised Stream Id 來讀推過去的響應。

簡單聊聊HTTP2.0中的Server Push

 

當客戶端收到這個 PUSH_PROMISE 幀的時候,它就知道服務端將要推送一個樣式表文件回來。如果此時客戶端需要請求這個樣式表文件,即便服務端還沒推完,它也不會往服務端發送對樣式表文件的請求。

這里需要注意的是避免競爭。在上面的例子中,必須先發送 PUSH_PROMISE,再發送 HTML 的內容。這是因為 HTML 中存在對樣式表文件的引用,一旦客戶端發現了這個引用卻還沒收到 PUSH_PROMISE,它就會發起請求。這會引起 PUSH_PROMISE 和對樣式表文件的請求之間的競爭,從而 server push 有一定的幾率失敗。

另一種競爭是不可避免的。如果客戶端認為它不需要某個即將被推過來的資源(比如這個資源還在緩存的有效期內),那么它會 reset 掉相應的流。但是即便如此,服務端在收到 RST_STREAM 幀的時候,很有可能已經推了一部分數據了。這種服務端開始推送數據和 RST_STREAM 幀之間的競爭是難以避免的(這是 feature 而不是 BUG)。

Demo

為了測試 server push 的效果,我們拿餓了么 PC的餐廳列表頁面做了個 demo。

在開啟 server push 之前,timeline 如下:

簡單聊聊HTTP2.0中的Server Push

 

使用 server push 推送頁面請求的 API 之后,timeline 變成了這樣:

簡單聊聊HTTP2.0中的Server Push

 

一方面,timeline 總時間變短了。兩者 Loading、Scripting、Rendering 和 Painting 的時間比較接近,但是主動推送 API 后,Idle 從超過 280ms 縮短至 50ms 左右,商家圖片的開始加載時間也大幅提前了(視覺上就是餐廳列表瞬間出來了)。

另一方面,頁面的 DOMContentLoaded 和 Load 時間有所提升(在 Network 面板中,沒有截圖)。這是意料之中的,客戶端在請求 HTML 之后需要同時接收 HTML 和 API 的響應。這并不影響頁面與資源的總體加載時間變短。

Demo 終究只是 demo。推送 API 比推送靜態資源復雜許多,具體在于大多數 API 是需要帶參數的。即便只推送 GET 方法的 API,也需要帶上 query string 和 header 里(包括 Cookie)的參數。

如果你好奇怎么驗證 server push 有沒有生效,請打開 Network 面板,你會看到一排漂亮的「Push」:

簡單聊聊HTTP2.0中的Server Push

 

寫在最后

Server push 還有許多有趣的地方,限于篇幅不能一一贅述。

最后我補充兩點:

  1. 調試 server push 的正確姿勢是用 Chrome 打開 chrome://net-internals/#http2,發了什么幀,收到什么幀,一目了然;
  2. 只要證書匹配,server push 也可以推送其他 host 的資源。

分享到:
標簽:Server Push
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定