一、概述
在分析瀏覽器的渲染過程之前,我們先了解一下什么是進程和線程:
(1)什么是進程?
進程是CPU進行資源分配的基本單位
(2)什么是線程?
線程是CPU調度的最小單位,是建立在進程的基礎上運行的單位,共享進程的內存空間。
那么我們可以得出結論:
1、進程是會占用系統資源;2、一個進程內可以存在一個或者多個線程,這就是單線程和多線程;3、無論是單線程還是多線程都是在一個進程內。
博客首發地址(sau交流學習社區):https://www.mwcxs.top/page/567.html
二、多進程
從上圖中可知:
1、瀏覽器是多進程
2、不同類型的標簽頁都會開啟一個新的進程
3、相同類型的標簽頁是會合並到一個進程
上圖中瀏覽器的各個進程的主要作用:
1、瀏覽器進程
(1)負責管理各個標簽頁的創建和銷毀
(2)負責瀏覽器的頁面顯示和功能(前進,后退,收藏等)
(3)負責資源的管理與下載
2、第三方插件進程
(1)負責每個第三方插件的使用,每個第三方插件使用時候都會創建一個對應的進程
3、GPU進程
(1)負責3D繪制和硬件加速
4、瀏覽器渲染進程(咱們這回主要分析的)
1、瀏覽器內核,主要負責HTML,CSS,JS等文件的解析和執行
三、瀏覽器內核
瀏覽器內核就是瀏覽器渲染進程,從接收下載文件后再到呈現整個頁面的過程,由瀏覽器渲染進程負責,主要流程如下:
1、解析HTML文件和CSS文件,加載圖片等資源文件,渲染成用戶看到的頁面
2、執行解析js文件腳本代碼
這里主要講瀏覽器頁面渲染過程,js腳本解析執行過程,可以看這篇文章:Javascript引擎執行的過程的理解--執行階段 ,所以本文的js解析的內容會省略
在該過程中瀏覽器渲染進程會開啟多個線程協作完成,主要的線程以及作用如下:
1、GUI渲染線程
(1)負責解析HTML文件構建DOM樹,解析CSS,結合DOM樹渲染成RenderObject樹,然后布局和繪制頁面
(2)當RenderObject樹需要更新樣式屬性時,即發生重繪(Repaint);當RenderObject樹中的元素規則尺寸,布局或顯示隱藏等發生變化,即發生回流(reflow)。
2、JS引擎線程
3、時間出發線程
4、定時器觸發線程
5、異步Http請求線程
注:GUI渲染線程與JS引擎線程是相互排斥的,因為JS引擎線程在執行的過程中可能會發生重繪和回流,所以GUI渲染線程執行時候,JS引擎線程會被掛起,等待GUI渲染線程執行完畢之后,JS引擎線程執行時候同理。
3.1GUI渲染線程
首先看一張圖,圖如下
接下來我們主要分析GUI渲染線程執行的詳細過程:
1、解析HTML文件,構建DOM樹,同時瀏覽器主進程負責下載CSS文件
2、CSS文件下載完成,解析CSS文件成樹形的數據結構,然后結合DOM樹合並成RenderObject樹
3、布局RenderObject樹,負責RenderObject樹中的元素的尺寸,位置等計算
4、繪制RenderObject樹,繪制頁面的像素信息
5、瀏覽器主進程將默認的圖層和復合圖層交給GPU進程,GPU進程再將各個圖層合成(conposite),最后顯示出頁面
注意:
1、默認圖層指的是出於普通文檔流的元素
2、復合圖層一般指的使用動畫執行或者<video><iframe><canvas><webgl>等元素,也可以使用z-index將層級高的元素變成復合圖層,使用復合圖層可以進行硬件加速,其原理是避免了默認圖層的重繪和回流,想了解更深入介意自行研究
了解GUI渲染線程的執行過程,我們可以根據原理進行渲染優化:
1、盡可能早的提前引入css文件,例如在頭部引入css文件。
2、盡可能早的加載css文件中的引入的資源,例如自定義字體文件,可以使用預加載,在link標簽中加入rel=“preload” as = “font”該元素屬性,不會造成渲染阻塞。
3、在DOM和CSS渲染之后加載js文件,例如在尾部加載js文件,或者使用該元素屬性defer和async,進行js問價異步加載,但是不同的瀏覽器會有兼容性問題。
四、總結
主要是介紹瀏覽器的渲染過程,但是沒有分析js腳本文件解析過程。
(一)瀏覽器渲染進程包含1、解析HTML文件和CSS文件,加載圖片等資源文件,渲染成用戶看到的頁面;2、執行解析js文件腳本代碼。
(二)整個過程瀏覽器會開啟多個線程協作完成,包括:GUI渲染線程,JS引擎線程,事件觸發線程,定時器觸發線程,異步HTTP請求線程。
(三)其中GUI渲染線程和JS引擎線程是相互排斥的,因為JS引擎線程在執行的時候有可能會發生重繪和回流。