創建連接
TCP三次握手:包括客戶端想服務端發起一個SYN包,接著服務端返回對應SYN的ACK響應以及新的SYN包,然后客戶端返回對應的ACK.
如果客戶端發起HTTPS連接,它還需要進行傳輸層安全協議(TLS)協商;TLS用來取代安全套接層.
HTTP1的問題
1.隊頭阻塞:允許一次發送一組請求,但是只能按照發送順序一次接受響應.現代瀏覽器一般針對單個域名開啟6個連接.
2.使用擁塞接口:在接受方確認數據包之前,發送方可以發出的TCP包的數量.慢啟動:每次響應成功則加倍發送的數據包,失敗則減半發送的數據包.
3.消息首部臃腫
4.受限的優先級設置
5.第三方資源
Web性能的最佳實踐(HTTP1)
1.DNS查詢優化
a.限制不同域名的數量
b.保證低限度的解析延遲
c.在主體頁面HTML或響應中利用DNS預取指定的域名如:
<link rel="dns-prefetch" href="//ajax.googleapis.com>
2.優化TCP連接
a.利用preconnect指令,連接在使用之前就已經建立好.如:
<link rel="preconnect" href="//fonts.example.com" crossorigin>
b.借助CDN,在距離請求用戶很近的邊緣端點上,請求就可以獲得響應.
3.避免重定向
4.客戶端緩存
瀏覽器支持
任何不支持HTTP2的客戶端都將簡單的退回到HTTP1
HTTP1的優化,對于HTTP2的建議:
1.資源合并:在HTTP2下并非必要.
2.去除域名拆分:域名拆分是為了利用瀏覽器對每個域名開啟多個連接的能力,以便實現資源的并行下載,繞過http1的串行化下載的限制.而http2的設計意圖是采用多路復用,充分利用單個socket連接,而拆分域名會違背這種意圖.
3.去除禁用cookie:應該避免為這些資源單位設立域名,因為http2采用了HPACK算法首部壓縮,會顯著減少巨型cookie(尤其是當它們在先后請求之間保持不變)的字節數.與此同時,禁用cookie的域名需要額外的主機名稱,這意味著將開啟更多的連接,與http2意圖違背.
HTTP2幀類型
0x0 DATA:傳輸流的核心內容
0x1 HEADERS:包含http首部,和可選的優先級參數
0x2 PRIORITY:指示或更改流的優先級和依賴
0x3 RST_STREAM:允許一端停止流
0x4 SETTINGS:協商連接級參數
0x5 PUSH_PROMISE:提示客戶端,服務器要推送些東西
0x6 PING:測試連接可用性和往返延時(RTT)
0x7 GOAWAY:告訴另一端,當前端已結束
0x8 WINDOW_UPDATE:協商一端將要接收多少字節
0x9 CONTINUATION:用以擴展HEADER數據塊
http2優先級
1.依賴關系:為客戶端提供了一種能力,通過指明某些對象對另一些對象有依賴,告知服務器這些對象應該優先傳輸.
2.權重:讓客戶端告訴服務器如何確定具有共同依關系的對象的優先級.
服務器推送局限
https2中,服務器會在第一次請求中就向客戶端推送信息,這樣雖然可以節省時間,不過也可能推送了客戶端不需要的信息.客戶端確實可以發送RST_STREAM幀來拒絕服務器的PUSH_PROMISE幀,但是RST_STREAM并不會即可到達,所以服務器還是會發送一些多余的信息.
首部壓縮HPACK,為什么不是GZIP?
因為GZIP也有泄露加密信息的風險.比如GRIME攻擊,攻擊者在請求中添加數據,觀察壓縮加密后的數據量是否會小于預期.如果變小了,攻擊者就知道注入的文本和請求中的其他內容(比如私有的會話cookie)有重復.在很短的時間內,經過加密的數據內容就可以全部搞清楚.
http2比http1多做的工作:
1.窗口大小調節
2.依賴樹構建
3.維持首部信息的靜態/動態表
4.壓縮/解壓縮首部
5.優先級調整(http2允許客戶端多次調整單一請求的優先級)
6.預先推送客戶端尚未請求的數據流