前端性能優(yōu)化(中)

圖片來(lái)自 昵圖網(wǎng)

性能優(yōu)化調(diào)研系列文章

  1. 《前端性能優(yōu)化(上)》
  2. 《前端性能優(yōu)化(中)》
  3. 《前端性能優(yōu)化(下)》

《前端性能優(yōu)化(上)》 主要說(shuō)明了:

  1. 為什么要進(jìn)行前端性能優(yōu)化矗蕊?
  2. 如何衡量前端性能郊楣?

這一篇主要記錄了瀏覽器的加載澎语、渲染過(guò)程的調(diào)研結(jié)果和理解榆综。(待詳細(xì)梳理 提供動(dòng)畫版本)

瀏覽器加載杜恰、渲染過(guò)程

有一道經(jīng)典的前端面試題: 從輸入一個(gè)url到頁(yè)面展示發(fā)生了什么饿序? 涉及到計(jì)算機(jī)網(wǎng)絡(luò)劳澄、操作系統(tǒng)、web等各個(gè)方面,從軟件到硬件柴底,從協(xié)議到實(shí)現(xiàn)婿脸,每一個(gè)點(diǎn)都可以展開(kāi)深入的學(xué)習(xí),所以很考察面試者的綜合能力和某一個(gè)方面的深入掌握程度柄驻。

關(guān)于這部分知識(shí)狐树,可以參考李兵老師的《瀏覽器原理》 課程介紹,下面的內(nèi)容很大一部分 都是引用他的課程內(nèi)容;另外《瀏覽器是如何工作的》也非常深入的介紹了瀏覽器工作的原理鸿脓。

如果你想要有更深入的理解和掌握抑钟,建議你跟著大神一起來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的瀏覽器引擎

image

不聞不若聞之 聞之不若見(jiàn)之 見(jiàn)之不若知之 知之不若行之 學(xué)至于行而止矣 -- 荀子

瀏覽器架構(gòu)

瀏覽器渲染流水線
進(jìn)程間通信
渲染主線程

瀏覽器導(dǎo)航

image

圖片來(lái)源: 極客時(shí)間

  1. 瀏覽器主進(jìn)程處理用戶輸入
  2. 瀏覽器主進(jìn)程 通知網(wǎng)絡(luò)進(jìn)程 發(fā)起真正的請(qǐng)求
  3. 網(wǎng)絡(luò)進(jìn)程接收到請(qǐng)求頭信息之后 發(fā)送給瀏覽器主進(jìn)程
  4. 瀏覽器主進(jìn)程 接收到網(wǎng)絡(luò)進(jìn)程發(fā)送的頭消息之后 發(fā)送“提交導(dǎo)航 (CommitNavigation)”消息到渲染進(jìn)程
  5. 渲染進(jìn)程 收到“提交導(dǎo)航”消息之后,直接和網(wǎng)絡(luò)進(jìn)程建立數(shù)據(jù)管道野哭,接受html數(shù)據(jù)
  6. 渲染進(jìn)程接收html數(shù)據(jù)完成之后在塔,會(huì)通知瀏覽器主進(jìn)程:確認(rèn)提交
  7. 主進(jìn)程收到渲染進(jìn)程的“確認(rèn)提交”消息之后,就開(kāi)始更新瀏覽器的狀態(tài):loading虐拓、前進(jìn)心俗、后退、url蓉驹、當(dāng)前頁(yè)面
navigation timimg

以上 整個(gè)導(dǎo)航流程就走完了城榛。

瀏覽器渲染流水線

一旦渲染進(jìn)程發(fā)送 “確認(rèn)提交”給瀏覽器主進(jìn)程,就會(huì)開(kāi)始解析頁(yè)面加載子資源态兴。

  1. html parsing


    圖片來(lái)自google 文檔- 解析html
  2. 生成DOM樹(shù)


    圖片來(lái)源 google文檔- 生成DOM樹(shù)
  3. 樣式計(jì)算:Recaculate Style
    將樣式信息(來(lái)自內(nèi)聯(lián)樣式狠持、style、link等)轉(zhuǎn)換成styleSheets瞻润;
    Recaculate Style 使用所有通過(guò)css parser解析得到的style rules喘垂,包括瀏覽器給出的默認(rèn)樣式,計(jì)算出每一個(gè)DOM元素最終的style的值绍撞,存儲(chǔ)在ComputedStyle中正勒。

圖片來(lái)源 google文檔- 樣式計(jì)算
  1. 布局階段: 生成LayoutTree
    經(jīng)過(guò)樣式計(jì)算階段之后,DOM-Tree中的節(jié)點(diǎn)都有了自己的樣式信息傻铣,但是還不知道如何排版章贞,放到哪個(gè)位置。
    布局階段非洲,就是確定繪制區(qū)域的位置和大小鸭限,相對(duì)來(lái)說(shuō)也是比較復(fù)雜。
    • 對(duì)于block flow布局來(lái)說(shuō)相對(duì)簡(jiǎn)單两踏,從上往下依次排列就好
      block flow
    • inline block


      inline-block
    • 其他更復(fù)雜的排版:文字败京、float、flex梦染、table等等

總結(jié)來(lái)說(shuō)赡麦,經(jīng)過(guò)了布局階段之后,就生成了一個(gè)LayoutTree

layout tree

  1. paint


    google文檔-繪制
    • 我們已經(jīng)通過(guò)布局階段,得到了一棵LayoutTree隧甚,現(xiàn)在我們已經(jīng)知道了每一個(gè)Layout object的布局车荔、顯示信息
    • 分層 生成圖層數(shù)LayerTree:z-index、3D轉(zhuǎn)換戚扳、 z-index 等會(huì)影響布局對(duì)象的顯示順序(層級(jí))請(qǐng)參考 《層疊上下文》
      分層
    • 根據(jù)LayerTree,產(chǎn)出一個(gè)線性的繪制對(duì)象列表(列表中的每一個(gè)元素存放著繪制的顯示對(duì)象和對(duì)應(yīng)的繪制操作)
    • 對(duì)于單獨(dú)的一個(gè)Layout Object族吻,可能會(huì)包含多個(gè)顯示對(duì)象(Display Item)(如果你使用過(guò)canvas 來(lái)繪制一些東西或者使用過(guò)一些游戲引擎對(duì)這個(gè)應(yīng)該比較熟悉)

輸出的display item list,會(huì)作為合成線程的輸出

current display item list: [
  {
    "chunk": "LayoutBlockFlow DIV id='example' 
        0x1b94c141c0:LayoutBlockFlow DIV id='example':DrawingPaintPhaseSelfBlockBackgroundOnly:0",
    "state": "t:0x3e697bca90 c:0x3e697ac8d0 e:0x3e697ac290",
    "displayItems": [
      {
        "index": 0,
        "clientDebugName": "InlineTextBox 'hi'",
        "id": "0x1605c60410:InlineTextBox 'hi':DrawingPaintPhaseForeground:0",
        "visualRect": "401,357 72x20",
        "opaque": false,
        "record": [
          {
            "method": "drawTextBlob",
            "params": {
              "x": 401.5,
              "y": 373,
              "paint": {
                "color": "#FF333333",
                "strokeWidth": 0,
                "strokeMiter": 4,
                "flags": "AntiAlias",
                "filterLevel": "Low",
                "strokeCap": "Butt",
                "strokeJoin": "Miter",
                "styleName": "Fill"
              }
            }
          }
        ]
      }
    ]
  }
]


  1. 光柵化
    • 渲染主線程提交 繪制列表給 合成線程帽借;
    • 合成線程將圖層劃分為圖塊(256256 或者 512512)
    • 合成線程將圖塊提交給 柵格化線程池
    • 渲染主進(jìn)程 通過(guò)柵格化線程 發(fā)送圖塊生成位圖的指令發(fā)送給GPU,
    • GPU 生成圖塊的位圖超歌,保存在GPU內(nèi)存中
    • 一旦所有圖塊都被光柵化 合成線程就會(huì)生成一個(gè)繪制圖塊的命令——“DrawQuad”砍艾,然后將該命令提交給瀏覽器進(jìn)程
    • 瀏覽器進(jìn)程里面有一個(gè)叫 viz 的組件,用來(lái)接收合成線程發(fā)過(guò)來(lái)的 DrawQuad 命令巍举,然后根據(jù) DrawQuad 命令脆荷,將其頁(yè)面內(nèi)容繪制到內(nèi)存中,最后再將內(nèi)存顯示在屏幕上

圖片來(lái)源:極客時(shí)間

image

圖片來(lái)源 google 文檔

幾個(gè)關(guān)于渲染流水線的問(wèn)題

待補(bǔ)充示例demo

  1. CSS 外鏈下載會(huì)阻塞 DOM 的構(gòu)建嗎懊悯?
    不會(huì)蜓谋, 參考demo
  1. CSS 外鏈下載會(huì)阻塞 布局樹(shù)的構(gòu)建嗎?
    會(huì) 參考demo

  2. CSS外鏈文件下載會(huì)阻塞后面的js的下載嗎炭分?
    不會(huì)桃焕,現(xiàn)代瀏覽器會(huì)在收到html文檔之后預(yù)解析,請(qǐng)求所有的資源


    image.png
  3. CSS外鏈文件下載會(huì)阻塞js的執(zhí)行嗎捧毛?
    會(huì)


    css的下載阻塞了js的執(zhí)行
  4. js文件的下載和執(zhí)行會(huì)阻塞 DOM樹(shù)的構(gòu)建嗎观堂?
    會(huì)

參考

  1. Let's build a browser engine!

  2. 《瀏覽器原理》

  3. 《瀏覽器是如何工作的》

  4. How Blink works

  5. life of pixel

  6. chrome university

  7. Inside a super fast CSS engine: Quantum CSS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市呀忧,隨后出現(xiàn)的幾起案子师痕,更是在濱河造成了極大的恐慌,老刑警劉巖而账,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胰坟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡福扬,警方通過(guò)查閱死者的電腦和手機(jī)腕铸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)铛碑,“玉大人狠裹,你說(shuō)我怎么就攤上這事∑常” “怎么了涛菠?”我有些...
    開(kāi)封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我俗冻,道長(zhǎng)礁叔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任迄薄,我火速辦了婚禮琅关,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讥蔽。我一直安慰自己涣易,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布冶伞。 她就那樣靜靜地躺著新症,像睡著了一般。 火紅的嫁衣襯著肌膚如雪响禽。 梳的紋絲不亂的頭發(fā)上徒爹,一...
    開(kāi)封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音芋类,去河邊找鬼隆嗅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛梗肝,可吹牛的內(nèi)容都是我干的榛瓮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼巫击,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼禀晓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起坝锰,我...
    開(kāi)封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤粹懒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后顷级,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體凫乖,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年弓颈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了帽芽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翔冀,死狀恐怖导街,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纤子,我是刑警寧澤搬瑰,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布款票,位于F島的核電站,受9級(jí)特大地震影響泽论,放射性物質(zhì)發(fā)生泄漏艾少。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一翼悴、第九天 我趴在偏房一處隱蔽的房頂上張望缚够。 院中可真熱鬧,春花似錦抄瓦、人聲如沸潮瓶。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至埂伦,卻和暖如春煞额,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沾谜。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工膊毁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人基跑。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓婚温,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親媳否。 傳聞我的和親對(duì)象是個(gè)殘疾皇子栅螟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容