聊聊瀏覽器渲染機制及常見bug

前言

瀏覽器拿到服務器的響應文本HTML後,如何渲染頁面?這是本文所要討論的問題!

瀏覽器
瀏覽器

一、瀏覽器渲染機制

瀏覽器不同,渲染機制就不同。其中兩種典型的代表就是IE、chrome瀏覽器和firefox瀏覽器,主要原因是由於渲染引擎不同。接下來我們看看他們渲染過程有何差異?
1.chrome瀏覽器的渲染過程:

    解析HTML,構建DOM樹
    解析CSS,構建CSSOM樹
    把DOM和CSSOM組合成渲染樹(render tree)
    在渲染器的基礎上進行佈局,計算每個節點的幾何結構
    把每個節點繪製到屏幕上(painting)

2.firefox瀏覽的渲染過程:

    解析HTML,構建DOM樹
    繪製HTML內容
    解析CSS,構建CSSOM樹
    把DOM和CSSOM組合成渲染樹(render tree)
    在渲染器的基礎上進行佈局,計算每個節點的幾何結構
    給所有的HTML內容添加樣式

二、CSS和JS部分在網頁中的位置

CSS一般放在HTML的頭部,也就是<head>標籤裏面。

先不談JS文件,以chrome瀏覽器爲例,當瀏覽器拿到服務器的響應文本HTML後,會從上往下開始構建DOM樹,但如果中途遇到<link>或者<style>引入的CSS部分,瀏覽器就會同步構建 CSSOM樹。由於CSSOM樹的構建比DOM樹來得慢,所以將CSS部分放在HTML的頭部,比較合理!

JS一般放在HTML的尾部,也就是</body>前面。

JS 是可以修改 DOM 節點和 DOM 樣式的,JS 既阻塞 DOM、CSSOM 的構建,也會阻塞渲染樹的生成。在解析 HTML過程 中發現 JS文件 ,等到下載並執行完 JS 後,纔會繼續解析、構建DOM和CSSOM。因此我們常常把<script>部分放到</body>前面,防止屏幕白屏。

三、白屏問題和FOUS

由於瀏覽器的渲染機制不同,在渲染頁面的時會出現兩種常見的不良現象,白屏問題和FOUS(無樣式內容閃爍)
FOUC:由於瀏覽器渲染機制(比如firefox),再CSS加載之前,先呈現了HTML,就會導致展示出無樣式內容,然後樣式突然呈現的現象;
白屏:有些瀏覽器渲染機制(比如chrome)要先構建DOM樹和CSSOM樹,構建完成後再進行渲染,如果CSS部分放在HTML尾部,由於CSS未加載完成,瀏覽器遲遲未渲染,從而導致白屏;或如果使用 @import標籤,即使 CSS 放入 link, 並且放在頭部,也可能出現白屏。也可能是把js文件放在頭部,腳本會阻塞後面內容的呈現,腳本會阻塞其後組件的下載,出現白屏問題。

四、async和defer的作用是什麼?有什麼區別?

情況1.<script src="script.js"></script>

沒有 defer 或 async,瀏覽器會立即加載並執行指定的腳本,“立即”指的是在渲染該 script 標籤之下的文檔元素之前,也就是說不等待後續載入的文檔元素,讀到就加載並執行。

情況2. <script async src="script.js"></script> (異步下載)

有async,加載和渲染後續文檔元素的過程將和 script.js 的加載與執行並行進行(異步)。

情況3. <script defer src="myscript.js"></script>(延遲執行)

有 defer,加載後續文檔元素的過程將和 script.js 的加載並行進行(異步),但是 script.js 的執行要在所有元素解析完成之後,DOMContentLoaded 事件觸發之前完成。
在加載多個JS腳本的時候,async是無順序的加載,而defer是有順序的加載。

async和defer
async和defer

其中藍色線代表網絡讀取,紅色線代表執行時間,這倆都是針對腳本的;綠色線代表 HTML 解析。

參考:async 和 defer 的區別 | SegmentFault

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章