[TOC]

## 二進制分幀
**最重要的改變,下面的優勢都是根據這個衍生出來**
HTTP 1.x的解析是基于文本。基于文本洗衣的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合,基于這種考慮HTTP2.0的協議解析決定采用二進制分幀格式,實現方便且健壯。

所以HTTP/2引入了三個新的概念
> 1、數據流:基于TCP連接之上的邏輯雙向字節流,對應一個請求及響應。客戶端每發起一個請求就建立一個數據量就,后續該請求及其響應的所有數據都通過該數據流傳輸。
> 2、消息:一個請求或者響應對應的一系列數據幀
> 3、幀”:HTTP/2的最小數據切片單位,每個幀包含幀首部,至少也會標示出當前幀所屬的流。
上述概念之間的邏輯關系:
> 1、所有通信都在一個TCP連接上完成,此連接可以承載任意數量的雙向數據流。
> 2、每個數據流都有一個唯一的標識符和可選的優先級信息,用于承載雙向消息。
> 3、每條消息都是一條邏輯HTTP消息(例如請求或者響應),包含一個或多個幀。
> 4、幀是最小的通信單位,承載著特定類型的數據,例如HTTP標頭、消息負載等等。來自不同數據流的幀可以交錯發送,然后再根據每個幀頭的數據流標識符重新組裝。
> 5、每個HTTP消息分分解為多個獨立的幀后可以交錯發送,從而在宏觀上實現了多個請求或者響應并行傳輸的效果。這類似于多進程環境下的時間分片機制。
所有HTTP 2.0通信都在一個連接上完成,這個連接可以承載任意數量的雙向數據流。每個數據流以消息的形式發送。而消息由一或多個幀組成,而這些幀可以亂序發送,然后再根據每個幀首部流標識符重新組裝。
## 首部壓縮
**第一次需要傳完整的請求頭部,后面只要穿與第一次不一樣的頭部消息就ok**
對于相同的數據,不再重新通過每次請求和響應發送。每個新的首部鍵值對要么追加到當前表的末尾,要么替換表中之前的值。**首部表在HTTP2.0的鏈接存續期內始終存在**,由客戶端和服務端共同漸進的更新。

## 多路復用
**多個http可以在一個tcp連接中同時進行**
1. 可以并行交錯的發送請求和響應,這些請求和響應之間互不影響
2. 只使用一個鏈接即可并行發送多個請求和響應
3. 消除不必要的延遲,從而減少頁面加載的時間
4. 不必再為繞過HTTP1.x限制而多做很多工作
## 請求優先級
//**可以控制優先響應哪些請求,比如一個網頁,網頁布局是最重要的,而圖片資源不太重要,可以優先就診網頁布局**
把HTTP消息分為很多獨立幀之后,就可以通過優化這些幀的交錯和傳輸順序進一步優化性能。
### 什么是請求優先級
每個流都可以帶有一個31bit的優先值:0表示最高優先級;2的31次方-1表示最低優先級。
### 請求優先級如何工作
客戶端明確指定優先級,服務端可以根據這個優先級作為交互數據的依據,比如客戶端優先設置為.css>.js>.jpg。服務端按此順序返回結果更加有利于高效利用底層連接,提高用戶體驗。然而,在使用請求優先級時應注意服務端是否支持請求優先級,是否會引起隊首阻塞問題,比如高優先級的慢響應請求會阻塞其他資源的交互。
## 服務器推送
HTTP2.0新增的一個強大的新功能,就是服務器可以對一個客戶端請求發送多個響應。服務器向客戶端推送資源無需客戶端明確的請求。
### 什么是服務器推送(HTTP2.0中)
服務端根據客戶端的請求,提前返回多個響應,推送額外的資源給客戶端。如下圖,客戶端請求stream 1(/page.html)。服務端在返回stream 1的消息的同時推送了stream 2(/script.js)和stream 4(/style.css)

### 服務器推送如何工作
* PUSH\_PROMISE幀是服務端向客戶端有意推送資源的信號。
* PUSH\_PROMISE幀中只包含預推送資源的首部。如果客戶端對PUSH\_PROMISE幀沒有意見,服務端在PUSH\_PROMISE幀后發送響應的DATA幀。如果客戶端已經緩存了該資源,不需要推送,可以拒絕PUSH\_PROMISE幀。
* PUSH-PROMISE必須遵循請求-響應原則,**只能借著對請求的響應推送資源**。
* **PUSH\_PROMISE幀必須在返回響應之前發送,**以免客戶端出現競態條件(競態條件是指在多線程的情況下不同的執行順序會導致計算機執行出不同的結果正確性不同)
* HTTP2.0連接后,客戶端與服務端交換SETTINGS幀,借此限定雙向并發的最大數量。因此,客戶端可以限定推送流的數量,或者通過把這個只設置為0來完全禁止服務器推送。
* 所有推送的資源都必須遵守同源策略。換句話說,服務器不能隨便將第三方資源推送給客戶端,而必須是經過雙方的確認才行。
### 服務器推送對性能優化工作的貢獻
服務端推送是一種在客戶端請求之前發送數據的機制。在HTTP2.0中,服務器可以對一個客戶端的請求發送多個響應。如果一個請求是由你的主頁發送的,服務器可能會響應主頁內容、logo以及樣式表,因為他知道客戶端會用到這些東西。這樣不但減輕了數據傳送冗余步驟,也加快了頁面響應的速度,提高了用戶體驗。
## 參考資料
[http2.0](https://www.jianshu.com/p/1ad439279974)
[HTTP----HTTP2.0新特性](https://juejin.im/post/5a4dfb2ef265da43305ee2d0)
- Android
- 四大組件
- Activity
- Fragment
- Service
- 序列化
- Handler
- Hander介紹
- MessageQueue詳細
- 啟動流程
- 系統啟動流程
- 應用啟動流程
- Activity啟動流程
- View
- view繪制
- view事件傳遞
- choreographer
- LayoutInflater
- UI渲染概念
- Binder
- Binder原理
- Binder最大數據
- Binder小結
- Android組件
- ListView原理
- RecyclerView原理
- SharePreferences
- AsyncTask
- Sqlite
- SQLCipher加密
- 遷移與修復
- Sqlite內核
- Sqlite優化v2
- sqlite索引
- sqlite之wal
- sqlite之鎖機制
- 網絡
- 基礎
- TCP
- HTTP
- HTTP1.1
- HTTP2.0
- HTTPS
- HTTP3.0
- HTTP進化圖
- HTTP小結
- 實踐
- 網絡優化
- Json
- ProtoBuffer
- 斷點續傳
- 性能
- 卡頓
- 卡頓監控
- ANR
- ANR監控
- 內存
- 內存問題與優化
- 圖片內存優化
- 線下內存監控
- 線上內存監控
- 啟動優化
- 死鎖監控
- 崩潰監控
- 包體積優化
- UI渲染優化
- UI常規優化
- I/O監控
- 電量監控
- 第三方框架
- 網絡框架
- Volley
- Okhttp
- 網絡框架n問
- OkHttp原理N問
- 設計模式
- EventBus
- Rxjava
- 圖片
- ImageWoker
- Gilde的優化
- APT
- 依賴注入
- APT
- ARouter
- ButterKnife
- MMKV
- Jetpack
- 協程
- MVI
- Startup
- DataBinder
- 黑科技
- hook
- 運行期Java-hook技術
- 編譯期hook
- ASM
- Transform增量編譯
- 運行期Native-hook技術
- 熱修復
- 插件化
- AAB
- Shadow
- 虛擬機
- 其他
- UI自動化
- JavaParser
- Android Line
- 編譯
- 疑難雜癥
- Android11滑動異常
- 方案
- 工業化
- 模塊化
- 隱私合規
- 動態化
- 項目管理
- 業務啟動優化
- 業務架構設計
- 性能優化case
- 性能優化-排查思路
- 性能優化-現有方案
- 登錄
- 搜索
- C++
- NDK入門
- 跨平臺
- H5
- Flutter
- Flutter 性能優化
- 數據跨平臺