網絡瀏覽器多是最普遍使用的軟件了。本文中我將解釋它們在幕後是如何工做的,咱們將看到從你在地址欄中輸入「google.com」,直到谷歌的頁面出如今瀏覽器屏幕的過程當中發生了什麼。html
如今主要有五種瀏覽器被使用,分別是:IE、火狐、Safari、Chrome和歐朋。根據W3C瀏覽器的統計資料,目前(2009年9月),Firefox, Safari and Chrome瀏覽的使用份額總和將近有60%。web
所以在當前,開源瀏覽器是瀏覽器市場的中堅力量。正則表達式
瀏覽器主要的功能是展現你所選擇的網絡資源,經過向服務器請求並顯示在瀏覽器的窗口中。資源的格式一般是HTML,或者PDF、image等等。資源的位置是由用戶使用的URI(統一資源標識符)來指定的。瀏覽器解釋和顯示HTML文件的方式根據HTML和CSS規範來指定。這些規範是由W3C組織維護的,W3C是網絡標準組織。數據庫
當前HTML的版本號是4(http://www.w3.org/TR/html401/),版本5還在制定中。當前的CSS版本號是2(http://www.w3.org/TR/CSS2/),版本3仍在制定中。多年來瀏覽器只遵循了規範的一部分,而且開發了他們本身的擴展。這給瀏覽器的使用者帶來了嚴重的兼容性問題。如今絕大部分的瀏覽器都基本上遵循了規範。express
瀏覽器的用戶界面彼此有不少共同之處,其中常見的用戶頁面元素有:後端
奇怪的是,瀏覽器的用戶界面沒有在任何正式的規範中指定,這些是多年來各瀏覽器廠商之間相互模仿和不斷改進得結果。HTML5規範並無定義瀏覽器中必須具備的UI元素,包括地址欄、狀態欄和工具欄。還有一些瀏覽器擁有本身特有的功能,像火狐的下載管理器。瀏覽器
瀏覽器的主要部件有:服務器
瀏覽器引擎:查詢和操做渲染引擎的接口cookie
渲染引擎: 負責顯示請求的內容,例如請求的是HTML內容,它負責解析HTML和CSS並將解析的內容顯示在屏幕上。網絡
網絡:用來網絡調用,例如HTTP請求,它有平臺無關的接口,能夠在不一樣的平臺上工做。
界面後端:用來繪製相似組合選擇框及對話框等基本組件,具備不限定於某個平臺的通用接口,底層使用操做系統的用戶接口。
JS解釋器:使用它來解析和執行JS代碼。
數據存儲:屬於持久層,瀏覽器須要將各類格式的數據保存在硬盤上,例如cookies。最新的HTML規範(HTML5)定義網絡數據庫是一種完整的輕量級客戶端數據庫。
下面爲瀏覽器的主要構件示意圖:
ps:須要特別指出的是,不一樣於大部分瀏覽器,Chrome爲每一個標籤分配了各自的渲染引擎實例,每一個標籤就是一個獨立的進程。
對於每個組件,我將在後面的章節中進行逐一闡述。
Firefox和Chrome都開發了一套特殊的通訊結構,後面將有專門的一章進行討論。
渲染引擎的職責是…渲染,就是在瀏覽器屏幕上顯示請求的內容。默認狀況下,渲染引擎可以顯示HTML和XML文件以及圖片。經過插件(一種瀏覽器擴展)能夠顯示其它類型文件。例如經過使用PDF查看插件顯示PDF文件。咱們將用一個章節來討論插件和擴展。這裏只討論渲染引擎最主要的用途——顯示應用了CSS以後的HTML和圖片。
咱們所討論的瀏覽器:Firefox, Chrome 和 Safari是基於兩種渲染器構建的。Firefox使用Gecko一種Mozilla自主研發的渲染引擎。afari 和 Chrome使用的都是Webkit。
Webkit是一種開源渲染引擎,它一開始是在Linux平臺上使用的,後來被Apple改進並應用到Mac及Windows上,更多詳情請參考http://webkit.org。
渲染引擎首先從網絡層獲取請求的內容,一般以8K分塊的方式完成。
下面是渲染引擎的基本流程:
渲染引擎首先解析HTML文件,將標籤轉化爲內容樹的DOM節點。而後將解析外部CSS文件和style標籤中的樣式信息。這些樣式信息和HTML中的可見性指令將會被用來構建另外一顆樹—渲染樹(渲染樹由一些包含有顏色和大小等屬性的矩形組成,這些矩形按照正確的順序顯示在屏幕上)。
渲染樹構建好以後,將執行佈局過程。這將出給每一個節點在屏幕上出現的確切座標。接下來的步驟是繪製—遍歷渲染樹,並使用後端UI層繪製出每個節點。
值得一提的是,這是一個逐步的過程。爲了更好的用戶體驗,渲染引擎將更可能早的將內容顯示在屏幕上,而不會等到全部的HTML都解析完以後再去構建和佈局渲染樹,它是邊解析邊顯示內容的,與此同時還可能經過網絡下載餘下內容。
圖 Webkit main flow
圖 Mozilla's Gecko rendering engine main flow
經過上面兩幅圖能夠看到儘管Webkit和Gecko使用稍微不一樣的術語,可是流程基本是相同的。Gecko稱可見的格式化元素組成的樹爲frame樹。
每一個元素都是一個frame。webkit則使用「Render Tree」這個名詞來命名由渲染對象組成的樹。Webkit中元素的定位稱爲佈局,而Gecko中稱爲迴流。Webkit稱鏈接DOM節點及樣式信息去構建render樹的過程爲」attachment」,Gecko在html和dom樹之間附加了一層,這層稱爲內容接收器,至關製造DOM元素的工廠。下面將討論流程中的各個階段。
由於解析是渲染引擎中一個很是重要的過程,咱們將更深刻研究一下它。讓咱們首先介紹一下解析。
解析一個文件是將其轉化爲具備必定意義的結構—能夠理解和使用的代碼。解析的結果一般是一顆表示文件結構的節點樹,稱爲解析樹或語法樹。
例子—解析表達式「2+3-1」,可能返回這樣一顆樹:
解析基於文檔依據的語法規則-文檔的語言或格式。每種可被解析的格式必須具備由詞彙及語法規則組成的特定文法,稱爲上下文無關文法。人類語言不具備這一特性,所以不能經過經常使用的解析技術解析。
解析能夠被分爲兩個子過程-語法分析和詞法分析。
詞法分析就是將輸入分解爲符號。符號是語言的詞彙表-有效構建塊的集合。對於人類而言,它至關因而咱們字典中出現的全部單詞。
語法分析是指對語言應用語法規則。
解析器一般將工做分配給兩個組件-詞法分析器負責將輸入分解爲合法的符號,解析器負責按照語言的語法規則分析文檔結構從而構建解析樹。詞法分析器知道怎麼跳過空白和換行之類的無關字符。
解析過程是迭代的。解析一般向詞法分析器獲取一個新的符號而後試圖用這個符號去匹配一條語法規則。若是有一條規則被匹配到,那麼這個符號對應的節點將會被添加到解析樹中,而後請求另外一個符號。若是沒有匹配到規則,解析器將在內部保存該符號並繼續從詞法分析器中獲取符號直到全部內部保存的符號可以匹配一條規則。若是最終沒有找到匹配的規則,解析器將會拋出一個異常,這意味着文檔無效或者包含語法錯誤。
不少時候解析樹不是最終的結果。解析通常在轉換中使用—將輸入文檔轉化成另外一種格式。編譯就是一個例子。編譯器將源代碼編譯成機器碼,首先將其解析爲一顆解析樹而後將樹轉換爲機器碼文檔。
在圖表5中,咱們從一個數學表達式中構建了一顆解析樹。讓咱們來定義一個簡單的數學語言,看看解析的過程。
詞彙表:咱們的語言能夠包括整數,加號和減號。
語法:
一、該語言的語法基本單元包括表達式,術語和操做符。
二、該語言能夠包括多個表達式
三、一個表達式定義爲兩個term經過一個操做符鏈接
四、一個操做符是一個加號或者一個減號
五、一個term是一個整數或是一個表達式
如今來分析一下「2+3-1」這個輸入:
第一個匹配規則的子字符串是「2」,根據規則5這是一個term。第二個匹配的是「2+3」,一個term後跟着一個操做符再鏈接着另外一個term。下一個匹配在輸入的結束處。「2+3-1」是一個表達式由於咱們已經知道?2+3?是一個term,因此咱們有了一個term緊跟着一個操做符及另外一個term。「2++」將不會匹配任何規則,所以是一個無效輸入
詞彙一般經過正則表達式來表示。
例如咱們語法將會被定義成:
INTEGER :0|[1-9][0-9]*
PLUS : +
MINUS: -
可見,整數經過一個正則表達式來定義。
語法一般以一種被稱做BNF的格式來定義,咱們的語言將會被定義成:
expression := term operation term
operation := PLUS | MINUS
term := INTEGER | expression
咱們說若是一種語言若是它的語法是上下文無關文法,則能夠經過解析器來解析。對於上下文無關文法的一個直觀的定義是該文法可以用BNF來完整的表達。正式的定義可查閱http://en.wikipedia.org/wiki/Context-free_grammar
有兩種基礎的解析器類型—自頂向下解析器和自底向上解析器。比較直觀的解釋是,自頂向下解析器是查看句法的最高層結構,而後嘗試匹配其中一個,自底向上解析器從輸入開始,而後逐步轉換爲句法規則,從底層規則開始直到匹配最高層規則。
咱們來看一下這兩種類型的解析器是如何解析咱們的例子的:
自頂向上解析器從最高層規則開始—它將「2+3」做爲一個表達式,而後識別「2+3-1」爲一個表達式。
自底向上解析器將掃描輸入直到匹配一條規則,而後用該規則取代匹配的輸入,直到解析完全部輸入。有一部分匹配的表達式被放在解析堆棧中。
這種自底向上的類型被稱爲轉換減小解析器,由於輸入向右移動,而且逐漸簡化爲語法規則。
有些工具能夠產生一個解析器,它們被稱爲解析器生成器。你須要指定語言的語法—詞彙表和句法規則,它就能夠生成有一個解析器。建立一個解析器須要對解析有一個深刻的理解,手動去建立一個性能優良的解析器是不容易的,所以解析器生成器是很是有用的。
Webkit 使用了兩個很著名的解析器生成器——用於建立語法分析器的Flex及建立解析器的Bison。Flex的輸入是一個包含了符號定義的正則表達式,Bison的輸入是用BNF格式表示的語法規則。
本文是由一篇外國文章翻譯而成,外文地址連接爲http://taligarsiel.com/Projects/howbrowserswork1.htm#The_browsers_we_will_talk_about。後續待更新。