來源:前端擺渡人 發(fā)布時間:2019-05-10 16:33:10 閱讀量:2161
各版本的http
發(fā)展
在HTTP建立之初,主要是為了傳輸超文本標(biāo)記語言(HTML)文檔。隨著時代的發(fā)展,也進(jìn)行了若干次演進(jìn)。下圖是各個版本發(fā)布的時間軸。
目前為止,使用最為廣泛的是http1.1,http1.0應(yīng)該比較少了,最新的是http2。
這篇博文也主要,圍繞著1.0、1.1、2.0三個版本進(jìn)行介紹。
http/1.0
http1.0不會復(fù)用tcp鏈接,每次請求都會打開、斷開一條鏈接。
如果您看過我前陣子整理的關(guān)于TCP的博文,您就會知道,TCP是有延遲響應(yīng)機(jī)制的,每次請求并不會馬上返回。這算是http1.0性能不好的一個原因吧。
http/1.1
http/1.1當(dāng)前普及程度最高的http版本。
到了http/1.1版本,tcp鏈接可以持久保持了(也就說,一段時間內(nèi),一個tcp鏈接會等到同一個域名下的所有資源加載完后再斷開。)
在保持tcp鏈接的基礎(chǔ)上,引入了http管道的機(jī)制,差點實現(xiàn)了多路復(fù)用。
http/1.1 without pipelining(不使用管道)
通過一條tcp鏈接請求資源,只有在上一個請求完成后,才能發(fā)出下一個請求。也就是上圖描述的情形。
http/1.1 with pipelining(使用管道)
客戶端不會等待響應(yīng),直接并發(fā)N個請求。但是,http/1.x有嚴(yán)格的串行返回響應(yīng)機(jī)制。通俗的講就是:請求時,不用等上一個完成;但響應(yīng)時,必須嚴(yán)格按照順序返回。
通過開發(fā)者工具,你就可以觀察到這一點。
基于以上描述,使用“ HTTP 管道”技術(shù)時,萬一第一個響應(yīng)時間很長,那么后面的響應(yīng)處理完了也無法發(fā)送,只能被緩存起來,占用服務(wù)器內(nèi)存,這就是傳說中的“隊首阻塞(head of line blocking)”。
這也是http/1.x下,多數(shù)網(wǎng)絡(luò)體驗不好的原因。
http/2.0
在介紹http/2.0之前,我們來先看一份Akamai公司提供的一個官方演示。
這里用了361(19*19)張圖片,分別使用http/1.1,http/2.0兩種版本的協(xié)議進(jìn)行對比。可以直觀的感受到,http/2.0比http/1.0快出5倍左右的速度。
考慮到您可能需要分別用開發(fā)者工具仔細(xì)查看下兩個版本,我已經(jīng)幫你找好了兩個版本對應(yīng)的鏈接。(不客氣)
http/1.1的演示
http/2.0的演示
那http/2.0究竟引入了哪些機(jī)制、特性才達(dá)到目前的加速效果呢?簡答的說可以概括成。
二進(jìn)制分幀層
多路復(fù)用
首部壓縮
服務(wù)器推送(server Push)
二進(jìn)制分幀層與多路復(fù)用
引入了二進(jìn)制分幀層,就不再是文本傳輸了,而是數(shù)據(jù)幀(二進(jìn)制)。
注意:HTTP原本的語義,方法、動詞、首部都不受影響。僅僅是傳輸期間的數(shù)據(jù)格式變化了。
http/2規(guī)定了10種不同的幀。
如上圖,分針層會把 開始行,首部行分割到HEADERS幀,正文實體分割到DATA幀。
TCP 連接在客戶端和服務(wù)器間建立了一條運(yùn)輸?shù)耐ǖ溃梢噪p向通行,當(dāng)一端要向另一端發(fā)送消息時,會先把這個消息拆分成幾部分(幀),然后通過發(fā)起一個流對這些幀進(jìn)行發(fā)送,最后在另一端將同一個流的幀重新組合。
這里涉及了以下概念。
流:已建立的連接上的雙向字節(jié)流
消息:與邏輯消息對應(yīng)的完整的一系列數(shù)據(jù)幀
幀:HTTP/2 通信的最小單位,每個幀包含幀首部
其中幀對數(shù)據(jù)進(jìn)行順序標(biāo)識,這樣瀏覽器收到數(shù)據(jù)之后,就可以按照序列對數(shù)據(jù)進(jìn)行合并,而不會出現(xiàn)合并后數(shù)據(jù)錯亂的情況。同樣是因為有了序列,服務(wù)器就可以并行的傳輸數(shù)據(jù),這就是流所做的事情。
HTTP/2對同一域名下所有請求都是基于流,也就是說同一域名不管訪問多少文件,也只建立一路連接。同樣Apache的最大連接數(shù)為300,因為有了這個新特性,最大的并發(fā)就可以提升到300,比原來提升了6倍!
首部壓縮
在服務(wù)器和客戶端各維護(hù)一個“首部表”,表中用索引代表首部名,或者首部鍵 - 值對,上一次發(fā)送兩端都會記住已發(fā)送過哪些首部,下一次發(fā)送只需要傳輸差異的數(shù)據(jù),相同的數(shù)據(jù)直接用索引表示即可。
首部壓縮,可以解決http頭臃腫的問題。
服務(wù)器推送(server Push)
服務(wù)器可以對一個客戶端請求發(fā)送多個響應(yīng)。也就是說,除了對最初請求的響應(yīng)外,服務(wù)器還可以額外向客戶端推送資源。
這里就涉及到了另一個幀類型:PUSH_PROMISE幀。
舉個栗子,當(dāng)客戶端請求index.html時,服務(wù)器會同時推送style.css,index.js對應(yīng)的PUSH_PROMISE幀??蛻舳丝梢灾苯泳彺嫫饋怼?/span>
基于http/2對前端性能優(yōu)化的思考
個人覺得前端的性能優(yōu)化,應(yīng)該主要從兩個方面。加載速度和流暢運(yùn)行。
原引,在網(wǎng)上看到的一段話:
網(wǎng)頁不僅應(yīng)該被快速加載,同時還應(yīng)該流暢運(yùn)行,比如快速響應(yīng)的交互,如絲般順滑的動畫等。
http/1.x的優(yōu)化方案
當(dāng)然,今天的主題是討論網(wǎng)路協(xié)議,那我們只談加載速度。
基于http1.x的相關(guān)特性,可愛的前端們提出了很多頗具成效的優(yōu)化方案。(精靈圖,多域名加載等等)其中,比較著名的雅虎軍規(guī),很多人應(yīng)道都知道,這里有一張整理好的圖。
http/2的變革
在http/2的基礎(chǔ)上,很多http/1.x要優(yōu)化的問題,都不存在了。問題都不存在了,問題的優(yōu)化方案也就不存在了。
這里插一句,我始終堅信的一個觀點是:沒有任何優(yōu)化手段是不需要付出代價的。是藥三分毒,無非是取舍罷了。
1.合并css、js與精靈圖
在http/1.x時代,http并沒有最大程度上利用好tcp鏈接。雖然http/1.1里有了http管道,但其也帶來了隊首阻塞等問題,同時也要受隊列大小的限制。所以我們要通過合并文件的方式減少http鏈接數(shù)量。
不錯,減少http請求數(shù)量的確能起到優(yōu)化的作用,但與此同時,也有很多弊端:
所有文件合成一個大文件,那不管哪個模塊發(fā)生變更,都要整體更新,用戶都要重新下載,無法繼續(xù)使用緩存。
帶來了額外的維護(hù)成本。印象比較深的是維護(hù)精靈圖,稍微改一點,就得重新弄。
以上,就是”合并css方案"、“合并js方案”、“精靈圖方案”的優(yōu)勢與弊端。
在http/1.x基礎(chǔ)上,明顯優(yōu)勢>弊端,所以我們使用這些方案。
但http/2,它對tcp鏈接的利用程度已經(jīng)有了飛躍性的提升。此時這些方案是否優(yōu)勢>弊端,就值得商榷了。筆者覺得應(yīng)該正好反過來。優(yōu)勢<弊端。
2.分域名
在http/1.x基礎(chǔ)上,分域名有兩個好處。
為了繞過瀏覽器對同一域名的最大管道限制??梢酝瑫r請求更多內(nèi)容。
同一域名下的請求報文,會匹配的站點的全部cookie,增大請求報文長度。而很多資源,比如圖片、css是不需要cookie的。
在http/2上,對于這些問題
原本就支持多路復(fù)用,沒必要分
有首部壓縮機(jī)制,首部行大點,也就傳一個。
3.接口合并
如果頁面需要多種數(shù)據(jù),我們會盡量將數(shù)據(jù)匯總到一個接口,以減少http請求數(shù)量。
這種做法,幾乎違背了各種程序設(shè)計規(guī)范,比如“單一職責(zé)原則”等等,接口很難復(fù)用,維護(hù)成本高。
這種方案在http/2下,明顯弊端>優(yōu)勢了。
最后,給大家推薦一個前端學(xué)習(xí)進(jìn)階內(nèi)推交流群685910553(前端資料分享),不管你在地球哪個方位,
不管你參加工作幾年都?xì)g迎你的入駐!(群內(nèi)會定期免費(fèi)提供一些群主收藏的免費(fèi)學(xué)習(xí)書籍資料以及整理好的面試題和答案文檔?。?/span>
如果您對這個文章有任何異議,那么請在文章評論處寫上你的評論。
如果您覺得這個文章有意思,那么請分享并轉(zhuǎn)發(fā),或者也可以關(guān)注一下表示您對我們文章的認(rèn)可與鼓勵。
愿大家都能在編程這條路,越走越遠(yuǎn)。