<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          bigPipe 原理分析

          共 2297字,需瀏覽 5分鐘

           ·

          2023-08-01 00:25

          一、什么是bigPipe?

          bigPipe是由facebook提出來的一種動(dòng)態(tài)網(wǎng)頁加載技術(shù)。它將網(wǎng)頁分解成稱為pagelets的小塊,然后分塊傳輸?shù)綖g覽器端,進(jìn)行渲染。它可以有效地提升首屏渲染時(shí)間。

          為了說清楚什么是bigPipe,我先需要介紹下目前的常規(guī)渲染方式,以及可以進(jìn)行優(yōu)化的方向。

          二、網(wǎng)頁首屏加載方案

          注:首屏加載方案指的是在服務(wù)端就已經(jīng)吐出頁面的方案,也就是說有SSR的方案,那些純客戶端渲染的方案不做比較,因?yàn)樗鼈儧]有首屏要求。

          現(xiàn)有的網(wǎng)頁首屏加載方案一般會(huì)經(jīng)過以下階段:

          1. 發(fā)送http請(qǐng)求到服務(wù)端

          2. 服務(wù)端接收并分析請(qǐng)求

          3. 服務(wù)端根據(jù)請(qǐng)求從存儲(chǔ)層獲取相關(guān)數(shù)據(jù),這里可能會(huì)比較耗時(shí),比如如果首頁涉及多個(gè)模塊(廣告位、推薦、內(nèi)容列表、用戶信息、好友列表等)

          4. 服務(wù)端準(zhǔn)備好所有內(nèi)容,拼接成完整的html文檔

          5. 發(fā)送回客戶端

          6. 客戶端接收完整的html文檔

          7. 構(gòu)建dom、cssom, 生成render tree,渲染出指定頁面

          如下圖所示:

          以上加載方案的缺點(diǎn)是,當(dāng)2、3、4、5 步在服務(wù)端進(jìn)行的時(shí)候,瀏覽器只能是傻傻地等待,做不了任何事情!


          而且第3步并行拉取業(yè)務(wù)數(shù)據(jù)在某些場(chǎng)景下(模塊多,業(yè)務(wù)場(chǎng)景復(fù)雜),是會(huì)占用比較多的時(shí)間的。而且只要其中某個(gè)模塊的數(shù)據(jù)如果拉取較慢,會(huì)拖慢整個(gè)首屏的顯示。

          更糟糕的情況下,某些模塊數(shù)據(jù)相互依賴,導(dǎo)致需要串行拉取數(shù)據(jù),那造成的瀏覽器的等待則會(huì)更久。


          三、優(yōu)化方案

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

          而bigPipe就是針對(duì)第3、4步進(jìn)行優(yōu)化,讓服務(wù)端在準(zhǔn)備好某個(gè)模塊的數(shù)據(jù)后,立馬返回給客戶端顯示,而不必要等待完整的數(shù)據(jù)和html生成,再發(fā)送給客戶端。

          客戶端在接收到某一部分內(nèi)容后,就可以開始渲染,顯示執(zhí)行(這里可以動(dòng)態(tài)請(qǐng)求需要的css,js 等等)。

          如下圖,客戶端拉取業(yè)務(wù)數(shù)據(jù)和客戶端渲染頁面可以并行。如果某一部分比如廣告信息拉取超時(shí),也并不影響其他部分率先渲染顯示。

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

          四、關(guān)鍵技術(shù)和原理

          想要實(shí)現(xiàn)以上優(yōu)化方案,可以利用現(xiàn)成的技術(shù),所以有比較好的兼容性。

          1.分段傳輸

          bigPipe依賴于分段傳輸html頁面,所以這是實(shí)現(xiàn)bigPipe的一個(gè)基礎(chǔ)。

          http1.1

          如果在http1.1版本上實(shí)現(xiàn),那需要設(shè)置Transfer-Encoding為chunked,也就是分塊傳輸編碼。

          關(guān)于分塊傳輸編碼:

          分塊傳輸編碼允許服務(wù)器為動(dòng)態(tài)生成的內(nèi)容維護(hù)HTTP持久連接。在這種情況下,不能使用HTTP Content-Length頭來分隔內(nèi)容和下一個(gè)HTTP請(qǐng)求/響應(yīng),因?yàn)閮?nèi)容大小未知。

          分塊編碼的好處是,在返回客戶端前不必生成完整的內(nèi)容,因?yàn)樗试S將內(nèi)容作為分塊進(jìn)行流式處理,并明確地發(fā)出內(nèi)容結(jié)尾的信號(hào),從而使連接可用于下一個(gè)HTTP請(qǐng)求/響應(yīng)。

          在頭部加入 Transfer-Encoding: chunked 之后,就代表這個(gè)報(bào)文采用了分塊編碼。這時(shí),報(bào)文中的實(shí)體需要改為用一系列分塊來傳輸。

          每個(gè)分塊包含十六進(jìn)制的長(zhǎng)度值和數(shù)據(jù),長(zhǎng)度值獨(dú)占一行,長(zhǎng)度不包括它結(jié)尾的 CRLF(\r\n),也不包括分塊數(shù)據(jù)結(jié)尾的 CRLF。

          最后一個(gè)分塊長(zhǎng)度值必須為 0,對(duì)應(yīng)的分塊數(shù)據(jù)沒有內(nèi)容,表示實(shí)體結(jié)束。

          http 2

          如果你使用的是http2,那則無需設(shè)置Transfer-Encoding為chunked,因?yàn)閔ttp2本身就是支持這種分塊傳輸?shù)膮f(xié)議。

          2.瀏覽器渲染原理

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

          階段一:

          解析html文檔,生成節(jié)點(diǎn),構(gòu)建dom樹

          階段二:

          在階段一中,如果遇到css(內(nèi)嵌在html文檔或者外鏈或者內(nèi)聯(lián)樣式都一樣),則會(huì)解析css文檔,生成cssom。

          階段三:

          階段一和階段二都是可以并行的,等到dom和cssom準(zhǔn)備好,會(huì)進(jìn)行合并,生成render tree。

          階段四:

          根據(jù)render tree進(jìn)行l(wèi)ayout。

          階段五:

          繪制到顯示區(qū)域。

          整個(gè)階段如下圖所示


          幸運(yùn)的是,瀏覽器并不會(huì)等解析完完整的html文檔后,才進(jìn)行l(wèi)ayout 和paint

          瀏覽器已經(jīng)對(duì)顯示html文檔進(jìn)行了優(yōu)化,會(huì)盡快將解析好的部分呈現(xiàn)給用戶。也就是,上圖所謂的一次渲染過程,在分塊傳輸?shù)臅r(shí)候,是可以多次進(jìn)行的。直到接收到</body></html>閉合標(biāo)簽。

          五、實(shí)踐

          bigPipe技術(shù)的基本原理在上面就已經(jīng)介紹完了。實(shí)踐都是基于以上原理而來的。

          常規(guī)實(shí)踐是將頁面分成各個(gè)模塊,稱之為一個(gè)個(gè)pagelets,每個(gè)pagelets包含自己需要的模板數(shù)據(jù),css樣式和需要的js。

          在傳輸pagelets之前,先將頁面主體layout傳輸?shù)娇蛻舳耍冗M(jìn)行渲染,此時(shí),用戶已經(jīng)可以看到頁面的主體框架了。

          之后,再將服務(wù)端處理完的pagelets一個(gè)個(gè)返回,在客戶端渲染。如下圖:

          瀏覽 343
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲欧洲视频在线观看 | 日韩三级电影在线观看 | 蜜臀VA| 韩国精品视频一区二区三区 | 就去 婷婷 操逼 |