您當前的位置:首頁 > 歷史

bigPipe 原理分析

作者:由 RealRaul7 發表于 歷史時間:2019-09-13

一、什麼是bigPipe?

bigPipe是由facebook提出來的一種動態網頁載入技術。它將網頁分解成稱為pagelets的小塊,然後分塊傳輸到瀏覽器端,進行渲染。它可以有效地提升首屏渲染時間。

為了說清楚什麼是bigPipe,我先需要介紹下目前的常規渲染方式,以及可以進行最佳化的方向。

二、網頁首屏載入方案

注:首屏載入方案指的是在服務端就已經吐出頁面的方案,也就是說有SSR的方案,那些純客戶端渲染的方案不做比較,因為它們沒有首屏要求。

現有的網頁首屏載入方案一般會經過以下階段:

傳送http請求到服務端

服務端接收並分析請求

服務端根據請求從儲存層獲取相關資料,這裡可能會比較耗時,比如如果首頁涉及多個模組(廣告位、推薦、內容列表、使用者資訊、好友列表等)

服務端準備好所有內容,拼接成完整的html文件

傳送回客戶端

客戶端接收完整的html文件

構建dom、cssom, 生成render tree,渲染出指定頁面

如下圖所示:

bigPipe 原理分析

以上載入方案的缺點是,當2、3、4、5 步在服務端進行的時候,瀏覽器只能是傻傻地等待,做不了任何事情!

而且第3步並行拉取業務資料在某些場景下(模組多,業務場景複雜),是會佔用比較多的時間的。而且只要其中某個模組的資料如果拉取較慢,會拖慢整個首屏的顯示。

更糟糕的情況下,某些模組資料相互依賴,導致需要序列拉取資料,那造成的瀏覽器的等待則會更久。

三、最佳化方案

以上方案在一些服務端渲染頁面中相當常見,不足之處也很明顯。

而bigPipe就是針對第3、4步進行最佳化,讓服務端在準備好某個模組的資料後,立馬返回給客戶端顯示,而不必要等待完整的資料和html生成,再發送給客戶端。

客戶端在接收到某一部分內容後,就可以開始渲染,顯示執行(這裡可以動態請求需要的css,js 等等)。

如下圖,客戶端拉取業務資料和客戶端渲染頁面可以並行。如果某一部分比如廣告資訊拉取超時,也並不影響其他部分率先渲染顯示。

bigPipe 原理分析

這樣,一個完整的頁面就可以拆成多個部分,分塊渲染,而無需等到拿到完整的頁面返回,再渲染。要知道, 如果要等到完整頁面返回,在這之前,瀏覽器只能是一片空白!

四、關鍵技術和原理

想要實現以上最佳化方案,可以利用現成的技術,所以有比較好的相容性。

1.分段傳輸

bigPipe依賴於分段傳輸html頁面,所以這是實現bigPipe的一個基礎。

http1。1

如果在http1。1版本上實現,那需要設定Transfer-Encoding為chunked,也就是分塊傳輸編碼。

關於分塊傳輸編碼:

分塊傳輸編碼允許伺服器為動態生成的內容維護HTTP持久連線。在這種情況下,不能使用HTTP Content-Length頭來分隔內容和下一個HTTP請求/響應,因為內容大小未知。

分塊編碼的好處是,在返回客戶端前不必生成完整的內容,因為它允許將內容作為分塊進行流式處理,並明確地發出內容結尾的訊號,從而使連線可用於下一個HTTP請求/響應。

在頭部加入 Transfer-Encoding: chunked 之後,就代表這個報文采用了分塊編碼。這時,報文中的實體需要改為用一系列分塊來傳輸。

每個分塊包含十六進位制的長度值和資料,長度值獨佔一行,長度不包括它結尾的 CRLF(\r\n),也不包括分塊資料結尾的 CRLF。

最後一個分塊長度值必須為 0,對應的分塊資料沒有內容,表示實體結束。

http 2

如果你使用的是http2,那則無需設定Transfer-Encoding為chunked,因為http2本身就是支援這種分塊傳輸的協議。

2.瀏覽器渲染原理

說到瀏覽器渲染,我們可以簡單地把它歸為五個階段。(為了方便分析渲染過程,先不考慮有js的情況)

階段一:

解析html文件,生成節點,構建dom樹

階段二:

在階段一中,如果遇到css(內嵌在html文件或者外鏈或者內聯樣式都一樣),則會解析css文件,生成cssom。

階段三:

階段一和階段二都是可以並行的,等到dom和cssom準備好,會進行合併,生成render tree。

階段四:

根據render tree進行layout。

階段五:

繪製到顯示區域。

整個階段如下圖所示

bigPipe 原理分析

幸運的是,

瀏覽器並不會等解析完完整的html文件後,才進行layout 和paint

瀏覽器已經對顯示html文件進行了最佳化,會盡快將解析好的部分呈現給使用者。也就是,上圖所謂的一次渲染過程,在分塊傳輸的時候,是可以多次進行的。直到接收到閉合標籤。

五、實踐

bigPipe技術的基本原理在上面就已經介紹完了。實踐都是基於以上原理而來的。

常規實踐是將頁面分成各個模組,稱之為一個個pagelets,每個pagelets包含自己需要的模板資料,css樣式和需要的js。

在傳輸pagelets之前,先將頁面主體layout傳輸到客戶端,先進行渲染,此時,使用者已經可以看到頁面的主體框架了。

之後,再將服務端處理完的pagelets一個個返回,在客戶端渲染。如下圖:

bigPipe 原理分析

參考資料:

https://www。facebook。com/note。php?note_id=389414033919

http://

taobaofed。org/blog/2015

/12/17/seller-bigpipe/

http://

taobaofed。org/blog/2016

/03/25/seller-bigpipe-coding/

標簽: 分塊  渲染  客戶端  服務端  HTML