《深入理解Android》一2.1 浏览器工作原理概述
本節(jié)書摘來自華章出版社《深入理解Android》一書中的第2章,第2.1節(jié),作者孟德國 王耀龍 周金利 黎歡,更多章節(jié)內(nèi)容可以訪問云棲社區(qū)“華章計算機”公眾號查看
2.1 瀏覽器工作原理概述
眾所周知,萬維網(wǎng)(World Wide Web,WWW)以統(tǒng)一資源定位符(Uniform Resource Locator,URL)作為地址空間編碼,以超文本傳送協(xié)議(HyperText Transfer Protocol,HTTP)請求和應(yīng)答,以超文本標記語言(HyperText Markup Language,HTML)記錄并以超鏈接(hyperlink)互相關(guān)聯(lián)起來的網(wǎng)頁(web page)文檔作為內(nèi)容單元,構(gòu)成了人類有史以來最為龐大的資料信息庫。瀏覽器(browser application)即是專門用來訪問和瀏覽萬維網(wǎng)頁面的客戶端軟件,也是現(xiàn)代計算機系統(tǒng)中應(yīng)用最為廣泛的軟件之一,其重要性不言而喻。瀏覽器內(nèi)部最主要也是最重要的模塊是負責頁面渲染的排版引擎(layout engine),也可稱作瀏覽器的內(nèi)核(kernel),其余的部分可統(tǒng)稱為瀏覽器的外殼(browser shell)。
下面將從頁面、排版引擎和瀏覽器外殼應(yīng)用三個方面對萬維網(wǎng)和瀏覽器技術(shù)的基本概念和原理逐一地做簡單介紹。
2.1.1 頁面
現(xiàn)代Web Page通常由三部分組成:描述頁面結(jié)構(gòu)和內(nèi)容的HTML語言,控制頁面動態(tài)邏輯的JavaScript腳本,設(shè)定頁面風格樣式的層疊樣式表(Cascading Style Sheets,CSS)。
HTML是為創(chuàng)建和描述可在瀏覽器中展現(xiàn)的網(wǎng)頁信息而設(shè)計的一種文本格式標記語言,最初于1982年由Tim Berners-Lee創(chuàng)建,后來成為國際標準,由萬維網(wǎng)聯(lián)盟(W3C)維護。HTML由SGML(Standard Generalized Markup Language)簡化發(fā)展而來,能夠結(jié)構(gòu)化地表示文檔的構(gòu)成和內(nèi)容(如標題、段落、文本、表格),以及一定的外觀(如寬、高、顏色)和語義(如注釋、鏈接)。HTML頁面由多種尖括號<>包圍起來的標簽元素以樹形結(jié)構(gòu)組成,其頂級標簽為,內(nèi)容標簽為
JavaScript是一種內(nèi)置于瀏覽器的動態(tài)、弱類型、基于原型的網(wǎng)頁腳本語言。一般來說,完整的JavaScript應(yīng)該包括以下幾個部分:
ECMAScript:描述了該語言的語法和基本對象;
文檔對象模型(DOM):描述處理網(wǎng)頁內(nèi)容的方法和接口;
瀏覽器對象模型(BOM):描述與瀏覽器進行交互的方法和接口。
JavaScript的出現(xiàn)使得網(wǎng)頁由單純的靜態(tài)HTML變成動態(tài)可編程的DHTML,開發(fā)者可用JavaScript來完成讀寫DOM,向頁面添加交互行為,對瀏覽器事件做出響應(yīng),創(chuàng)建和發(fā)起網(wǎng)絡(luò)請求等許多工作。
層疊樣式表(CSS)的發(fā)明是為了將網(wǎng)頁的內(nèi)容描述與顯示風格的描述分隔出來,HTML中只包含結(jié)構(gòu)和內(nèi)容的描述信息,CSS則只包含樣式的描述信息。單獨把一些顯示風格信息如字體顏色、背景、排版方式等統(tǒng)一放在CSS文本中,可以大大簡化HTML文件,同時增強可讀性和修改靈活性。
Web Page一般由前端(front end)開發(fā)設(shè)計人員直接編寫或者由服務(wù)器端的腳本動態(tài)生成,通過Web服務(wù)器以HTTP協(xié)議發(fā)布,供瀏覽器訪問,這種方式即是通常所說的B/S架構(gòu)(Browser/Server Architecture)。
2.1.2 內(nèi)核
瀏覽器的內(nèi)核或稱排版引擎,負責請求網(wǎng)絡(luò)頁面資源加以解析排版并呈現(xiàn)給用戶。從資源的下載到最終的頁面展現(xiàn),可簡單地理解成一個線性串聯(lián)的變換過程的組合,原始輸入為URL地址,最終輸出為頁面Bitmap,中間依次經(jīng)過了Loader、Parser、Layout和Paint模塊,如圖2-1所示。
Loader模塊(如圖2-2所示)負責處理所有的HTTP請求以及網(wǎng)絡(luò)資源的緩存,相當于是從URL輸入到Page Resource輸出的變換過程。HTML頁面中通常有外鏈的JS/CSS/Image資源,為了不阻塞后續(xù)解析過程,一般會有兩個IO管道同時存在,一個負責主頁面下載,一個負責各種外鏈資源的下載。
雖然大部分情況下不同資源可以并發(fā)下載異步解析(如圖片資源可以在主頁面解析顯示完成后再被顯示),但JS腳本可能會要求改變頁面,因此有時保持執(zhí)行順序和下載管道后續(xù)處理的阻塞是不可避免的。
Parser模塊主要負責解析HTML頁面,完成從HTML文本到HTML語法樹再到文檔對象樹(Document Object Model Tree,DOM Tree)的映射過程。
HTML語法樹生成如圖2-3所示是一個典型的語法解析過程,可以分成兩個子過程:詞法解析和語法解析。詞法解析按照詞法規(guī)則(如正則表達式)將HTML文本分割成大量的標記(token),并去除其中無關(guān)的字符如空格。語法解析按照語法規(guī)則(如上下文無關(guān)文法)匹配Token序列生成語法樹,通常有自上而下和自下而上兩種匹配方式。
瀏覽器內(nèi)核中對HTML頁面真正的內(nèi)部表示并不是語法樹,而是W3C組織規(guī)范的文檔對象模型 (Document Object Model,DOM)。DOM也是樹形結(jié)構(gòu),以Document對象為根。DOM節(jié)點基本和HTML語法樹節(jié)點一一對應(yīng),因此在語法解析過程中,通常直接生成最終的DOM樹。下面這個HTML文檔對應(yīng)的語法樹如圖2-4所示,而實際構(gòu)建的DOM樹如圖2-5所示。
不同的頁面標簽對應(yīng)不同類型的DOM樹節(jié)點,如
標簽會對應(yīng)HTMLDiv-Element。DOM節(jié)點類型構(gòu)成一個繼承體系,詳情可參見WebKit源碼中WebCore/dom和WebCore/html兩個目錄。頁面中所有的CSS由樣式表CSSStyleSheet集合構(gòu)成,而CSSStyleSheet是一系列CSSRule的集合,每一條CSSRule則由選擇器CSSStyleSelector部分和聲明CSSStyleDeclaration部分構(gòu)成,而CSSStyleDeclaration是CSS屬性和值的Key-Value集合。圖2-6顯示了某一CSS樣式表經(jīng)過CSSParser解析后在瀏覽內(nèi)核中的基本表示。
CSS解析完畢后會進行CSSRule的匹配過程,即尋找滿足每條CSS規(guī)則Selector部分的HTML元素,然后將其Declaration部分應(yīng)用于該元素。實際的規(guī)則匹配過程會考慮到默認和繼承的CSS屬性、匹配的效率及規(guī)則的優(yōu)先級等因素。
JavaScript一般由單獨的腳本引擎解析執(zhí)行,它的作用通常是動態(tài)地改變DOM樹(比如為DOM節(jié)點添加事件響應(yīng)處理函數(shù)),即根據(jù)時間(timer)或事件(event)映射一棵DOM樹到另一棵DOM樹。
簡單來說,經(jīng)過了Parser模塊的處理,內(nèi)核把頁面文本轉(zhuǎn)換成了一棵節(jié)點帶CSS Style、會響應(yīng)自定義事件的Styled DOM樹。
顧名思義,Layout過程就是排版,它包含兩大過程。
步驟1:創(chuàng)建布局樹。
布局樹(或者叫做渲染樹、Render Tree,如圖2-7所示)和DOM樹大體能一一對應(yīng),兩者在內(nèi)核中同時存在但作用不同。DOM樹是HTML文檔的對象表示,同時也作為JavaScript操縱HTML的對象接口。Render樹是DOM樹的排版表示,用以計算可視DOM節(jié)點的布局信息(如寬、高、坐標)和后續(xù)階段的繪制顯示。
并非所有DOM節(jié)點都可視,也就是并非所有DOM樹節(jié)點都會對應(yīng)生成一個Render樹節(jié)點。例如,
步驟2:計算布局。
布局就是安排和計算頁面中每個元素大小位置等幾何信息的過程。HTML 采用流式布局模型,基本的原則是頁面元素在順序遍歷過程中依次按從左至右、從上至下的排列方式確定各自的位置區(qū)域。一個HTML元素對應(yīng)一個以CSS盒子模型(如圖2-8所示)描述的方塊區(qū)域,盒子模型決定了內(nèi)容、邊框和邊框內(nèi)外填充區(qū)(Padding、Margin)的大小。HTML元素分成兩個基本類型,Inline和Block。Inline元素不會換行,按從左到右來布局。Block元素的出現(xiàn)意味著需要從上至下?lián)Q到下一行來布局。除了這種基本的順序按照元素的Inline和Block來進行流式布局之外,還有特殊指定的一些布局方式,如Absolute/Fixed/Relative三種定位布局以及Float浮動布局。簡單情況下,布局可以順序遍歷一次Render樹完成,但也有需要迭代的情況。當祖先元素的大小位置依賴于后代元素或者互相依賴時,一次遍歷就無法完成布局,如Table元素的寬高未明確指定而其下某一子元素Tr指定其高度為父Table高度的30%的情況。
經(jīng)過了Layout階段的處理,我們把帶Style的DOM樹變換成包含布局信息和繪制信息的Render樹,接下來的顯示工作就交由Paint模塊進行操作了。
Paint模塊負責將Render樹映射成可視的圖形,它會遍歷Render樹調(diào)用每個Render節(jié)點的繪制方法將其內(nèi)容顯示在一塊畫布或者位圖上,并最終呈現(xiàn)在瀏覽器應(yīng)用窗口中成為用戶看到的實際頁面。每個節(jié)點對應(yīng)的大小位置等信息都已經(jīng)由Layout階段計算好了,節(jié)點的內(nèi)容取決于對應(yīng)的HTML元素,或是文本,或是圖片,或是UI控件。
通常情況下,布局和繪制是相當耗時的操作。如果DOM樹每次略有改動都要重新布局和繪制一次,效率會相當?shù)拖隆R虼?#xff0c;一般瀏覽內(nèi)核都會實現(xiàn)一種增量布局和增量繪制的方式。當一個DOM樹節(jié)點(或者它的子節(jié)點)內(nèi)容或者樣式發(fā)生變化時,內(nèi)核會確定其影響范圍,在布局階段會標記出受該節(jié)點布局影響的其他節(jié)點(比如可能是子節(jié)點),在繪制階段則會標記出一個Dirty區(qū)域并通知系統(tǒng)重繪。
按照HTML相關(guān)規(guī)范,頁面元素的CSS屬性也規(guī)定了其繪制順序,如根據(jù)不同Layer必須按順序繪制,否則覆蓋疊加效果會出現(xiàn)錯誤,如元素的邊框輪廓和內(nèi)容背景的繪制次序也有規(guī)定。
基本上瀏覽內(nèi)核的工作原理即如上所述,不同瀏覽器的具體實現(xiàn)架構(gòu)不盡相同,所采用的術(shù)語名稱可能不一樣,但都需要完成上述各個階段的工作。例如,Mozilla Firefox瀏覽器使用的Gecko排版引擎主要流程如圖2-9所示。
2.1.3 外殼
瀏覽器作為一個完整軟件,除了對用戶透明和不可見的渲染引擎作為內(nèi)核外,還需要有供用戶交互使用的外殼UI界面,圖2-10給出了一個瀏覽器Shell的基本模塊架構(gòu)。目前的主流瀏覽器基本都會提供如下功能:
地址欄URI輸入;
前進后退和刷新停止的控制按鈕;
主頁、網(wǎng)絡(luò)導(dǎo)航和搜索;
歷史、書簽和下載管理;
多標簽頁瀏覽和會話管理;
查找、縮放和全屏;
數(shù)據(jù)持久化如Cookie、LocalStorage等;
選項設(shè)置;
插件和功能擴展。
由于Ajax、HTML 5等前端技術(shù)和瀏覽引擎的迅猛發(fā)展,今天的瀏覽器已經(jīng)超出了展現(xiàn)某URL上網(wǎng)頁內(nèi)容這一基本功能的范疇,網(wǎng)頁可作為繪圖、辦公、游戲、即時通信等應(yīng)用的載體。Web App已經(jīng)成為現(xiàn)實,瀏覽器也從單一的工具軟件向Web OS的方向演進。每一個Web Page或Web App可看成對應(yīng)于傳統(tǒng)操作系統(tǒng)中的一個Native App,排版引擎作為Kernel執(zhí)行Web App,瀏覽外殼作為GUI Shell供用戶操作使用,多標簽瀏覽器相當于多任務(wù)操作系統(tǒng),Google的Chrome瀏覽器和由此演變而來的Chrome OS可看作這一想法的實施典型。圖2-11描述了Chrome瀏覽器和WebKit排版引擎之間的層次結(jié)構(gòu)和調(diào)用關(guān)系,圖2-12則給出了Chrome多進程設(shè)計的核心架構(gòu)。
總結(jié)
以上是生活随笔為你收集整理的《深入理解Android》一2.1 浏览器工作原理概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线性规划问题(一)
- 下一篇: 《Java和Android开发实战详解》