瀏覽器渲染原理與過程

一、瀏覽器如何渲染網頁

要了解瀏覽器渲染頁面的過程,首先得知道一個名詞——關鍵路徑渲染。關鍵渲染路徑(Critical Rendering Path)是指與當前用戶操作有關的內容。例如用戶在瀏覽器中打開一個頁面,其中頁面所顯示的東西就是當前用戶操作相關的內容,也就是瀏覽器從服務器那收到的HTML,CSS,JavaScript等相關資源,然后經過一系列處理后渲染出來的web頁面。

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

  • 瀏覽器將獲取的HTML文檔并解析成DOM樹。

  • 處理CSS標記,構成層疊樣式表模型CSSOM(CSS Object Model)。

  • 將DOM和CSSOM合并為渲染樹(rendering tree)將會被創建,代表一系列將被渲染的對象。

  • 渲染樹的每個元素包含的內容都是計算過的,它被稱之為布局layout。瀏覽器使用一種流式處理的方法,只需要一次pass繪制操作就可以布局所有的元素。

  • 將渲染樹的各個節點繪制到屏幕上,這一步被稱為繪制painting.

具體如下圖過程如下圖所示:

Webkit

需要注意的是,以上五個步驟并不一定一次性順序完成,比如DOM或CSSOM被修改時,亦或是哪個過程會重復執行,這樣才能計算出哪些像素需要在屏幕上進行重新渲染。而在實際情況中,JavaScript和CSS的某些操作往往會多次修改DOM或者CSSOM。

下面我們就來詳細的了解一下這幾個過程及需要注意的事項。

二、瀏覽器渲染網頁的具體流程

2.1 構建DOM樹

當瀏覽器客戶端從服務器那接受到HTML文檔后,就會遍歷文檔節點然后生成DOM樹,DOM樹結構和HTML標簽一一對應。需要注意記下幾點:

  1. DOM樹在構建的過程中可能會被CSS和JS的加載而執行阻塞。(這在后面會詳細介紹。)

  2. display:none 的元素也會在DOM樹中。

  3. 注釋也會在DOM樹中

  4. script標簽會在DOM樹中

2.2 CSS解析

瀏覽器會解析CSS文件并生成CSS規則樹,在過程中,每個CSS文件都會被分析成StyleSheet對象,每個對象都包括CSS規則,CSS規則對象包括對應的選擇器和聲明對象以及其他對象。
在這個過程需要注意的是:

  • CSS解析可以與DOM解析同進行。

  • CSS解析與script的執行互斥 。

  • 在Webkit內核中進行了script執行優化,只有在JS訪問CSS時才會發生互斥。

2.3 構建渲染樹(Rendr tree construction)

通過DOM樹和CSS規則樹,瀏覽器就可以通過它兩構建渲染樹了。瀏覽器會先從DOM樹的根節點開始遍歷每個可見節點,讓后對每個可見節點找到適配的CSS樣式規則并應用。具體的規則有以下幾點需要注意:

  • Render Tree和DOM Tree不完全對應。

  • display: none的元素不在Render Tree中

  • visibility: hidden的元素在Render Tree中

2.4 渲染樹布局(layout of the render tree)

布局階段會從渲染樹的更節點開始遍歷,由于渲染樹的每個節點都是一個Render Object對象,包含寬高,位置,背景色等樣式信息。所以瀏覽器就可以通過這些樣式信息來確定每個節點對象在頁面上的確切大小和位置,布局階段的輸出就是我們常說的盒子模型,它會精確地捕獲每個元素在屏幕內的確切位置與大小。需要注意的是:

  • float元素,absoulte元素,fixed元素會發生位置偏移。

  • 我們常說的脫離文檔流,其實就是脫離Render Tree。

2.5 渲染樹繪制(Painting the render tree)

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

三、瀏覽器渲染網頁的那些事兒

3.1 阻塞渲染

前面我們有提到這方面的問題,說到資源的阻塞我們清楚的是,現代瀏覽器總是并行加載自語言。例如當HTML解析器被腳本阻塞時,解析器雖然會停止構建DOM,但仍然會辨識該腳本后面的資源,并進行預加載。且由于以下兩點。瀏覽器會延遲 JavaScript 的執行和 DOM 構建:

  • CSS 被默認被視為阻塞渲染的資源,因此瀏覽器將在 CSSOM 構建完畢前不會渲染任何已處理的內容。

  • JavaScript 不僅可以讀取和修改 DOM 屬性,還可以讀取和修改 CSSOM 屬性,因此CSS解析與script的執行互斥。

正是由于以上這些原因,script標簽的位置很重要我們在實際開發中應該盡量堅持以下兩個原則:

  • 在引入順序上,CSS 資源先于 JavaScript 資源。

  • JavaScript 應盡量少的去影響 DOM 的構建。

3.2 回流和重繪(reflow和repaint)

我們都知道HTML默認是流式布局的,但CSS和JS會打破這種布局,改變DOM的外觀樣式以及大小和位置。因此我們就需要知道兩個概念:

  • reflow(回流):當瀏覽器發現某個部分發生了變化從而影響了布局,這個時候就需要倒回去重新渲染,大家稱這個回退的過程叫 reflow。 常見的reflow是一些會影響頁面布局的操作,諸如Tab,隱藏等。reflow 會從 html 這個 root frame 開始遞歸往下,依次計算所有的結點幾何尺寸和位置,以確認是渲染樹的一部分發生變化還是整個渲染樹。reflow幾乎是無法避免的,因為只要用戶進行交互操作,就勢必會發生頁面的一部分的重新渲染,且通常我們也無法預估瀏覽器到底會reflow哪一部分的代碼,因為他們會相互影響。

  • repaint(重繪): repaint則是當我們改變某個元素的背景色、文字顏色、邊框顏色等等不影響它周圍或內部布局的屬性時,屏幕的一部分要重畫,但是元素的幾何尺寸和位置沒有發生改變。

需要注意的是,display:none 會觸發 reflow,而visibility: hidden屬性則并不算是不可見屬性,它的語義是隱藏元素,但元素仍然占據著布局空間,它會被渲染成一個空框,這在我們上面有提到過。所以visibility:hidden 只會觸發 repaint,因為沒有發生位置變化。

我們不能避免reflow,但還是能通過一些操作來減少回流:

  1. 用transform做形變和位移.

  2. 通過絕對位移來脫離當前層疊上下文,形成新的Render Layer。

另外有些情況下,比如修改了元素的樣式,瀏覽器并不會立刻reflow 或 repaint 一次,而是會把這樣的操作積攢一批,然后做一次 reflow,這又叫異步 reflow 或增量異步 reflow。但是在有些情況下,比如resize 窗口,改變了頁面默認的字體等。對于這些操作,瀏覽器會馬上進行 reflow。

3.3 幾條關于優化渲染效率的建議

結合上文和我看到的一些文章,有以下幾點可以優化渲染效率

  1. 合法地去書寫 HTML 和 CSS ,且不要忘了文檔編碼類型。

  2. 樣式文件應當在 head 標簽中,而腳本文件在 body 結束前,這樣可以防止阻塞的方式。

  3. 簡化并優化CSS選擇器,盡量將嵌套層減少到最小。

  4. 盡量減少在 JavaScript 中進行DOM操作。

  5. 修改元素樣式時,更改其class屬性是性能最高的方法。

  6. 盡量用 transform 來做形變和位移

轉載于:https://www.cnblogs.com/guchengnan/p/10755950.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249080.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249080.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249080.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

css框架:五大css流行框架的總結-css教程-PHP中文網

本篇文章給大家帶來的內容是關于css框架:五大css流行框架的總結,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。 如今,CSS框架越來越受歡迎,可以說已經應用到每一個網站上了。作為開發工具…

第十四天

###數組:面向對象的方式創建:var arr01 new Array(1,2,3,"abc");直接創建:var arr02 [1,2,3,"abc"]alert (arr02.length);alert(arr02[3]);var arr03 [[1,2,3],["a","b","c","d&q…

【English Email】CIP payouts now in Workday

simplification簡化的[?s?mpl?f??ke??n] quota配額[?kwo?t?] regional區域的[?ri?d??nl] mechanics技工[m??kn?ks] annual年度的 [?nju?l] mid-year年中 [m?d j?r] bridge橋接[br?d?] Incentive激勵 [?n?sent?v] Due to the simplification of …

爬取網頁的通用代碼框架

import requests def getHTMLText(url)try:r requests.get(url,timeout30)r.raise_for_status()r.encoding r.apparent_encodingreturn r.textexcept:return "產生異常"if__name__ "__main__"url "http://www.baidu.com"print(getHTMLText(ur…

深入理解CSS盒模型 - 程序猿的程 - 博客園

深入理解CSS盒模型 本文是學習中傳思客在慕課網開的課程《前端跳槽面試必備技巧》的學習筆記。課程地址:https://coding.imooc.com/class/evaluation/129.html#Anchor。 如果你在面試的時候面試官讓你談談對盒模型的理解,你是不是不知從何談起。這種看似…

藍橋杯——機器人行走

某少年宮引進了一批機器人小車。可以接受預先輸入的指令,按指令行動。小車的基本動作很簡單,只有3種:左轉(記為L),右轉(記為R),向前走若干厘米(直接記數字&am…

JavaWeb:腳本標識

腳本標識 一、JSP表達式 1、介紹 用于向頁面中輸出信息 2、語法格式 <% 表達式%>3、注意 在"<%"和""之間不允許有空格&#xff0c;但是在""后面的表達式之間可以有空格不僅可以插入到網頁中&#xff0c;還可以插入到HTML標記中&#xf…

線程死鎖問題

1 package com.demo.bingfa;2 3 /**4 * java并發編程中&#xff0c;死鎖的概念5 *6 * 我們啟用了兩個線程&#xff0c;分別搶占2個資源&#xff0c;但這兩個資源又分別被不同的對象&#xff08;字符串&#xff09;鎖住了。7 * 當第一個線程調用 resource1 方法&#xff0c;…

CSS的4個簡寫

CSS的4個簡寫 2010-12-13 18:50 聶微東 閱讀(1547) 評論(3) 編輯 收藏 1.background 簡寫屬性在一個聲明中設置所有的背景屬性: background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 例如: background: #444444 url(image.png…

spring boot 整合 (全)

參考: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples轉載于:https://www.cnblogs.com/lshan/p/9924005.html

使用PM2搭建在線vue.js開發環境(以守護進程方式熱啟動)

項目以vue.jslayUI的作為前端開發技術棧&#xff0c;需要有一個在線的環境供項目成員實時查看效果&#xff0c;總不能每次都webpack打包發布后才能看到效果吧&#xff01;剛開始就簡單使用npm run dev命令熱啟動&#xff0c;但是shell命令窗口退出后&#xff0c;熱啟動也就失效…

微信小程序工具類

wechat-common-sdk ? 場景&#xff1a;目前工作中的項目需要包含并使用另一個項目。 也許是第三方庫&#xff0c;或者你獨立開發的&#xff0c;用于多個父項目的庫。 現在問題來了&#xff1a;你想要把它們當做兩個獨立的項目&#xff0c;同時又想在一個項目中使用另一個。 我…

zabbix實現mysql數據庫的監控

先來介紹zabbix中幾個常用的術語&#xff1a; 主機&#xff08;host&#xff09;&#xff1a; 要監控的網絡設備&#xff0c;可由ip或DNS名稱指定。 主機組&#xff08;host group&#xff09;&#xff1a; 主機的邏輯容器&#xff0c;可以包含主機和模板&#xff…

VSCode配合eslint進行JavaScript質量檢查

寫在開始前&#xff1a;如有不準確的地方希望大家提出&#xff0c;文章可以改知識不能錯。 創建一個項目 這里已node項目為例 npm init 根據提示填寫相關信息 安裝eslint npm install eslint --save也可以全局安裝 npm install eslint -g初始化 eslint文件 eslint --init執行命…

未找到導入的項目,請確認 Import 聲明中的路徑正確

VS2017打開以前vs版本開發的項目 <Import Project"$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project"$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\WebApplications\Microsoft.WebApplication.targets" /> 修改V12…

修改Jupyter的工作空間

修改Jupyter的工作空間 1、安裝Jupyter Notebook 剛安裝完并配置好Sublime Text 3后被學長推薦使用Jupyter notebook&#xff0c;于是就想著看看試試有沒有他說的那么好。 安裝&#xff1a;命令行直接pip install jupyter(前提是先安裝好了python和pip) 2、安裝完后困惑 這么大…

bzoj [Usaco2009 Hol]Cattle Bruisers 殺手游戲

Description Input 第1行輸入N&#xff0c;R&#xff0c;BX&#xff0c;BY, BVX&#xff0c;BVY&#xff0c;之后N行每行輸入四個整數Xi&#xff0c;Yi&#xff0c;VXi&#xff0c;VYi&#xff0e; Output 一個整數&#xff0c;表示在逃脫過程中&#xff0c;某一個時刻最多有這…

Visual Studio Code 使用 ESLint 增強代碼風格檢查 - gyzhao - 博客園

前言 在團隊協作開發中&#xff0c;為了統一代碼風格&#xff0c;避免一些低級錯誤&#xff0c;應該設有團隊成員統一遵守的編碼規范。很多語言都提供了Lint工具來實現這樣的功能&#xff0c;JavaScript也有類似的工具&#xff1a;ESLint。除了可以集成到構建工具中(如&#x…

CS 325 HW

代做CS 325作業、代寫C, C/Python編程設計作業、代做Python/c實驗作業CS 325 – HW 51. (6 points) Consider an undirected graph G(V,E) with nonnegative edge weights w(u,v)0. Supposethat you have computed a minimum spanning tree G, and that you have also computed…

express下使用ES6 - dtdxrk - 博客園

express下使用ES6 1 2 3 4 5 6 7 8 9 //環境切換配置 package.json scripts:{ "service": "NODE_ENVproduction PORT3000 npm start" } //node js判斷 var app express(); app.get(env) production 原文地址&#xff1a;https://segmentfault.com/a…