介紹:
瀏覽器可能是最常用的軟件之一了跺讯, 以下將會(huì)介紹當(dāng)你在地址欄輸入 'google.com' 后左胞,瀏覽器背后的故事担钮。
我們將會(huì)討論的瀏覽器:
主流瀏覽器的五大類:
Internet Explorer, Firefox, Safari, Chrome and Opera, 我將會(huì)解釋一些半開源的瀏覽器的工作方式:
Firefox,Chrome and Safari厚棵。根據(jù) W3C 的統(tǒng)計(jì)蕉世,這3中瀏覽器的使用已經(jīng)接近 60%.
瀏覽器的主要功能:
瀏覽器的主要功能是呈現(xiàn)你選擇的資源內(nèi)容,從服務(wù)器獲取資源并展現(xiàn)在瀏覽器中婆硬。 資源的主要形式是HTML, 或者 PDF 狠轻, 圖片或者其他的”蚍福客戶使用URI找到這些資源向楼。
瀏覽器按照W3C的規(guī)范解析HTML和CSS。但瀏覽器廠商僅僅實(shí)現(xiàn)了規(guī)范的一部分并增加了他們自己的擴(kuò)展谐区,這為開發(fā)者們?cè)斐闪瞬簧俚穆闊┖桑缃瘢蟛糠值臑g覽器廠商都會(huì)或多或少的遵守W3C的規(guī)范宋列。
瀏覽器的UI非常相似昭抒,大多都有如下功能:
- 地址欄用于URI的輸入
- 前進(jìn)和后退按鈕
- 書簽
- 刷新或停止加載
- 回到首頁(yè)按鈕
這非常奇怪,因?yàn)闉g覽器的UI并不是規(guī)范的一部分炼杖,這是經(jīng)年累月的用戶實(shí)踐造成的相似戈鲁。H5 的標(biāo)準(zhǔn)并沒有定義瀏覽器必須要有哪些UI元素,但列出了一些常用的UI元素:地址欄嘹叫、狀態(tài)欄和工具欄。當(dāng)然诈乒,也有一些比較特殊的功能比如Firefox的下載管理功能罩扇。
瀏覽器的主要結(jié)構(gòu):
UI。包括地址欄、前進(jìn)后退按鈕喂饥、書簽管理器等等消约,除了你用來看請(qǐng)求資源的窗口以外的其他,都算是瀏覽器的UI员帮。
browser engine 或粮。 用于查詢和操作渲染引擎。 rendering engine.
rendering engine捞高。 負(fù)責(zé)展示資源氯材。 比如如果請(qǐng)求了HTML, 它將會(huì)負(fù)責(zé)將HTML 、CSS編譯和展現(xiàn)在屏幕上硝岗。
Networking氢哮。 用于處理網(wǎng)絡(luò)請(qǐng)求。是一個(gè)獨(dú)立的部分型檀。
UI backend冗尤。 用于繪制一些基礎(chǔ)組件,例如組合框和窗口胀溺。暴露了一些非特定平臺(tái)使用的通用接口裂七,內(nèi)部使用了操作系統(tǒng)的一些接口和方法。
JavaScript interpreter. 用于解釋執(zhí)行JS 仓坞。
Data storage. 用于持久化數(shù)據(jù)的層背零,一些需要儲(chǔ)存到硬盤的數(shù)據(jù),例如 cookies 扯躺。 是一個(gè)瀏覽器上的小型數(shù)據(jù)庫(kù)捉兴。
和所有其他瀏覽器不同,Chrome 擁有
多個(gè)渲染引擎實(shí)例 - 每個(gè)標(biāo)簽頁(yè)都有一個(gè)實(shí)例录语。每個(gè)選項(xiàng)卡是一個(gè)單獨(dú)的過程
以下將會(huì)詳述各個(gè)部分倍啥。
就是以下流程了:
渲染引擎從解析HTML并將標(biāo)簽轉(zhuǎn)譯成DOM節(jié)點(diǎn)開始,這種節(jié)點(diǎn)樹通常被叫做 "content tree"(內(nèi)容樹)澎埠。 它會(huì)解析無(wú)論是內(nèi)連還是外鏈樣式文件虽缕。樣式信息同HTML的架構(gòu)信息將會(huì)建立一種新的樹形系統(tǒng),'render tree' (渲染樹)蒲稳。
'render tree' (渲染樹)包含許許多多的帶視覺信息的矩形氮趋,這些視覺信息包括顏色、大小等等江耀。然后這些矩形將會(huì)以一定的順序被呈現(xiàn)在屏幕上剩胁。
在'render tree' (渲染樹)建造完成后,將會(huì)進(jìn)行一個(gè)叫 'layout' 的過程祥国。這個(gè)過程將會(huì)給每個(gè)node節(jié)點(diǎn)詳細(xì)的坐標(biāo)昵观。下一步是 'painting' ,'render tree' (渲染樹)將會(huì)與節(jié)點(diǎn)穿插然后使用UI backend層渲染晾腔。
非常重要的是這個(gè)過程是逐步推進(jìn)的。為了更好的用戶體驗(yàn)啊犬,渲染引擎嘗試盡快地渲染內(nèi)容灼擂。所以它不會(huì)等待所有HTML文件被解析就開始著手搭建layout和渲染樹。剩余的內(nèi)容持續(xù)不斷的從互聯(lián)網(wǎng)獲得觉至,與此同時(shí)部分內(nèi)容已經(jīng)被轉(zhuǎn)譯并展現(xiàn)在頁(yè)面上剔应。
Figure 3: Webkit main flow
Figure 4: Mozilla's Gecko rendering engine main flow
從上述兩張圖片可以看出,Webkit 和 Gecko 用了稍微不同的術(shù)語(yǔ)语御,但主要流程是基本相似的峻贮。
Gecko 將視覺上格式化的元素集合叫做 ‘Frame tree’(框架樹),每一個(gè)元素都是一個(gè)框架沃暗。Webkit 叫它 render tree, render tree 中的每一個(gè)元素都是一個(gè) ‘ render objects'. webkit 將放置元素到相應(yīng)地點(diǎn)的過程叫做 ' layout ' 而 Gecko 叫他叫做 'reflow' 月洛。Webkit 將鏈接DOM節(jié)點(diǎn)和視覺信息用于構(gòu)建render tree 的過程叫做 'Attachment'. 還有一個(gè)叫法的小不同在 Gecko 在HTML和DOM樹之間有一個(gè)附加的層 ‘content sink’, 它實(shí)際上是一個(gè)制作DOM 元素的工廠。我們下面對(duì)每一個(gè)部分進(jìn)行詳細(xì)敘述
Parsing -通用
由于解析HTML這個(gè)過程在渲染中是非常重要的孽锥,我們稍微深入一些嚼黔。下面稍微介紹一下什么是解析。
解析是將一個(gè)文檔轉(zhuǎn)譯成程序可以理解的某種結(jié)構(gòu)惜辑,他的結(jié)果通常是代表了文檔結(jié)構(gòu)的節(jié)點(diǎn)樹(Node tree)唬涧,我們叫他 解析樹或語(yǔ)法樹(parse tree or a syntax tree)
例如, 解析"2 + 3 - 1"將會(huì)返回:
Grammars - 語(yǔ)法
解析文檔依靠確定的詞匯和句法規(guī)則盛撑,這叫做上下文無(wú)關(guān)語(yǔ)法碎节。人類的語(yǔ)言不符合這種可譯的結(jié)構(gòu)所以無(wú)法被這種技術(shù)解析。
Parser - 語(yǔ)法分析程序
解析分為兩部分:句法分析和詞法分析抵卫。
詞法分析是將輸入變成記號(hào)的過程狮荔。這些記號(hào)是一種有效集合,就像人類語(yǔ)言的字典一樣介粘。
句法分析就是應(yīng)用語(yǔ)言的句法規(guī)則殖氏。
解析器通常分為兩個(gè)部分,詞法分析器和解析器姻采。詞法分析器將輸入的內(nèi)容符號(hào)化雅采,解析器依照語(yǔ)言句法規(guī)范分析文檔來建立解析樹(parse tree)詞法分析器知道怎么跳過無(wú)關(guān)緊要的東西比如恐嚇和換行。
Figure 6: from source document to parse trees
解析過程是迭代進(jìn)行的慨亲。解析器項(xiàng)詞法分析器要來新的需要分析的項(xiàng)(token)然后嘗試用它來匹配句法規(guī)則婚瓜,如果符合了,一個(gè)新節(jié)點(diǎn)就會(huì)產(chǎn)生并懸掛到解析樹上刑棵,然后解析器會(huì)去要下一個(gè)需要分析的項(xiàng)巴刻。
如果有一個(gè)項(xiàng)沒有規(guī)則可以匹配,解析器會(huì)將這個(gè)項(xiàng)儲(chǔ)存在內(nèi)部蛉签,然后繼續(xù)下一個(gè)項(xiàng)一直到某一個(gè)規(guī)則可以適用內(nèi)部?jī)?chǔ)存的項(xiàng)胡陪。如果沒有可適用的項(xiàng)茂附,那么解析器將會(huì)拋出一個(gè)語(yǔ)法錯(cuò)誤(syntax errors)
Translation
大多時(shí)候解析樹并不是最后的產(chǎn)物,解析常常用于將某種語(yǔ)言轉(zhuǎn)換為另一種格式督弓,比如匯編。編譯器將遠(yuǎn)嗎先解析成解析樹而后轉(zhuǎn)譯成匯編語(yǔ)言乒验。
Figure 7: compilation flow
一個(gè)解析的例子:
如圖5所示愚隧,我們建立了一顆解析樹,我們嘗試定義一種簡(jiǎn)單的數(shù)學(xué)語(yǔ)言然后看看解析的過程锻全。
詞匯表: 數(shù)字狂塘、加號(hào)、減號(hào)
句法:
- 構(gòu)建塊為表達(dá)式鳄厌、項(xiàng)和操作符荞胡。
- 表達(dá)式中可包含任何數(shù)字。
- 一個(gè)表達(dá)式的定義形如:項(xiàng) 操作符 項(xiàng)
- 操作符是指加號(hào)和減號(hào)
- 項(xiàng) 是指一個(gè)數(shù)字或者一個(gè)表達(dá)式
由此了嚎,我們可以分析 "2 + 3 - 1"
第一個(gè)符合規(guī)則的是 '2', 根據(jù)句法規(guī)則5泪漂,它是一個(gè)項(xiàng)。而后符合規(guī)則的是 "2+3", 它符合句法規(guī)則2. 而后符合規(guī)則的是
"2 + 3 - 1"歪泳,因?yàn)樗卜弦?guī)則5萝勤, 因?yàn)?“2+3”是一個(gè)項(xiàng)。而
"2 + + "是不符合上述任何一個(gè)條件的呐伞,所以是一個(gè)無(wú)效的輸入敌卓。