《瀏覽器工作原理》學(xué)習(xí)筆記

學(xué)習(xí)內(nèi)容來自于HTML5Rocks網(wǎng)站颊亮,《瀏覽器的工作原理:現(xiàn)代瀏覽器幕后揭秘》,簡(jiǎn)單輸入輸出一下讀后筆記陨溅。

解析

解析文檔是指將文檔轉(zhuǎn)化成有意義的結(jié)構(gòu)终惑,也就是可讓代碼理解和使用的結(jié)構(gòu)。

解析得到的結(jié)果通常是代表了文檔結(jié)構(gòu)的節(jié)點(diǎn)樹门扇,它稱作解析樹或者語(yǔ)法樹雹有。

HTML解析

HTML語(yǔ)法定義

常規(guī)解析器都不適用于HTML,HTML并不能很容易地用解析器所需的的上下文無關(guān)的語(yǔ)法來定義臼寄。

有一種可以定義HTML的正規(guī)格式:DTD(Document Type Definition霸奕,文檔類型定義),但它還是與上下文無關(guān)的語(yǔ)法吉拳。原因是HTML的語(yǔ)法處理很寬容质帅,允許省略某些隱匿添加的標(biāo)記,有時(shí)還能省略一些起始或者結(jié)束標(biāo)記等等留攒。

DOM

解析器輸出的“解析樹”是由DOM元素與屬性節(jié)點(diǎn)構(gòu)成的樹結(jié)構(gòu)煤惩。DOM是文檔對(duì)象模型(Document Object Model)的縮寫。它是HTML文檔的對(duì)象表示炼邀,同時(shí)也是外部?jī)?nèi)容與HTML元素之間的接口魄揉。

HTML5規(guī)范詳細(xì)地打描述了解析算法。此算法由兩個(gè)階段組成:標(biāo)記化和樹構(gòu)建拭宁。

![HTML解析流程][fig9]
[fig9]:http://1-ps.googleusercontent.com/x/s.html5rocks-hrd.appspot.com/www.html5rocks.com/zh/tutorials/internals/howbrowserswork/308x400ximage017.png.pagespeed.ic.BGy2jYmiQr.jpg "HTML5規(guī)范中的解析流程"

解析算法

我們?cè)谥罢鹿?jié)已經(jīng)說過什猖,HTML 無法用常規(guī)的自上而下或自下而上的解析器進(jìn)行解析票彪。

原因在于:

  • 語(yǔ)言的寬容本質(zhì)。
  • 瀏覽器歷來對(duì)一些常見的無效 HTML 用法采取包容態(tài)度不狮。
  • 解析過程需要不斷地反復(fù)。源內(nèi)容在解析過程中通常不會(huì)改變在旱,但是在 HTML 中摇零,腳本標(biāo)記如果包含 document.write,就會(huì)添加額外的標(biāo)記桶蝎,這樣解析過程實(shí)際上就更改了輸入內(nèi)容驻仅。

HTML的解析算法由兩個(gè)階段組成:標(biāo)記化和樹構(gòu)建

標(biāo)記化算法
<html>
    <body>
        Hello world
    </body>
</html>

初始狀態(tài)是數(shù)據(jù)狀態(tài),當(dāng)遇到字符<時(shí)登渣,狀態(tài)更改為“標(biāo)記打開狀態(tài)”噪服。接收一個(gè)a-z字符會(huì)創(chuàng)建“起始標(biāo)記”,狀態(tài)更改為“標(biāo)記名稱狀態(tài)”胜茧。這個(gè)狀態(tài)會(huì)一直保持到接收>粘优。在此期間接收的每個(gè)字符都會(huì)附加到新的標(biāo)記名稱上。在本例中呻顽,我們創(chuàng)建的標(biāo)記是html標(biāo)記雹顺。

遇到>標(biāo)記時(shí),會(huì)發(fā)送當(dāng)前的標(biāo)記廊遍,狀態(tài)發(fā)回“數(shù)據(jù)狀態(tài)”嬉愧。<body>標(biāo)記也會(huì)進(jìn)行同樣的處理。目前htmlbody標(biāo)記均已發(fā)出『砬埃現(xiàn)在我們回到“數(shù)據(jù)狀態(tài)”没酣。接收到Hello world中的H字符時(shí),將創(chuàng)建并發(fā)送字符標(biāo)記卵迂,直到接收</body>中的<裕便。我們將為Hello world中的每個(gè)字符都發(fā)送一個(gè)字符標(biāo)記。

現(xiàn)在我們回到“標(biāo)記打開狀態(tài)”狭握。接收下一個(gè)輸入字符/時(shí)闪金,會(huì)創(chuàng)建end tag token并改為“標(biāo)記名稱狀態(tài)”。我們會(huì)再次保持這個(gè)狀態(tài)论颅,直到接收>哎垦。然后將發(fā)送新的標(biāo)記,并回到“數(shù)據(jù)狀態(tài)”恃疯。</html>輸入也會(huì)進(jìn)行同樣的處理漏设。

標(biāo)記化算法
標(biāo)記化算法
樹構(gòu)建算法

樹構(gòu)建階段的輸入是一個(gè)來自標(biāo)記化階段的標(biāo)記序列。第一個(gè)模式是“initial mode”今妄。接收HTML標(biāo)記后轉(zhuǎn)為“before html”模式郑口,并在這個(gè)模式下重新處理此標(biāo)記鸳碧。這樣會(huì)創(chuàng)建一個(gè)HTMLHtmlElement元素,并獎(jiǎng)其附加到Document根對(duì)象上犬性。

后續(xù)狀態(tài):

  1. “before head”瞻离,接收“body”標(biāo)記,創(chuàng)建HTMLHeadElement乒裆,添加到樹中套利。
  2. “in head”模式,然后轉(zhuǎn)入“after head”模式鹤耍。創(chuàng)建并插入HTMLBodyElement肉迫,然后模式轉(zhuǎn)變?yōu)?strong>“body”。
  3. 接收body中的字符串稿黄,然后創(chuàng)建并插入“text”節(jié)點(diǎn)喊衫,其他字符也將附加到該節(jié)點(diǎn)
  4. 接收body結(jié)束標(biāo)記,觸發(fā)after body模式杆怕,接收剩余的HTML結(jié)束標(biāo)記族购。解析過程結(jié)束。
樹構(gòu)建算法
樹構(gòu)建算法

解析結(jié)束后的操作

文檔標(biāo)記為交互狀態(tài)财著,可以解析處于“deferred”模式的腳本联四。

瀏覽器容錯(cuò)機(jī)制

瀏覽器會(huì)糾正任何無效內(nèi)容,然后繼續(xù)工作撑教。Webkit在HTML解析器類的形狀注釋中對(duì)此做了相應(yīng)的概括:

解析器對(duì)標(biāo)記化輸入內(nèi)容進(jìn)行解析朝墩,以構(gòu)建文檔樹。如果文檔的格式正確伟姐,就直接進(jìn)行解析收苏。遺憾的是,我們不得不處理很多格式錯(cuò)誤的 HTML 文檔愤兵,所以解析器必須具備一定的容錯(cuò)性鹿霸。

我們至少要能夠處理以下錯(cuò)誤情況:

  1. 明顯不能在某些外部標(biāo)記中添加的元素。在此情況下秆乳,我們應(yīng)該關(guān)閉所有標(biāo)記懦鼠,直到出現(xiàn)禁止添加的元素,然后再加入該元素屹堰。
  2. 我們不能直接添加的元素肛冶。這很可能是網(wǎng)頁(yè)作者忘記添加了其中的一些標(biāo)記(或者其中的標(biāo)記是可選的)。這些標(biāo)簽可能包括:HTML HEAD BODY TBODY TR TD LI(還有遺漏的嗎扯键?)睦袖。
  3. 向 inline 元素內(nèi)添加 block 元素。關(guān)閉所有 inline 元素荣刑,直到出現(xiàn)下一個(gè)較高級(jí)的 block 元素馅笙。
  4. 如果這樣仍然無效伦乔,可關(guān)閉所有元素,直到可以添加元素為止董习,或者忽略該標(biāo)記烈和。

CSS解析

詞法語(yǔ)法(詞匯)是針對(duì)各個(gè)標(biāo)記用正則表達(dá)式定義的:

comment   \/\*[^*]*\*+([^/*][^*]*\*+)*\/
num   [0-9]+|[0-9]*"."[0-9]+
nonascii  [\200-\377]
nmstart   [_a-z]|{nonascii}|{escape}
nmchar    [_a-z0-9-]|{nonascii}|{escape}
name    {nmchar}+
ident   {nmstart}{nmchar}*

語(yǔ)法是采用BNF格式描述的。什么是BNF格式皿淋?豆瓣里面有解釋斥杜。

Webkit CSS 解析器

Webkit CSS解析
Webkit CSS解析

呈現(xiàn)樹構(gòu)建(Render Tree)

在 DOM 樹構(gòu)建的同時(shí),瀏覽器還會(huì)構(gòu)建另一個(gè)樹結(jié)構(gòu):呈現(xiàn)樹沥匈。這是由可視化元素按照其顯示順序而組成的樹,也是文檔的可視化表示忘渔。它的作用是讓您按照正確的順序繪制內(nèi)容高帖。

在Webkit中,如果一個(gè)元素需要?jiǎng)?chuàng)建特殊的呈現(xiàn)器畦粮,就會(huì)替換createRenderer方法散址。呈現(xiàn)器所指向的樣式對(duì)象中包含了一些和幾何無關(guān)的信息。

呈現(xiàn)樹與DOM樹的關(guān)系

呈現(xiàn)樹與DOM樹的關(guān)系
呈現(xiàn)樹與DOM樹的關(guān)系

樣式計(jì)算

共享樣式數(shù)據(jù)

Webkit 節(jié)點(diǎn)會(huì)引用樣式對(duì)象 (RenderStyle)宣赔。這些對(duì)象在某些情況下可以由不同節(jié)點(diǎn)共享预麸。這些節(jié)點(diǎn)是同級(jí)關(guān)系,并且:

  • 這些元素必須處于相同的鼠標(biāo)狀態(tài)(例如儒将,不允許其中一個(gè)是“:hover”狀態(tài)吏祸,而另一個(gè)不是)
  • 任何元素都沒有 ID
  • 標(biāo)記名稱應(yīng)匹配
  • 類屬性應(yīng)匹配
  • 映射屬性的集合必須是完全相同的
  • 鏈接狀態(tài)必須匹配
  • 焦點(diǎn)狀態(tài)必須匹配
  • 任何元素都不應(yīng)受屬性選擇器的影響,這里所說的“影響”是指在選擇器中的任何位置有任何使用了屬性選擇器的選擇器匹配
  • 元素中不能有任何 inline 樣式屬性
  • 不能使用任何同級(jí)選擇器钩蚊。WebCore 在遇到任何同級(jí)選擇器時(shí)贡翘,只會(huì)引發(fā)一個(gè)全局開關(guān),并停用整個(gè)文檔的樣式共享(如果存在)砰逻。這包括 + 選擇器以及 :first-child 和 :last-child 等選擇器鸣驱。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蝠咆,隨后出現(xiàn)的幾起案子踊东,更是在濱河造成了極大的恐慌,老刑警劉巖刚操,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闸翅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡赡茸,警方通過查閱死者的電腦和手機(jī)缎脾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來占卧,“玉大人遗菠,你說我怎么就攤上這事联喘。” “怎么了辙纬?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵豁遭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我贺拣,道長(zhǎng)蓖谢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任譬涡,我火速辦了婚禮闪幽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涡匀。我一直安慰自己盯腌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布陨瘩。 她就那樣靜靜地躺著腕够,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舌劳。 梳的紋絲不亂的頭發(fā)上帚湘,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音甚淡,去河邊找鬼大诸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛材诽,可吹牛的內(nèi)容都是我干的底挫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼脸侥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼建邓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睁枕,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤官边,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后外遇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體注簿,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年跳仿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诡渴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡菲语,死狀恐怖妄辩,靈堂內(nèi)的尸體忽然破棺而出惑灵,到底是詐尸還是另有隱情,我是刑警寧澤眼耀,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布英支,位于F島的核電站,受9級(jí)特大地震影響哮伟,放射性物質(zhì)發(fā)生泄漏干花。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一楞黄、第九天 我趴在偏房一處隱蔽的房頂上張望池凄。 院中可真熱鬧,春花似錦鬼廓、人聲如沸修赞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至勾邦,卻和暖如春蚣录,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背眷篇。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工萎河, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蕉饼。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓虐杯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親昧港。 傳聞我的和親對(duì)象是個(gè)殘疾皇子擎椰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容