整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          干貨 - 十分鐘讀懂瀏覽器渲染流程

          文就瀏覽器渲染流程單獨開篇講解,希望大家都能有新的收獲。

          瀏覽器主要組件結構

          (瀏覽器主要組件)

          渲染引擎——webkit和Gecko

          Firefox使用Geoko——Mozilla自主研發的渲染引擎。

          Safari和Chrome都使用webkit。Webkit是一款開源渲染引擎,它本來是為linux平臺研發的,后來由Apple移植到Mac及Windows上。

          本文我主要以webkit渲染引擎來講解,盡管webkit和Gecko使用的術語稍有不同,他們的主要流程基本相同。

          (webkit渲染引擎流程)

          關鍵渲染路徑

          關鍵渲染路徑是指瀏覽器從最初接收請求來的HTML、CSS、javascript等資源,然后解析、構建樹、渲染布局、繪制,最后呈現給客戶能看到的界面這整個過程。

          所以瀏覽器的渲染過程主要包括以下幾步:

          1.解析HTML生成DOM樹。

          2.解析CSS生成CSSOM規則樹。

          3.將DOM樹與CSSOM規則樹合并在一起生成渲染樹。

          4.遍歷渲染樹開始布局,計算每個節點的位置大小信息。

          5.將渲染樹每個節點繪制到屏幕。

          構建DOM樹

          當瀏覽器接收到服務器響應來的HTML文檔后,會遍歷文檔節點,生成DOM樹。

          需要注意的是,DOM樹的生成過程中可能會被CSS和JS的加載執行阻塞。渲染阻塞問題下文會講。

          構建CSSOM規則樹

          瀏覽器解析CSS文件并生成CSS規則樹,每個CSS文件都被分析成一個StyleSheet對象,每個對象都包含CSS規則。CSS規則對象包含對應于CSS語法的選擇器和聲明對象以及其他對象。

          渲染阻塞

          當瀏覽器遇到一個 script 標記時,DOM 構建將暫停,直至腳本完成執行,然后繼續構建DOM。每次去執行JavaScript腳本都會嚴重地阻塞DOM樹的構建,如果JavaScript腳本還操作了CSSOM,而正好這個CSSOM還沒有下載和構建,瀏覽器甚至會延遲腳本執行和構建DOM,直至完成其CSSOM的下載和構建。

          所以,script 標簽的位置很重要。實際使用時,可以遵循下面兩個原則:

          CSS 優先:引入順序上,CSS 資源先于 JavaScript 資源。

          JS置后:我們通常把JS代碼放到頁面底部,且JavaScript 應盡量少影響 DOM 的構建。

          當解析html的時候,會把新來的元素插入dom樹里面,同時去查找css,然后把對應的樣式規則應用到元素上,查找樣式表是按照從右到左的順序去匹配的。

          例如: div p {font-size: 16px},會先尋找所有p標簽并判斷它的父標簽是否為div之后才會決定要不要采用這個樣式進行渲染)。

          所以,我們平時寫CSS時,盡量用id和class,千萬不要過渡層疊。

          構建渲染樹

          通過DOM樹和CSS規則樹我們便可以構建渲染樹。瀏覽器會先從DOM樹的根節點開始遍歷每個可見節點。對每個可見節點,找到其適配的CSS樣式規則并應用。

          渲染樹構建完成后,每個節點都是可見節點并且都含有其內容和對應規則的樣式。這也是渲染樹與DOM樹的最大區別所在。渲染樹是用于顯示,那些不可見的元素當然就不會在這棵樹中出現了,譬如。除此之外,display等于none的也不會被顯示在這棵樹里頭,但是visibility等于hidden的元素是會顯示在這棵樹里頭的。

          渲染樹布局

          布局階段會從渲染樹的根節點開始遍歷,然后確定每個節點對象在頁面上的確切大小與位置,布局階段的輸出是一個盒子模型,它會精確地捕獲每個元素在屏幕內的確切位置與大小。

          渲染樹繪制

          在繪制階段,遍歷渲染樹,調用渲染器的paint()方法在屏幕上顯示其內容。渲染樹的繪制工作是由瀏覽器的UI后端組件完成的。

          reflow與repaint:

          根據渲染樹布局,計算CSS樣式,即每個節點在頁面中的大小和位置等幾何信息。HTML默認是流式布局的,CSS和js會打破這種布局,改變DOM的外觀樣式以及大小和位置。這時就要提到兩個重要概念:replaint和reflow。

          replaint:屏幕的一部分重畫,不影響整體布局,比如某個CSS的背景色變了,但元素的幾何尺寸和位置不變。

          reflow: 意味著元件的幾何尺寸變了,我們需要重新驗證并計算渲染樹。是渲染樹的一部分或全部發生了變化。這就是Reflow,或是Layout。

          所以我們應該盡量減少reflow和replaint,我想這也是為什么現在很少有用table布局的原因之一。

          display:none 會觸發 reflow,visibility: hidden屬性并不算是不可見屬性,它的語義是隱藏元素,但元素仍然占據著布局空間,它會被渲染成一個空框,所以visibility:hidden 只會觸發 repaint,因為沒有發生位置變化。

          有些情況下,比如修改了元素的樣式,瀏覽器并不會立刻 reflow 或 repaint 一次,而是會把這樣的操作積攢一批,然后做一次 reflow,這又叫異步 reflow 或增量異步 reflow。

          有些情況下,比如 resize 窗口,改變了頁面默認的字體等。對于這些操作,瀏覽器會馬上進行 reflow。

          小結

          本文我們就瀏覽器渲染流程逐步了解了一遍,相信大家一定都有所新的收獲,如果大家對于瀏覽器渲染流程還有任何疑問,可前往51Testing軟件測試網哈~或歡迎留言反饋,我們共同交流,共同學習,共同進步。

          要:在本文中,將重點關注網頁的初始渲染,即它從解析 HTML 開始。 我將探索可能導致高渲染時間的問題,以及如何解決它們。

          本文分享自華為云社區《頁面首屏渲染性能指南-云社區-華為云》,作者:Ocean2022。

          我們知道渲染頁面是一個將服務器的響應內容翻譯成圖片的過程。但是,如果你頁面的渲染性能比較糟糕的話,可能會帶來相對較高的跳出率。

          在本文中,我將重點關注網頁的初始渲染,即它從解析 HTML 開始。 我將探索可能導致高渲染時間的問題以及如何解決它們。

          關鍵渲染路徑(CRP)

          關鍵渲染路徑 (CRP) 是瀏覽器將代碼轉換為屏幕上可顯示像素的過程。 它有幾個階段,其中一些可以并行執行以節省時間,但有些部分必須依次完成。 如下圖所示:

          首先,一旦瀏覽器得到響應,它就會開始解析它。 當它遇到依賴項時,它會嘗試下載它。 如果它是一個樣式表文件,瀏覽器必須在渲染頁面之前完全解析它,這就是為什么 CSS 會阻塞渲染的原因。

          如果是腳本,瀏覽器必須:停止解析,下載腳本,然后運行。 只有在那之后它才能繼續解析,因為 JavaScript 程序可以改變網頁的內容(尤其是 HTML)。 這就是為什么 JS 會阻塞解析的原因。

          完成所有解析后,瀏覽器將構建文檔對象模型 (DOM) 和級聯樣式表對象模型 (CSSOM)。 將它們組合在一起得到渲染樹。 頁面的不顯示部分不會進入渲染樹,因為它只包含繪制頁面所需的數據。

          倒數第二步是將渲染樹進行布局, 這個階段也稱為回流:就是計算每個渲染樹節點的每個位置及其大小的地方。

          最后一步是繪制。 它會根據瀏覽器在前一階段計算得到的數據對像素進行著色。

          優化相關結論

          因此,根據這一過程,我們在優化性能方面,得出了一些結論。如果你要提升頁面初始化渲染的性能,你需要:

          • 減少傳輸的數據量
          • 減少瀏覽器必須下載的資源數量(尤其是阻塞的資源)
          • 減小 CRP 的長度

          同時,我們會根據下面 3 個指標來衡量優化的效率:

          • FP(First Paint)
          • FCP(First Contentful Paint)
          • FMP(First Meaningful Paint)

          除了渲染時間之外,還有其他一些因素也需要考慮。例如,你的頁面使用了多少阻塞資源以及下載它們需要多長時間

          性能優化策略

          鑒于我們在上面得出的結論,我們得出網站性能優化有三種主要策略:

          1. 盡量減少通過網絡傳輸的數據量;
          2. 減少通過網絡傳輸的資源總數;
          3. 縮短關鍵渲染路徑;

          1. 減少要傳輸的數據量

          首先,移除所有未使用的部分,例如 JavaScript 中無法訪問的函數、帶有從不匹配任何元素的選擇器的樣式以及被 CSS 永遠隱藏的 HTML 標簽。 其次,刪除所有重復項。

          然后,我建議建立一個自動壓縮過程。 例如,它應該從你的后端服務中刪除所有注釋(但不是源代碼)以及每個不包含附加信息的字符(例如 JS 中的空白字符)。

          完成后,我們剩下的可以是文本字符串。 這意味著我們可以安全地應用諸如 GZIP(大多數瀏覽器都理解)之類的壓縮算法。

          最后,還有緩存。 瀏覽器第一次呈現頁面時它不會有幫助,但它會在以后的訪問中節省很多。 但是,記住兩點至關重要:

          • 如果你使用 CDN,請確保支持緩存并在正確設置。
          • 與其等待資源的到期,不如 將文件的“指紋”嵌入到其 URL 中,以使本地緩存無效。

          當然,應該為每個資源定義緩存策略。 有些可能很少改變或根本不會改變,有的則是變化的很快,還有些文件包含敏感的信息(可以使用 “private” 防止 CDN 緩存私有數據)

          2. 減少關鍵資源的總數

          “關鍵”僅指網頁正確呈現所需的資源。 因此,我們可以直接跳過所有流程中沒有涉及的樣式以及腳本文件。

          樣式

          為了告訴瀏覽器不需要特定的 CSS 文件,我們應該為所有引用樣式表的鏈接設置媒體屬性。 使用這種方法,瀏覽器將只根據需要處理與當前媒體(設備類型、屏幕尺寸)匹配的資源同時降低所有其他樣式表的優先級。 例如,如果你將 media=“print” 屬性添加到引用樣式以打印頁面的樣式標記,則這些樣式不會在不打印媒體時干擾你的關鍵渲染路徑

          為了進一步改進該過程,你還可以將一些樣式內聯這可以為我們節省了至少一次到服務器的往返行程

          腳本

          如上所述,腳本會阻塞解析,因為它們可以改變 DOM 和 CSSOM。 為了避免這一點,所有腳本標簽都必須用屬性標記——異步或延遲。

          標有 async 的腳本不會阻塞 DOM 構建或 CSSOM,因為它們可以在 CSSOM 構建之前執行。 但請記住,內聯腳本無論如何都會阻止 CSSOM,除非你將它們放在 CSS 之上。

          相比之下,標有 defer 的腳本將在頁面加載結束時進行執行

          換句話說,使用 defer,腳本直到頁面加載事件被觸發后才會執行,而 async 讓腳本在文檔被解析時就會在后臺運行。

          3.縮短關鍵渲染路徑長度

          最后,應將 CRP 長度縮短到可能的最小值。

          作為樣式標簽屬性的媒體查詢將減少必須下載的資源總數。 script 標簽屬性 defer 和 async 將防止相應的腳本阻塞解析。

          使用 GZIP 壓縮、壓縮和歸檔資源將減少傳輸數據的大小(從而也減少數據傳輸時間)。

          內聯一些樣式和腳本也可以減少瀏覽器和服務器之間的往返次數。

          按照最新的最佳性能實踐理念,一個網站應該做的最快的第一件事就是展示 ATF 內容。 ATF 代表首屏這是立即可見的區域,無需滾動。 因此,最好以首先加載所需樣式和腳本的方式重新排列與渲染相關的所有內容,而其他所有內容都停止(既不解析也不渲染)。

          結尾

          總而言之,網站性能優化包含了網站響應的各個方面,例如緩存、設置 CDN、重構、資源優化等,但是所有這些都可以逐步完成。 作為 Web 開發人員,你可以將本文作為參考,并始終記住在實驗之前和之后測量性能。

          瀏覽器開發人員盡最大努力優化你訪問的每個頁面的網站性能,這就是瀏覽器通常實現所謂的“預加載器”的原因。 這部分程序會在你以 HTML 格式請求的資源之前進行掃描,以便一次發出多個請求并讓它們并行運行。 這就是為什么在 HTML(逐行)以及腳本標簽中保持樣式標簽彼此靠近的原因。

          此外,嘗試批量更新 HTML 以避免多個布局事件這些事件不僅由 DOM 或 CSSOM 中的更改觸發,而且在設備方向更改和窗口大小調整時也會觸發。

          點擊下方,第一時間了解華為云新鮮技術~

          華為云博客_大數據博客_AI博客_云計算博客_開發者中心-華為云

          段時間有很多同學通過不同渠道問我關于瀏覽器渲染的問題。今天,小郭在這里用簡單的一張圖概括出瀏覽器渲染的全過程。

          廢話不多說,直接上圖


          渲染流程圖


          1. 渲染進程收到HTML 文檔后,遍歷文檔節點并轉換為能夠讀懂的DOM 樹結構;
          2. 渲染引擎將 CSS 樣式表轉化為瀏覽器可以理解的styleSheets對象,每一個對象都包含CSS規則。根據CSS規則對象計算出 DOM 節點的樣式;
          3. 創建渲染樹,并計算元素的布局信息。布局階段會從渲染樹的根節點開始遍歷,然后確定每個節點對象在頁面上的確切大小與位置,布局階段的輸出是一個盒子模型,它會精確地捕獲每個元素在屏幕內的確切位置與大小。對渲染樹進行分層,并生成分層樹。
          4. 為每個圖層生成繪制列表,并將其提交到合成線程。合成線程將圖層分成圖塊,并在光柵化線程池中將圖塊轉換成位圖。合成線程發送繪制圖塊命令DrawQuad給瀏覽器進程。
          5. 瀏覽器進程根據 DrawQuad 消息生成頁面,并顯示到顯示器上。

          寫到這里一定有很不少人好奇,為什么我們寫頁面時要把script標簽放在頁面最低部呢?

          別著急,答案就在下面。

          這就是前端小伙伴經常遇到的一個問題:渲染阻塞


          當瀏覽器遇到一個 script 標記時,DOM 構建將暫停,直至腳本完成執行,然后繼續構建DOM。每次去執行JavaScript腳本都會嚴重地阻塞DOM樹的構建,如果JavaScript腳本還操作了CSSOM,而正好這個CSSOM還沒有下載和構建,瀏覽器甚至會延遲腳本執行和構建DOM,直至完成其CSSOM的下載和構建。

          所以,script 標簽的位置很重要。實際使用時,可以遵循下面兩個原則:

          CSS 優先:引入順序上,CSS 資源先于 JavaScript 資源;
          JS置后:我們通常把JS代碼放到頁面底部,且JavaScript 應盡量少影響 DOM 的構建。


          現在終于知道我們使用script的時候經常將它置于頁面最底部的原因了。

          另外,這一點也是經常在前端面試題中看到它的身影。

          到這里瀏覽器渲染的全部流程已經講述完畢,如果還有疑問可以在下方留言,大家一起討論。

          有任何前端問題可以私信我,想了解更多前端知識關注公眾號“一郭鮮”,小郭等著你的到來


          主站蜘蛛池模板: 亚洲欧美成人一区二区三区| 精品一区二区三区影院在线午夜 | 国产一区二区三区在线| 午夜精品一区二区三区在线视 | 日韩精品无码免费一区二区三区 | 亚洲欧美日韩国产精品一区| 国产精品一区电影| 寂寞一区在线观看| 国产一区二区视频免费| 在线播放偷拍一区精品| 国产福利电影一区二区三区久久久久成人精品综合 | 自慰无码一区二区三区| 亚洲成av人片一区二区三区| 国产精品高清视亚洲一区二区| 国产裸体歌舞一区二区| 中文字幕在线观看一区二区| 国产一区韩国女主播| 国产一区二区在线观看视频| 四虎成人精品一区二区免费网站 | 久久一区二区三区精品| 国产精品一区12p| 国产一区二区三区精品视频 | 国内精品视频一区二区八戒| 福利国产微拍广场一区视频在线| 久久精品无码一区二区无码 | 亚洲一区二区三区91| 日本免费一区二区在线观看| 无码人妻精一区二区三区| 亚洲国产专区一区| 亚洲乱码国产一区三区| 成人一区专区在线观看| 亚洲精品精华液一区二区| 一区二区三区视频在线| 国产高清在线精品一区小说| 国产成人一区二区三区精品久久| 亚洲高清一区二区三区 | 呦系列视频一区二区三区| 中文字幕一区精品| 精品一区二区三区高清免费观看 | 无码国产精品一区二区免费式芒果 | 国产精品福利一区二区|