目前咱們使用的主流瀏覽器包括:chrome, firefox, ie, safari, opera, uc等等。其中chrome瀏覽器所佔的全球市場份額最高,其次是IE。下面截圖數據來源於統計網站 www.netmarketshare.com/ html
瀏覽器的主要目的就是向服務器發送請求,獲取並展現服務器上的資源,資源文件能夠是html文檔,也能夠是pdf,jpg等其餘類型的文件。html5
用戶操做界面:包括地址欄、前進/後退按鈕、書籤菜單等。web
瀏覽器引擎:在用戶界面和呈現引擎之間傳輸指令。chrome
呈現引擎:展現所請求的內容,好比解析HTML文檔和CSS內容,將頁面展現給用戶瀏覽。數據庫
網絡:用於網絡調用,好比發起HTTP請求。其底層實現跟平臺無關。後端
用戶界面後端:用於繪製基本的窗口小部件,好比彈窗等。其底層使用操做系統的用戶界面方法。瀏覽器
JavaScript解釋器:用於解釋和執行JS代碼。bash
數據存儲:用於瀏覽器在硬盤上存儲數據,好比cookie,local storage等。HTML5的網絡數據庫就是瀏覽器內的完整的輕量的數據庫。服務器
chrome瀏覽器的每一個標籤頁分別對應一個呈現引擎實例,每一個標籤頁都是一個獨立的進程。cookie
firefox使用的呈現引擎是 Mozilla 公司自制的 「Gecko」 引擎。Safari 和 chrome 使用的是 「Webkit」 引擎。 IE 使用的是 「trident」 引擎。webkit 是源代碼開放的呈現引擎。
呈現引擎經過網絡層獲取到請求文檔的內容後,進行以下流程的解析:
瀏覽器使用HTML解析器將HTML標記解析成解析樹。解析器輸出的「解析樹」是由DOM元素和屬性節點構成的樹形結構,DOM是HTML文檔的對象表示,同時也是JS調用的基礎。
由於HTML語言的包容性,HTML解析器沒法使用常規的自上而下或自下而上的解析器進行解析,因此使用自定義的解析器來解析。解析過程包括兩個階段:標記化和樹構建。
標記化:是詞法分析過程,將輸入內容分析成多個標記。HTML標記包括起始標記,結束標記,屬性名稱和屬性值。
樹構建:標記生成器識別標記後,傳遞給樹構建器,由樹構造器進行處理,而後再接受下一個字符繼續識別,繼續傳遞給樹構建器,如此循環直到輸入的結束。
例如:下面HTML標記化過程
<html>
<body>
Hello world
</body>
</html>
複製代碼
初始狀態是數據狀態。遇到< 字符時,狀態更改成「標記打開狀態」。接收一個 a-z 字符會建立「起始標記」,狀態更改成「標記名稱狀態」。這個狀態會一直保持到接收 > 字符。在此期間接收的每一個字符都會附加到新的標記名稱上。在本例中,咱們建立的標記是 html 標記。
遇到 > 標記時,會發送當前的標記,狀態改回「數據狀態」。 標記也會進行一樣的處理。目前 html 和 body 標記均已發出。如今咱們回到「數據狀態」。接收到 Hello world 中的 H 字符時,將建立併發送字符標記,直到接收 中的 <。咱們將爲 Hello world 中的每一個字符都發送一個字符標記。
如今咱們回到「標記打開狀態」。接收下一個輸入字符 / 時,會建立 end tag token 並改成「標記名稱狀態」。咱們會再次保持這個狀態,直到接收 >。而後將發送新的標記,並回到「數據狀態」。 輸入也會進行一樣的處理。
例如:下面HTML的樹構建過程
<html>
<body>
Hello world
</body>
</html>
複製代碼
樹構建階段的輸入是一個來自標記化階段的標記序列。第一個模式是「initial mode」。接收 HTML 標記後轉爲「before html」模式,並在這個模式下從新處理此標記。這樣會建立一個 HTMLHtmlElement 元素,並將其附加到 Document 根對象上。
而後狀態將改成「before head」。此時咱們接收「body」標記。即便咱們的示例中沒有「head」標記,系統也會隱式建立一個 HTMLHeadElement,並將其添加到樹中。
如今咱們進入了「in head」模式,而後轉入「after head」模式。系統對 body 標記進行從新處理,建立並插入 HTMLBodyElement,同時模式轉變爲「in body」。
如今,接收由「Hello world」字符串生成的一系列字符標記。接收第一個字符時會建立並插入「Text」節點,而其餘字符也將附加到該節點。
接收 body 結束標記會觸發「after body」模式。如今咱們將接收 HTML 結束標記,而後進入「after after body」模式。接收到文件結束標記後,解析過程就此結束。
瀏覽器解析完成後,將文檔標註爲交互狀態,並處理那些在文檔解析完成後才執行的腳本。而後將文檔狀態設置爲「完成」,並觸發load加載事件。