渲染引擎 & 页面渲染流程 & 阻塞
文檔對象模型(Document Object Model,簡稱DOM)
瀏覽器渲染引擎
一個渲染引擎 主要模塊:
HTML 解析器
解釋 HTML 文檔的解析器,將 HTML 文本 解析成 DOM 樹
css 解析器
級聯(lián)樣式的解析器,為 DOM 中的各個元素計算出樣式信息,為布局提高基礎(chǔ)設(shè)施
javascript 引擎
使用 Javascript 代碼可以修改網(wǎng)頁的內(nèi)容,也能修改 css 的信息
javascript 引擎能夠解釋 javascript 代碼,并通過 DOM 接口和 CSSOM 接口來修改網(wǎng)頁內(nèi)容和樣式信息,從而改變渲染的結(jié)果。
layout 布局模塊
在 DOM 創(chuàng)建之后,Webkit 需要將其中的元素對象同樣式信息結(jié)合起來,
計算他們的大小位置等布局信息,形成一個能表達(dá)這所有信息的內(nèi)部表示模型
繪圖模塊
使用 圖形庫 將布局計算后的各個網(wǎng)頁的節(jié)點 繪制成 圖像結(jié)果
瀏覽器渲染頁面的整個過程,瀏覽器會從上至下解析文檔:
以上這些模塊依賴很多其他的基礎(chǔ)模塊,包括要使用到網(wǎng)絡(luò) 存儲 2D/3D圖像 音頻視頻解碼器 和 圖片解碼器。
所以渲染引擎中還會包括如何使用這些依賴模塊的部分。
1. 遇見HTML 標(biāo)記
調(diào)用 HTML 解析器解析為對應(yīng)的 token (一個 token 就是一個標(biāo)簽文本的序列化)
并構(gòu)建 DOM 樹(就是一塊內(nèi)存,保存著 tokens,建立它們之間的關(guān)系)
2.遇見 style/link 標(biāo)記 調(diào)用 css 解析器 處理 CSS 標(biāo)記并構(gòu)建 內(nèi)部表示結(jié)構(gòu) CSSOM 樹
CSS 解析器工作完成之后,在 DOM 樹上附加解釋后的樣式信息,這就是 RenderObject 樹
RenderObject 在創(chuàng)建的同時,Webkit 會根據(jù)網(wǎng)頁的結(jié)構(gòu)創(chuàng)建 RenderLayer,同時構(gòu)建一個繪圖上下文
根據(jù) 繪圖上下文 生成最終的圖像(這一過程需要依賴圖形庫)
3.遇見 script 標(biāo)記 調(diào)用 javascript 解析器 處理 script 標(biāo)記,綁定事件、修改 DOM 樹 / CSSOM樹 等
4.將 DOM 樹 與 CSSOM 樹 再次合并成一個渲染樹 Render 樹
5.根據(jù) 渲染樹 來布局,以計算每個節(jié)點的幾何信息____重排
6.將各個節(jié)點繪制到屏幕上____重繪
上面介紹的是一個完整的渲染過程
但現(xiàn)代網(wǎng)頁很多都是動態(tài)的,這意味著在渲染完成之后,
由于網(wǎng)頁的動畫或者用戶的交互,瀏覽器其實一直在不停地重復(fù)執(zhí)行渲染過程。(重繪重排)
以上的數(shù)字表示的是基本順序,這不是嚴(yán)格一致的,這個過程可能重復(fù)也可能交叉
網(wǎng)頁在加載和渲染過程會觸發(fā) "DOMContentLoaded" 和 "load" 事件
----> 分別在 DOM 樹解析完成后,觸發(fā) "DOMContentLoaded"
----> DOM 樹構(gòu)建并且網(wǎng)頁所有依賴資源都加載完成之后發(fā)生,觸發(fā) "load"
實際測試
瀏覽器加載資源是異步的
用 <style> 內(nèi)部樣式表 寫 css,是由 Parse HTML 異步解析的。
一張圖片分多次解析,其中 Parse HTML 這么快,體現(xiàn)了其異步執(zhí)行,只是開啟了一個任務(wù),讓它自己去請求資源并解析
css 阻塞 ---- 樣式寫在外部文件,在 index.css 中 link 導(dǎo)入
通過 link 進來的樣式 是同步解析的,由 Parse Stylesheet 進行解析
正因為是同步解析,所以 css 解析器 會阻塞頁面的渲染,從而避免了閃屏
這也是為什么推薦使用 <style link='index.css'> 引入外部樣式表
阻塞
css 阻塞
<style> 標(biāo)簽中的樣式
1. 由 html 解析器進行解析
2. 不阻塞瀏覽器渲染
3. 不阻塞 DOM 解析
<link src='index.css'>引入的外部 css 樣式 (推薦使用 <link> 方式引入外部 css,可以避免閃屏現(xiàn)象)
1. 由 CSS 解析器進行解析
2. 會阻塞瀏覽器頁面渲染(原因:避免閃屏)
<link rel="stylesheet" href="css/my-sleep-3000-commen.css" />
3. 不阻塞 DOM 結(jié)構(gòu)的解析
因為 DOM 解析 和 CSS 解析是兩個并行的進程
瀏覽器解析 DOM 生成 DOM Tree,解析 CSS 生成 CSS Tree
最終組成 render Tree,再渲染頁面,DOM 的解析,和 CSS的解析并行的。
4. 會阻塞 js 的執(zhí)行(但不會阻塞 js 等資源的加載)
腳本在文檔解析階段會請求樣式信息,如果 css 還沒有完全加載解析完,腳本可能獲得錯誤的回復(fù)
FireFox 會在樣式表加載解析過程中,禁止所有腳本
對于 WebKit 而言,僅當(dāng)腳本嘗試訪問樣式屬性可能會得到錯誤的回復(fù)時,禁止腳本的執(zhí)行
優(yōu)化方案: (盡可能快的提高 css 加載速度)
使用 CDN 加速
對 css 進行壓縮(用打包工具,比如 webpack, gulp 等,也可以通過開啟 gzip 壓縮)
減少 http 請求數(shù),將多個 css 文件合并
js 阻塞
會阻塞 DOM 解析
因為 js 可能會修改 DOM 樹
會阻塞 頁面的渲染
因為 js 代碼可能會修改 DOM 樹 / CSSOM 樹 的結(jié)構(gòu)
js 會順序執(zhí)行,阻塞后續(xù) js 邏輯的執(zhí)行 (不阻塞 js 等其他資源的加載)
維護依賴關(guān)系
css 的解析 和 js 的執(zhí)行 是互斥的 ( css 解析的時候 js 停止執(zhí)行,js 執(zhí)行的時候 css 停止解析)
預(yù)解析
WebKit 和 FireFox 都進行了這項優(yōu)化。
在執(zhí)行 js 腳本時,其他線程會解析文檔的其余部分 (只是檢查,不影響原結(jié)構(gòu)),找出并加載需要網(wǎng)絡(luò)加載的其他資源
使得這些資源在并行連接上加載,從而提高總體速度
預(yù)解析器 不會修改 DOM 樹,而是將這件事交給 主解析器 處理
預(yù)解析器 只會解析外部資源的引用(例如外部腳本、樣式、圖片)
提前發(fā)送請求,提前解析外部資源內(nèi)容
--------小尾巴
________一個人欣賞-最后一朵顏色的消逝-忠誠于我的是·一顆叫做野的心.決不受人奴役.怒火中生的那一刻·終將結(jié)束...
總結(jié)
以上是生活随笔為你收集整理的渲染引擎 & 页面渲染流程 & 阻塞的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么北鼎的养生壶贵?
- 下一篇: 雅迪电动车24安锂电池,跑了两年后还能跑