日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
瀏覽器的渲染原理簡(jiǎn)介

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

在西峽等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站建設(shè),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,成都全網(wǎng)營(yíng)銷,成都外貿(mào)網(wǎng)站制作,西峽網(wǎng)站建設(shè)費(fèi)用合理。

  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++的類對(duì)應(yīng)這三類文檔。解析這三種文件會(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.     Web page parsing
  2.     
  3.         

    Web page parsing

  4.         

    This is an example Web page.

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

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

    CSS解析

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

     
     
     
     
    1. A few quotes
    2.   Franklin said that "A penny saved is a penny earned."
    3.   FDR said "We have nothing to fear but fear itself."

    于是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ò)渡層疊下去,……

    #p#

    通過(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)上了。

    渲染

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

    計(jì)算CSS樣式

    構(gòu)建Render Tree

    Layout – 定位坐標(biāo)和大小,是否換行,各種position, overflow, z-index屬性 ……

    正式開(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ì)從這個(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)?滾屏也有可能會(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.  
    3. bstyle.padding = "20px"; // reflow, repaint
    4. bstyle.border = "10px solid red"; //  再一次的 reflow 和 repaint
    5.  
    6. bstyle.color = "blue"; // repaint
    7. bstyle.backgroundColor = "#fad"; // repaint
    8.  
    9. bstyle.fontSize = "2em"; // reflow, repaint
    10.  
    11. // new DOM element - reflow, repaint
    12. 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。

    #p#

    但是有些時(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。

    減少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.  
    7. // Good
    8. el.className += " theclassname";
    9.  
    10. // Good
    11. 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的重新布局。

    幾個(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的東東。
    • Firefox下這個(gè)基于Firebug的叫Firebug Paint Events的插件也不錯(cuò)。
    • IE下你可以用一個(gè)叫dynaTrace的IE擴(kuò)展。

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

    • Google – Web Performance Best Practices
    • Yahoo – Best Practices for Speeding Up Your Web Site
    • Steve Souders – 14 Rules for Faster-Loading Web Sites

    網(wǎng)頁(yè)題目:瀏覽器的渲染原理簡(jiǎn)介
    本文路徑:http://www.dlmjj.cn/article/djdoidj.html