国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

瀏覽器的渲染原理簡(jiǎn)介

系統(tǒng) 瀏覽器
《How Browsers Work》,這篇文章把瀏覽器的很多細(xì)節(jié)講得很細(xì),而且也被翻譯成了中文。 但是,這篇文章太長(zhǎng)了,閱讀成本太大,不能一口氣讀完,而且似乎對(duì)工作沒(méi)什么幫助。本文主要是解決這兩個(gè)難題。

看到這個(gè)標(biāo)題大家一定會(huì)想到這篇神文《How Browsers Work》,這篇文章把瀏覽器的很多細(xì)節(jié)講得很細(xì),而且也被翻譯成了中文。為什么我還想寫(xiě)一篇呢?因?yàn)閮蓚€(gè)原因,

1)這篇文章太長(zhǎng)了,閱讀成本太大,不能一口氣讀完。

2)花了大力氣讀了這篇文章后可以了解很多,但似乎對(duì)工作沒(méi)什么幫助。

所以,我準(zhǔn)備寫(xiě)下這篇文章來(lái)解決上述兩個(gè)問(wèn)題。希望你能在上班途中,或是坐馬桶時(shí)就能讀完,并能從中學(xué)會(huì)一些能用在工作上的東西。

瀏覽器工作大流程

廢話少說(shuō),先來(lái)看個(gè)圖:

從上面這個(gè)圖中,我們可以看到那么幾個(gè)事:

 

1)瀏覽器會(huì)解析三個(gè)東西:

  • 一個(gè)是HTML/SVG/XHTML,事實(shí)上,Webkit有三個(gè)C++的類(lèi)對(duì)應(yīng)這三類(lèi)文檔。解析這三種文件會(huì)產(chǎn)生一個(gè)DOM Tree。
  • CSS,解析CSS會(huì)產(chǎn)生CSS規(guī)則樹(shù)。
  • Javascript,腳本,主要是通過(guò)DOM API和CSSOM API來(lái)操作DOM Tree和CSS Rule Tree.

2)解析完成后,瀏覽器引擎會(huì)通過(guò)DOM Tree 和 CSS Rule Tree 來(lái)構(gòu)造 Rendering Tree。注意:

  • Rendering Tree 渲染樹(shù)并不等同于DOM樹(shù),因?yàn)橐恍┫馠eader或display:none的東西就沒(méi)必要放在渲染樹(shù)中了。
  • CSS 的 Rule Tree主要是為了完成匹配并把CSS Rule附加上Rendering Tree上的每個(gè)Element。也就是DOM結(jié)點(diǎn)。也就是所謂的Frame。
  • 然后,計(jì)算每個(gè)Frame(也就是每個(gè)Element)的位置,這又叫l(wèi)ayout和reflow過(guò)程。

3)最后通過(guò)調(diào)用操作系統(tǒng)Native GUI的API繪制。

DOM解析

HTML的DOM Tree解析如下:

  1. <html> 
  2. <html> 
  3. <head> 
  4.     <title>Web page parsing</title> 
  5. </head> 
  6. <body> 
  7.     <p> 
  8.         <h1>Web page parsing</h1> 
  9.         <p>This is an example Web page.</p> 
  10.     </p> 
  11. </body> 
  12. </html> 

上面這段HTML會(huì)解析成這樣:

下面是另一個(gè)有SVG標(biāo)簽的情況。

#p#

CSS解析

CSS的解析大概是下面這個(gè)樣子(下面主要說(shuō)的是Gecko也就是Firefox的玩法),假設(shè)我們有下面的HTML文檔:

  1. <doc> 
  2. <title>A few quotes</title> 
  3. <para> 
  4.   Franklin said that <quote>"A penny saved is a penny earned."</quote> 
  5. </para> 
  6. <para> 
  7.   FDR said <quote>"We have nothing to fear but <span>fear itself.</span>"</quote> 
  8. </para> 
  9. </doc> 

于是DOM Tree是這個(gè)樣子:

然后我們的CSS文檔是這樣的:

  1. /* rule 1 */ doc { display: block; text-indent: 1em; } 
  2. /* rule 2 */ title { display: block; font-size: 3em; } 
  3. /* rule 3 */ para { display: block; } 
  4. /* rule 4 */ [class="emph"] { font-style: italic; } 

于是我們的CSS Rule Tree會(huì)是這個(gè)樣子:

注意,圖中的第4條規(guī)則出現(xiàn)了兩次,一次是獨(dú)立的,一次是在規(guī)則3的子結(jié)點(diǎn)。所以,我們可以知道,建立CSS Rule Tree是需要比照著DOM Tree來(lái)的。CSS匹配DOM Tree主要是從右到左解析CSS的Selector,好多人以為這個(gè)事會(huì)比較快,其實(shí)并不一定。關(guān)鍵還看我們的CSS的Selector怎么寫(xiě)了。

注意:CSS匹配HTML元素是一個(gè)相當(dāng)復(fù)雜和有性能問(wèn)題的事情。所以,你就會(huì)在N多地方看到很多人都告訴你,DOM樹(shù)要小,CSS盡量用id和class,千萬(wàn)不要過(guò)渡層疊下去,……

通過(guò)這兩個(gè)樹(shù),我們可以得到一個(gè)叫Style Context Tree,也就是下面這樣(把CSS Rule結(jié)點(diǎn)Attach到DOM Tree上):

所以,F(xiàn)irefox基本上來(lái)說(shuō)是通過(guò)CSS 解析 生成 CSS Rule Tree,然后,通過(guò)比對(duì)DOM生成Style Context Tree,然后Firefox通過(guò)把Style Context Tree和其Render Tree(Frame Tree)關(guān)聯(lián)上,就完成了。注意:Render Tree會(huì)把一些不可見(jiàn)的結(jié)點(diǎn)去除掉。而Firefox中所謂的Frame就是一個(gè)DOM結(jié)點(diǎn),不要被其名字所迷惑了。

注:Webkit不像Firefox要用兩個(gè)樹(shù)來(lái)干這個(gè),Webkit也有Style對(duì)象,它直接把這個(gè)Style對(duì)象存在了相應(yīng)的DOM結(jié)點(diǎn)上了。#p#

渲染

渲染的流程基本上如下(黃色的四個(gè)步驟):

  1. 計(jì)算CSS樣式
  2. 構(gòu)建Render Tree
  3. Layout – 定位坐標(biāo)和大小,是否換行,各種position, overflow, z-index屬性 ……
  4. 正式開(kāi)畫(huà)

注意:上圖流程中有很多連接線,這表示了Javascript動(dòng)態(tài)修改了DOM屬性或是CSS屬會(huì)導(dǎo)致重新Layout,有些改變不會(huì),就是那些指到天上的箭頭,比如,修改后的CSS rule沒(méi)有被匹配到,等。

這里重要要說(shuō)兩個(gè)概念,一個(gè)是Reflow,另一個(gè)是Repaint。這兩個(gè)不是一回事。

  • Repaint——屏幕的一部分要重畫(huà),比如某個(gè)CSS的背景色變了。但是元素的幾何尺寸沒(méi)有變。
  • Reflow——意味著元件的幾何尺寸變了,我們需要重新驗(yàn)證并計(jì)算Render Tree。是Render Tree的一部分或全部發(fā)生了變化。這就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的幾何尺寸發(fā)生了變化,需要重新布局,也就叫reflow)reflow 會(huì)從<html>這個(gè)root frame開(kāi)始遞歸往下,依次計(jì)算所有的結(jié)點(diǎn)幾何尺寸和位置,在reflow過(guò)程中,可能會(huì)增加一些frame,比如一個(gè)文本字符串必需被包裝起來(lái)。

下面是一個(gè)打開(kāi)Wikipedia時(shí)的Layout/reflow的視頻(注:HTML在初始化的時(shí)候也會(huì)做一次reflow,叫intial reflow),你可以感受一下:

Reflow的成本比Repaint的成本高得多的多。DOM Tree里的每個(gè)結(jié)點(diǎn)都會(huì)有reflow方法,一個(gè)結(jié)點(diǎn)的reflow很有可能導(dǎo)致子結(jié)點(diǎn),甚至父點(diǎn)以及同級(jí)結(jié)點(diǎn)的reflow。在一些高性能的電腦上也許還沒(méi)什么,但是如果reflow發(fā)生在手機(jī)上,那么這個(gè)過(guò)程是非常痛苦和耗電的。

所以,下面這些動(dòng)作有很大可能會(huì)是成本比較高的。

  • 當(dāng)你增加、刪除、修改DOM結(jié)點(diǎn)時(shí),會(huì)導(dǎo)致Reflow或Repaint
  • 當(dāng)你移動(dòng)DOM的位置,或是搞個(gè)動(dòng)畫(huà)的時(shí)候。
  • 當(dāng)你修改CSS樣式的時(shí)候。
  • 當(dāng)你Resize窗口的時(shí)候(移動(dòng)端沒(méi)有這個(gè)問(wèn)題),或是滾動(dòng)的時(shí)候。
  • 當(dāng)你修改網(wǎng)頁(yè)的默認(rèn)字體時(shí)。

注:display:none會(huì)觸發(fā)reflow,而visibility:hidden只會(huì)觸發(fā)repaint,因?yàn)闆](méi)有發(fā)現(xiàn)位置變化。

多說(shuō)兩句關(guān)于滾屏的事,通常來(lái)說(shuō),如果在滾屏的時(shí)候,我們的頁(yè)面上的所有的像素都會(huì)跟著滾動(dòng),那么性能上沒(méi)什么問(wèn)題,因?yàn)槲覀兊娘@卡對(duì)于這種把全屏像素往上往下移的算法是很快。但是如果你有一個(gè)fixed的背景圖,或是有些Element不跟著滾動(dòng),有些Elment是動(dòng)畫(huà),那么這個(gè)滾動(dòng)的動(dòng)作對(duì)于瀏覽器來(lái)說(shuō)會(huì)是相當(dāng)相當(dāng)痛苦的一個(gè)過(guò)程。你可以看到很多這樣的網(wǎng)頁(yè)在滾動(dòng)的時(shí)候性能有多差。因?yàn)闈L屏也有可能會(huì)造成reflow。

基本上來(lái)說(shuō),reflow有如下的幾個(gè)原因:

  • Initial。網(wǎng)頁(yè)初始化的時(shí)候。
  • Incremental。一些Javascript在操作DOM Tree時(shí)。
  • Resize。其些元件的尺寸變了。
  • StyleChange。如果CSS的屬性發(fā)生變化了。
  • Dirty。幾個(gè)Incremental的reflow發(fā)生在同一個(gè)frame的子樹(shù)上。

好了,我們來(lái)看一個(gè)示例吧:

  1. var bstyle = document.body.style; // cache 
  2. bstyle.padding = "20px"; // reflow, repaint 
  3. bstyle.border = "10px solid red"; //  再一次的 reflow 和 repaint  
  4. bstyle.color = "blue"; // repaint 
  5. bstyle.backgroundColor = "#fad"; // repaint  
  6. bstyle.fontSize = "2em"; // reflow, repaint 
  7. // new DOM element - reflow, repaint 
  8. document.body.appendChild(document.createTextNode('dude!')); 

當(dāng)然,我們的瀏覽器是聰明的,它不會(huì)像上面那樣,你每改一次樣式,它就reflow或repaint一次。一般來(lái)說(shuō),瀏覽器會(huì)把這樣的操作積攢一批,然后做一次reflow,這又叫異步reflow或增量異步reflow。但是有些情況瀏覽器是不會(huì)這么做的,比如:resize窗口,改變了頁(yè)面默認(rèn)的字體,等。對(duì)于這些操作,瀏覽器會(huì)馬上進(jìn)行reflow。

但是有些時(shí)候,我們的腳本會(huì)阻止瀏覽器這么干,比如:如果我們請(qǐng)求下面的一些DOM值:

  1. offsetTop, offsetLeft, offsetWidth, offsetHeight
  2. scrollTop/Left/Width/Height
  3. clientTop/Left/Width/Height
  4. IE中的 getComputedStyle(), 或 currentStyle

因?yàn)椋绻覀兊某绦蛐枰@些值,那么瀏覽器需要返回最新的值,而這樣一樣會(huì)flush出去一些樣式的改變,從而造成頻繁的reflow/repaint。#p#

減少reflow/repaint

下面是一些Best Practices:

1)不要一條一條地修改DOM的樣式。與其這樣,還不如預(yù)先定義好css的class,然后修改DOM的className。

  1. // bad 
  2. var left = 10
  3. top = 10
  4. el.style.left = left + "px"; 
  5. el.style.top  = top  + "px"; 
  6. // Good 
  7. el.className += " theclassname"; 
  8.  // Good 
  9. el.style.cssText += "; left: " + left + "px; top: " + top + "px;"; 

2)把DOM離線后修改。如:

  • 使用documentFragment 對(duì)象在內(nèi)存里操作DOM
  • 先把DOM給display:none(有一次reflow),然后你想怎么改就怎么改。比如修改100次,然后再把他顯示出來(lái)。
  • clone一個(gè)DOM結(jié)點(diǎn)到內(nèi)存里,然后想怎么改就怎么改,改完后,和在線的那個(gè)的交換一下。

3)不要把DOM結(jié)點(diǎn)的屬性值放在一個(gè)循環(huán)里當(dāng)成循環(huán)里的變量。不然這會(huì)導(dǎo)致大量地讀寫(xiě)這個(gè)結(jié)點(diǎn)的屬性。

4)盡可能的修改層級(jí)比較低的DOM。當(dāng)然,改變層級(jí)比較底的DOM有可能會(huì)造成大面積的reflow,但是也可能影響范圍很小。

5)為動(dòng)畫(huà)的HTML元件使用fixed或absoult的position,那么修改他們的CSS是不會(huì)reflow的。

6)千萬(wàn)不要使用table布局。因?yàn)榭赡芎苄〉囊粋€(gè)小改動(dòng)會(huì)造成整個(gè)table的重新布局。

In this manner, the user agent can begin to lay out the table once the entire first row has been received. Cells in subsequent rows do not affect column widths. Any cell that has content that overflows uses the ‘overflow’ property to determine whether to clip the overflow content.

Fixed layout, CSS 2.1 Specification

This algorithm may be inefficient since it requires the user agent to have access to all the content in the table before determining the final layout and may demand more than one pass.

Automatic layout, CSS 2.1 Specification

幾個(gè)工具和幾篇文章

有時(shí)候,你會(huì)也許會(huì)發(fā)現(xiàn)在IE下,你不知道你修改了什么東西,結(jié)果CPU一下子就上去了到100%,然后過(guò)了好幾秒鐘repaint/reflow才完成,這種事情以IE的年代時(shí)經(jīng)常發(fā)生。所以,我們需要一些工具幫我們看看我們的代碼里有沒(méi)有什么不合適的東西。

  • Chrome下,Google的SpeedTracer是個(gè)非常強(qiáng)悍的工作讓你看看你的瀏覽渲染的成本有多大。其實(shí)Safari和Chrome都可以使用開(kāi)發(fā)者工具里的一個(gè)Timeline的東東。
  • IE下你可以用一個(gè)叫dynaTrace的IE擴(kuò)展。

最后,別忘了下面這幾篇提高瀏覽器性能的文章:

參考

責(zé)任編輯:黃丹 來(lái)源: coolshell.cn
相關(guān)推薦

2013-06-14 13:56:29

瀏覽器渲染原理

2020-11-06 15:20:45

瀏覽器前端架構(gòu)

2022-08-30 09:01:11

瀏覽器渲染前端

2013-11-18 14:42:53

瀏覽器渲染

2012-03-20 11:35:32

傲游手機(jī)瀏覽器

2017-03-08 08:31:48

瀏覽器渲染路徑

2013-11-20 10:47:57

瀏覽器渲染html

2017-03-12 10:15:18

瀏覽器DOM樹(shù)CSSOM樹(shù)

2013-11-20 13:04:41

css瀏覽器渲染

2013-11-20 13:47:43

瀏覽器渲染引擎

2017-10-09 13:39:26

瀏覽器渲染服務(wù)器

2018-01-19 14:39:53

瀏覽器頁(yè)面優(yōu)化

2019-01-03 13:09:58

瀏覽器緩存原理

2013-11-18 15:09:34

瀏覽器渲染速度

2022-02-07 21:49:06

瀏覽器渲染chromium

2021-04-19 11:40:15

瀏覽器路徑

2020-03-12 11:29:51

JavaScript瀏覽器語(yǔ)言

2015-02-28 09:39:24

Windows 10Spartan

2021-04-01 06:23:24

CSS33D3D Web 動(dòng)畫(huà)

2019-04-08 10:27:00

渲染瀏覽器DOM
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

丝袜美腿亚洲一区二区| 无码专区aaaaaa免费视频| 奇米一区二区| 欧美麻豆精品久久久久久| 在线免费观看av的网站| 福利电影一区二区三区| 一区二区三区在线观看www| 日韩天堂av| 亚洲综合日韩在线| 日本a级不卡| 国产91热爆ts人妖在线| 女人抽搐喷水高潮国产精品| 欧美华人在线视频| 亚洲欧洲一二区| 亚洲视频欧美视频| 亚洲精品成人图区| 亚洲美女在线看| 日韩伦理精品| 亚洲精品一区中文| 欧美精品高清| 欧美www在线| 超碰97久久| 日韩av电影在线网| 日韩久久精品网| 999视频在线免费观看| 欧美大片一区| 久久精品ww人人做人人爽| 在线亚洲一区| 亚洲精品国产系列| 国产成人精品网址| 国产成人手机视频| 亚洲免费av在线| 视频在线不卡| 4438亚洲最大| www.精品| 美女精品久久久| 综合干狼人综合首页| 国产精品美女午夜av| 亚洲成av人电影| 欧美午夜精品理论片a级大开眼界| 久久99精品久久久久久动态图| 国产欧美123| 国产精品毛片无遮挡高清| 嫩草影院永久入口| 一本色道久久加勒比精品| 中文字幕在线观看日本| 日韩av在线网址| 精品亚洲免a| 国产视色精品亚洲一区二区| 久久成人免费电影| 一区二区三区 日韩| 欧美综合在线视频| 久久xxx视频| 国产精品美女免费视频| 奇米综合一区二区三区精品视频| 18禁网站免费无遮挡无码中文| 日韩美女久久久| 日本亚洲精品| 美女撒尿一区二区三区| 欧美激情aⅴ一区二区三区| 亚洲第一精品区| 一区二区三区免费| av资源在线| 国产mv久久久| 欧美aaa在线| 免费在线黄色av| 亚洲女在线观看| 青青草国产免费一区二区下载| 亚洲无玛一区| 亚洲一二三四在线观看| 老司机深夜福利在线观看| 欧美自拍视频在线观看| 日本一不卡视频| 日本福利视频| 亚洲欧洲日产国码av系列天堂 | 国产人久久人人人人爽| 日本在线视频1区| 亚洲最新av在线| 在线观看国产精品入口| 日韩欧美国产免费| 色999日韩国产欧美一区二区| 亚洲青青久久| 日韩福利一区二区三区| 亚洲精品日产精品乱码不卡| 毛片在线网址| 亚洲资源在线看| 中文字幕av一区二区三区| sm捆绑调教国产免费网站在线观看| 国产精品视频网址| 久久久久亚洲蜜桃| 2021中文字幕在线| 亚洲xxxxx电影| 欧美国产丝袜视频| videos性欧美另类高清| 久久99久久99精品蜜柚传媒| 一区二区三区欧美日| 欧美高清影院| 视频一区三区| 色域天天综合网| 国产欧美日韩| 超碰在线公开97| 中文字幕一精品亚洲无线一区 | 99riav在线| 国产精品aaa| 久久丝袜美腿综合| 男女羞羞视频在线观看| 91九色蝌蚪嫩草| 亚洲视频在线一区| 国产精品2区| av一区二区三区免费观看| 日韩精品自拍偷拍| 欧美成人69| 三级在线播放| 国产精品一区二区在线| 亚洲免费在线视频| 国产精品45p| 在线观看亚洲色图| 欧美人在线观看| 国产亚洲自拍一区| 视频在线亚洲| 少妇激情一区二区三区| 久久精品国产亚洲一区二区 | 一级毛片精品毛片| 91成人在线观看喷潮教学| 精品亚洲夜色av98在线观看| 日本欧美大码aⅴ在线播放| 成人午夜在线影视| 欧美午夜精品久久久久久蜜| 欧美一区二区在线观看| 久久精品女人| 污污的网站在线免费观看| 欧美性天天影院| 日韩精品最新网址| 激情久久五月天| 成人福利片在线| 亚洲美免无码中文字幕在线| 欧美大肥婆大肥bbbbb| 久久久久久**毛片大全| 国产区一区二| 66av99| 欧洲一区二区视频| 亚洲精品国产a| 日韩在线二区| 国产二区视频在线观看| 精品在线观看一区二区| 欧美精品一区二区久久婷婷| 国产在线日韩欧美| 久久久91麻豆精品国产一区| av网站免费| 成人福利在线观看| 制服丝袜成人动漫| 国产精品一区二区免费不卡| 综合久草视频| 免费观看羞羞视频网站| 国内精品一区二区| 亚洲人成网站色ww在线| 国产三级精品三级在线专区| 日本久久综合| 少女频道在线观看高清 | 欧美激情精品久久久久| 亚洲欧美日韩在线| 伊人久久成人| 欧美日韩国产v| youjizzxxxx18| 国产欧美日韩免费看aⅴ视频| 欧美三级视频在线| 九九热在线视频观看这里只有精品| 国产精品99| 一个人看的www一区| 日本一区二区三区四区在线观看 | 国产精品99| 黄色直播在线| 色噜噜狠狠色综合网| 日韩性xxxx爱| 精品日韩视频在线观看| 免费不卡在线观看| 日韩高清成人在线| 伊人影院在线视频| 国产三级三级三级看三级| 91久久久久久久一区二区| 亚洲第一页中文字幕| 国产精品卡一卡二卡三| 一区二区三区国产盗摄| 免费看一区二区三区| 国产精品一区在线看| 成人午夜免费在线| 亚洲精品欧美日韩专区| 中文字幕精品国产| 日韩欧美一区视频| av一区二区三区黑人| 亚洲视频电影在线| jizzjizz少妇亚洲水多| 污视频网站在线| 成人在线观看你懂的| 91免费国产视频| 久久久国产视频91| 欧美一卡二卡三卡四卡| 亚洲免费在线视频一区 二区| 狠狠色丁香久久婷婷综| 欧美好骚综合网|