前端與HTTP

本文整理在,個人github 上。歡迎Star。css

各版本的http

發展

在HTTP創建之初,主要是爲了傳輸超文本標記語言(HTML)文檔。隨着時代的發展,也進行了若干次演進。下圖是各個版本發佈的時間軸。
html

目前爲止,使用最爲普遍的是http1.1http1.0應該比較少了,最新的是http2
這篇博文也主要,圍繞着1.0、1.一、2.0三個版本進行介紹。前端

http/1.0

http1.0不會複用tcp連接,每次請求都會打開、斷開一條連接。
若是您看過我前陣子整理的關於TCP的博文,您就會知道,TCP是有延遲響應機制的,每次請求並不會立刻返回。這算是http1.0性能很差的一個緣由吧。git

http/1.1

http/1.1當前普及程度最高的http版本。
到了http/1.1版本,tcp連接能夠持久保持了(也就說,一段時間內,一個tcp連接會等到同一個域名下的全部資源加載完後再斷開。)github

在保持tcp連接的基礎上,引入了http管道的機制,差點實現了多路複用算法

http/1.1 without pipelining(不使用管道)

經過一條tcp連接請求資源,只有在上一個請求完成後,才能發出下一個請求。也就是上圖描述的情形。瀏覽器

http/1.1 with pipelining(使用管道)

客戶端不會等待響應,直接併發N個請求。可是,http/1.x有嚴格的串行返回響應機制。通俗的講就是:請求時,不用等上一個完成;但響應時,必須嚴格按照順序返回
經過開發者工具,你就能夠觀察到這一點。緩存

基於以上描述,使用「 HTTP 管道」技術時,萬一第一個響應時間很長,那麼後面的響應處理完了也沒法發送,只能被緩存起來,佔用服務器內存,這就是傳說中的「隊首阻塞(head of line blocking)」。
這也是http/1.x下,多數網絡體驗很差的緣由。性能優化

http/2.0

在介紹http/2.0以前,咱們來先看一份Akamai公司提供的一個官方演示服務器

這裏用了361(19*19)張圖片,分別使用http/1.1,http/2.0兩種版本的協議進行對比。能夠直觀的感覺到,http/2.0比http/1.0快出5倍左右的速度。

考慮到您可能須要分別用開發者工具仔細查看下兩個版本,我已經幫你找好了兩個版本對應的連接。(不客氣)


那http/2.0究竟引入了哪些機制、特性才達到目前的加速效果呢?簡答的說能夠歸納成。

  • 二進制分幀層
  • 多路複用
  • 首部壓縮
  • 服務器推送(server Push)

二進制分幀層與多路複用

引入了二進制分幀層,就再也不是文本傳輸了,而是數據幀(二進制)。
注意:HTTP本來的語義,方法、動詞、首部都不受影響。僅僅是傳輸期間的數據格式變化了。

http/2規定了10種不一樣的幀。
如上圖,分針層會把 開始行首部行分割到HEADERS幀正文實體分割到DATA幀。


TCP 鏈接在客戶端和服務器間創建了一條運輸的通道,能夠雙向通行,當一端要向另外一端發送消息時,會先把這個消息拆分紅幾部分(幀),而後經過發起一個流對這些幀進行發送,最後在另外一端將同一個流的幀從新組合。

這裏涉及瞭如下概念。

流:已創建的鏈接上的雙向字節流
消息:與邏輯消息對應的完整的一系列數據幀
幀:HTTP/2 通訊的最小單位,每一個幀包含幀首部

其中幀對數據進行順序標識,這樣瀏覽器收到數據以後,就能夠按照序列對數據進行合併,而不會出現合併後數據錯亂的狀況。一樣是由於有了序列,服務器就能夠並行的傳輸數據,這就是流所作的事情。

HTTP/2對同一域名下全部請求都是基於流,也就是說同一域名無論訪問多少文件,也只創建一路鏈接。一樣Apache的最大鏈接數爲300,由於有了這個新特性,最大的併發就能夠提高到300,比原來提高了6倍!

首部壓縮

在服務器和客戶端各維護一個「首部表」,表中用索引表明首部名,或者首部鍵 - 值對,上一次發送兩端都會記住已發送過哪些首部,下一次發送只須要傳輸差別的數據,相同的數據直接用索引表示便可。

首部壓縮,能夠解決http頭臃腫的問題。

服務器推送(server Push)

服務器能夠對一個客戶端請求發送多個響應。也就是說,除了對最初請求的響應外,服務器還能夠額外向客戶端推送資源。

這裏就涉及到了另外一個幀類型:PUSH_PROMISE幀。
舉個栗子,當客戶端請求index.html時,服務器會同時推送style.css,index.js對應的PUSH_PROMISE幀。客戶端能夠直接緩存起來。

基於http/2對前端性能優化的思考

我的以爲前端的性能優化,應該主要從兩個方面。加載速度流暢運行
原引,在網上看到的一段話:

網頁不只應該被快速加載,同時還應該流暢運行,好比快速響應的交互,如絲般順滑的動畫等。


http/1.x的優化方案

固然,今天的主題是討論網路協議,那咱們只談加載速度。
基於http1.x的相關特性,可愛的前端們提出了不少頗具成效的優化方案。(精靈圖,多域名加載等等)其中,比較著名的雅虎軍規,不少人應道都知道,這裏有一張整理好的圖。

http/2的變革

在http/2的基礎上,不少http/1.x要優化的問題,都不存在了。問題都不存在了,問題的優化方案也就不存在了。
這裏插一句,我始終堅信的一個觀點是:沒有任何優化手段是不須要付出代價的。是藥三分毒,無非是取捨罷了。

1.合併css、js與精靈圖

在http/1.x時代,http並無最大程度上利用好tcp連接。雖然http/1.1裏有了http管道,但其也帶來了隊首阻塞等問題,同時也要受隊列大小的限制。因此咱們要經過合併文件的方式減小http連接數量。
不錯,減小http請求數量的確能起到優化的做用,但與此同時,也有不少弊端:

  1. 全部文件合成一個大文件,那無論哪一個模塊發生變動,都要總體更新,用戶都要從新下載,沒法繼續使用緩存。
  2. 帶來了額外的維護成本。印象比較深的是維護精靈圖,稍微改一點,就得從新弄。

以上,就是」合併css方案"、「合併js方案」、「精靈圖方案」的優點與弊端。

  • 在http/1.x基礎上,明顯優點>弊端,因此咱們使用這些方案。
  • 但http/2,它對tcp連接的利用程度已經有了飛躍性的提高。此時這些方案是否優點>弊端,就值得商榷了。筆者以爲應該正好反過來。優點<弊端

2.分域名

在http/1.x基礎上,分域名有兩個好處。

  • 爲了繞過瀏覽器對同一域名的最大管道限制。能夠同時請求更多內容。
  • 同一域名下的請求報文,會匹配的站點的所有cookie,增大請求報文長度。而不少資源,好比圖片、css是不須要cookie的。

在http/2上,對於這些問題

  • 本來就支持多路複用,不必分
  • 首部壓縮機制,首部行大點,也就傳一個。

3.接口合併

若是頁面須要多種數據,咱們會盡可能將數據彙總到一個接口,以減小http請求數量。
這種作法,幾乎違背了各類程序設計規範,好比「單一職責原則」等等,接口很難複用,維護成本高。
這種方案在http/2下,明顯弊端>優點了。

參考文獻

插一句《RFC7540》是官方對http2.0規格的描述,比較權威。

相關文章
相關標籤/搜索