1. 程式人生 > >瀏覽器前世今生之技術內幕大揭祕

瀏覽器前世今生之技術內幕大揭祕

目錄

1.從瀏覽器UA角度看瀏覽器前世今生

1.1 你是否好奇標識瀏覽器身份的User-Agent,為什麼每個瀏覽器都有Mozilla字樣?

1.2 國產外殼瀏覽器現狀比較研究

2.渲染引擎WebKit

2.1 WebKit結構介紹

2.2 理解WebKit和Chromium: WebKit, WebKit2, Chromium和Chrome介紹

2.3 Webkit2與Chromium程序架構的異同

2.4 JavaScript引擎介紹

3.V8的前世今生

3.1 WebKit之V8的詳細介紹 (js與C++互調)  

3.2 v8引擎詳解     

3.3 WebKit之V8引擎(js排程C++)  

4.理解WebKit和Chromium

5.WebKit

6.V8

7. 編譯v8引擎

7.1 編譯v8引擎

7.2 windows下 V8 JS引擎 編譯 2016-06-30

7.3 最新 Win7平臺 谷歌v8引擎編譯with GN(2017-9-8)(附編譯後的dll檔案網盤連結)


序言

        瀏覽器自從上世紀80年代後期90年代初期誕生以來,已經得到了長足的發展,其功能也越來越豐富,包括網路、資源管理、網頁瀏覽、多頁面管理、外掛和擴充套件、書籤管理、歷史記錄管理、設定管理、下載管理、賬戶和同步、安全機制、隱私管理、外觀主題、開發者工具等。在這些功能中,為使用者提供網頁瀏覽服務無疑是最重要的功能,下面將對相關內容進行介紹。

1.從瀏覽器UA角度看瀏覽器前世今生

1.1 你是否好奇標識瀏覽器身份的User-Agent,為什麼每個瀏覽器都有Mozilla字樣?

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
Mozilla/5.0 (Linux; U; Android 4.1.2; zh-tw; GT-I9300 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)

故事還得從頭說起,最初的主角叫NCSA Mosaic,簡稱Mosaic(馬賽克),是1992年末位於伊利諾伊大學厄巴納-香檳分校的國家超級計算機應用中心(National Center for Supercomputing Applications,簡稱NCSA)開發,並於1993年釋出的一款瀏覽器。它自稱“NCSA_Mosaic/2.0(Windows 3.1)”,Mosaic可以同時展示文字和圖片,從此瀏覽器變得有趣多了。
然而很快就出現了另一個瀏覽器,這就是著名的Mozilla,中文名稱摩斯拉。一說 Mozilla = Mosaic + Killer,意為Mosaic殺手,也有說法是 Mozilla = Mosaic & Godzilla,意為馬賽克和哥斯拉,而Mozilla最初的吉祥物是隻綠色大蜥蜴,後來更改為紅色暴龍,跟哥斯拉長得一樣。
但Mosaic對此非常不高興,於是後來Mozilla更名為Netscape,也就是網景。Netscape自稱“Mozilla/1.0(Win3.1)”,事情開始變得更加有趣。網景支援框架(frame),由於大家的喜歡框架變得流行起來,但是Mosaic不支援框架,於是網站管理員探測user agent,對Mozilla瀏覽器傳送含有框架的頁面,對非Mozilla瀏覽器傳送沒有框架的頁面。
後來網景拿微軟尋開心,稱微軟的Windows是“沒有除錯過的硬體驅動程式”。微軟很生氣,後果很嚴重。此後微軟開發了自己的瀏覽器,這就是Internet Explorer,並希望它可以成為Netscape Killer。IE同樣支援框架,但它不是Mozilla,所以它總是收不到含有框架的頁面。微軟很鬱悶很快就沉不住氣了,它不想等到所有的網站管理員都瞭解IE並且給IE傳送含有框架的頁面,它選擇宣佈IE是相容Mozilla,並且模仿Netscape稱IE為“Mozilla/1.22(compatible; MSIE 2.0; Windows 95)”,於是IE可以收到含有框架的頁面了,所有微軟的人都嗨皮了,但是網站管理員開始暈了。
因為微軟將IE和Windows捆綁銷售,並且把IE做得比Netscape更好,於是第一次瀏覽器血腥大戰爆發了,結果是Netscape以失敗退出歷史舞臺,微軟更加嗨皮。但沒想到Netscape居然以Mozilla的名義重生了,並且開發了Gecko,這次它自稱為“Mozilla/5.0(Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826”。
Gecko是一款渲染引擎並且很出色。Mozilla後來變成了Firefox,並自稱“Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0”。Firefox效能很出色,Gecko也開始攻城略地,其他新的瀏覽器使用了它的程式碼,並且將它們自己稱為“Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0.8.1”,以及“Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0”,每一個都將自己裝作Mozilla,而它們全都使用Gecko。
Gecko很出色,而IE完全跟不上它,因此user agent探測規則變了,使用Gecko的瀏覽器被髮送了更好的程式碼,而其他瀏覽器則沒有這種待遇。Linux的追隨者對此很難過,因為他們編寫了Konqueror,它的引擎是KHTML,他們認為KHTML和Gecko一樣出色,但卻因為不是Gecko而得不到好的頁面,於是Konqueror為得到更好的頁面開始將自己偽裝成“like Gecko”,並自稱為“Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko)”。自此user agent變得更加混亂。
這時更有Opera跳出來說“毫無疑問,我們應該讓使用者來決定他們想讓我們偽裝成哪個瀏覽器。”於是Opera乾脆建立了選單項讓使用者自主選擇讓Opera瀏覽器變成“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51”,或者“Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51”, 或者“Opera/9.51 (Windows NT 5.1; U; en)”。
後來蘋果開發了Safari瀏覽器,並使用KHTML作為渲染引擎,但蘋果加入了許多新的特性,於是蘋果從KHTML另闢分支稱之為WebKit,但它又不想拋棄那些為KHTML編寫的頁面,於是Safari自稱為“Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5”,這進一步加劇了user agent的混亂局面。
因為微軟十分忌憚Firefox,於是IE重灌上陣,這次它自稱為“Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ”,並且渲染效果同樣出色,但是需要網站管理員的指令它這麼做才行。
再後來,谷歌開發了Chrome瀏覽器,Chrome使用Webkit作為渲染引擎,和Safari之前一樣,它想要那些為Safari編寫的頁面,於是它偽裝成了Safari。於是Chrome使用WebKit,並將自己偽裝成Safari,WebKit偽裝成KHTML,KHTML偽裝成Gecko,最後所有的瀏覽器都偽裝成了Mozilla,這就是為什麼所有的瀏覽器User-Agent裡都有Mozilla。Chrome自稱為“Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13”。
因為以上這段歷史,現在的User-Agent字串變得一團糟,幾乎根本無法彰顯它最初的意義。追根溯源,微軟可以說是這一切的始作俑者,但後來每一個人都在試圖假扮別人,最終把User-Agent搞得混亂不堪。
一句話結論:因為網站開發者可能會因為你是某瀏覽器(這裡是 Mozilla),所以輸出一些特殊功能的程式程式碼(這裡指好的特殊功能),所以當其它瀏覽器也支援這種好功能時,就試圖去模仿 Mozilla 瀏覽器讓網站輸出跟 Mozilla 一樣的內容,而不是輸出被閹割功能的程式程式碼。大家都為了讓網站輸出最好的內容,都試圖假裝自己是 Mozilla 一個已經不存在的瀏覽器……
附各大瀏覽器誕生年表:
1993年1月23日:Mosaic
1994年12月:Netscape
1994年:Opera
1995年8月16日:Internet Explorer
1996年10月14日:Kongqueror
2003年1月7日:Safari
2008年9月2日:Chrome

1.2 國產外殼瀏覽器現狀比較研究

國產外殼瀏覽器現狀比較研究 :https://www.douban.com/note/203951112/

2.渲染引擎WebKit

什麼是渲染引擎?渲染引擎是能夠將HTML/CSS/JavaScript文字及相應的資原始檔轉換成影象結果。渲染引擎的主要作用是將資原始檔轉化為使用者可見的結果。在瀏覽器的發展過程中,不同的廠商開發了不同的渲染引擎,如Tridend(IE)、Gecko(FX)、WebKit(Safari,Chrome,Andriod瀏覽器)等。WebKit是由蘋果2005年發起的一個開源專案,引起了眾多公司的重視,幾年間被很多公司所採用,在移動端更佔據了壟斷地位。更有甚者,開發出了基於WebKit的支援HTML5的web作業系統(如:Chrome OS、Web OS)。

2.1 WebKit結構介紹

下面是WebKit的大致結構:

上圖中實線框內模組是所有移植的共有部分,虛線框內不同的廠商可以自己實現。下面進行介紹:

  • 作業系統:是管理和控制計算機硬體與軟體資源的計算機程式,是直接執行在“裸機”上的最基本的系統軟體,任何其他軟體都必須在作業系統的支援下才能執行。WebKit也是在作業系統上工作的。
  • 第三方庫,為了WebKit提供支援,如圖形庫、網路庫、視訊庫等。
  • WebCore 是各個瀏覽器使用的共享部分,包括HTML解析器、CSS解析器、DOM和SVG等。JavaScriptCore是WebKit的預設引擎,在谷歌系列產品中被替換為V8引擎。WebKit Ports是WebKit中的非共享部分,由於平臺差異、第三方庫和需求的不同等原因,不同的移植導致了WebKit不同版本行為不一致,它是不同瀏覽器效能和功能差異的關鍵部分。
  • WebKit嵌入式程式設計介面,供瀏覽器呼叫,與移植密切相關,不同的移植有不同的介面規範。
  • 測試用例,包括佈局測試用例和效能測試用例,用來驗證渲染結果的正確性。

2.2 理解WebKit和Chromium: WebKit, WebKit2, Chromium和Chrome介紹

有必要解釋一下極其容易混淆的幾個概念,它們是WebKit,WebKit2,Chromium和Chrome。

首先來了解WebKit。廣義上來說,WebKit是一個開源的專案,其前身是來源於KDE的KHTML和KJS。該專案專注於網頁內容的展示,開發出一流的網頁渲染引擎。它不是瀏覽器,而且也不想成為瀏覽器。 該專案包含兩個部分,第一是WebCore,其中包含了對HTML,CSS等很多W3C規範的實現;第二部分就是狹義上的WebKit,它主要是各個平臺的的移植並提供相對應的Web介面,也就是WebView或者類似WebView,這些介面提供操作和顯示網頁的能力。目前使用WebKit的主流的瀏覽器或者WebView包括Chrome, Safari, QtWebKit, Android Browser以及眾多的移動平臺的瀏覽器。

WebKit2相對於狹義上的WebKit而言,它不是WebKit簡單的第二個版本,它是一個新的API層,其最主要的變化在於將網頁的渲染置於單獨的程序,而介面層則在另外一個程序,它們之間通過IPC來通訊。對於介面的呼叫者來說,中間的IPC和底下的實現是透明的,這樣做的好處有很多,一個很明顯的好處是,當網頁的渲染出現問題時,不會阻礙Web介面的呼叫者程序,這會在很大程度上解決或者幫助解決瀏覽器或者這些呼叫者的穩定性和安全性等問題。

Chromium是一個建立在WebKit之上的瀏覽器開源專案,由Google發起的。該專案被建立以來發展迅速,很多先進的技術被採用,如跨程序模型,沙箱模型等等。同時,很多新的規範被支援,例如WebGL,Canvas2D,CSS3以及其他很多的HTML5特性,基本上每天你都可以看到它的變化,它的版本升級很快。在效能方面,其也備受稱讚,包括快速啟動,網頁載入迅速等。

Chrome是Google公司的瀏覽器產品,它基於chromium開源專案,一般選擇穩定的版本作為它的基礎,它和chromium的不同點在於chromium是開源試驗場,會嘗試很多新的東西,當這些東西穩定之後,chrome才會整合進來,這也就是說chrome的版本會落後於chromium。另外一個就是,chrome裡面會加入一些私有的codec,這些僅在chrome中才會出現。再次,chrome還會整合Google的很多服務, 最後chrome還會有自動更新的功能,這也是chromium所沒有的。

2.3 Webkit2與Chromium程序架構的異同

下圖詳細比較了兩者的差別

WebKit2                             Chromium

個人看法:Chromium的標籤程序架構實現了UI和渲染的分離,用一種簡潔的方式實現了”渲染是一種服務“。而WebKit2是從”渲染是一種服務“這種理念出發直接實現多程序架構,這是兩者的根本區別。但是兩者的根本目的都是要實現UI和渲染的分離。
Chromium這種標籤程序方式,將網頁看成一種應用,採用程序方式隔離,實現起來成本較低。但是對於手機等移動裝置,該架構消耗資源實在太大。
WebKit2要將渲染變成一種服務,實現起來代價非常高。這也是到目前為止還在完善的一個原因。但是WebKit2非常適合移動端等這種資源沒有PC這麼豐富的裝置。
Chromium實現的標籤程序架構是從瀏覽器角度出發,沒有提供到處的C介面,不方便嵌入到第三方開發;而WebKit2定位成渲染引擎,提供C介面,方便第三方嵌入使用。

2.4 JavaScript引擎介紹

自從十九世紀九十年底中,Netscape 瀏覽器集成了JavaScript,它使得 web 開發者更加容易訪問 HTML 頁面元素如:表單、frames 和圖象。JavaScript 迅速流行,用於定製控制元件和增加動畫效果。到19世紀九十年代後,出現大量的用於切換圖片以響應使用者生成的滑鼠事件的指令碼。

最近,隨著 AJAX 的出現,JavaScript 已經稱為了實現基於 web 的應用(如:Gmail)的中心技術。JavaScript 程式由簡單的幾行成長為幾百k的原始碼。然而 JavaScript 是被設計成實現 web 應用的非常有效的技術。效能已經成為開發基於 web 的 JavaScript 應用的限制因素。

V8 是全新的 JavaScript 引擎,主要設計目標是快速執行大量 JavaScript 指令碼應用。 在幾種 benchmark 測試中,V8 的效能是 JScript(IE內的引擎)、SpiderMonkey(Firefox所用)和 JavaScriptCore(safari 所用)的許多倍。如果您的 web應用受限於 JavaScript 的執行速度,則使用V8 代替您當前的 JavaScript 引擎將很可能提高您的應用的效能。效能提升的程度依賴於JavaScript 的多少和 JavaScript 的特點。例如,如果在您的 應用中函式傾向於一次一次被執行,則與僅執行一次許多不同函式相比效能將大大地提升。當您閱讀完本文件時,您將更加清楚效能提升的原因。

V8 引擎主要工作流程。V8 執行JavaScript 的流程如下:

                                           V8-flow

                                                                     圖 V8 處理JavaScript 流程

為什麼V8 的速度比其他瀏覽器的JS 引擎快?

V8 執行過程分為兩個階段:編譯階段和執行階段。

首先JavaScript 經過Compiler 將指令碼轉為抽象語法樹(AST) ,然後在巨集彙編器的作用下,將AST 的每個節點轉化為機器相關的指令( 如Intel 有IA32 實現,ARM 有arm 實現) ,最後交由CPU 直接執行這些生成的指令。

其他瀏覽器JS 引擎(Firefox) 在編譯階段和V8 類似,但是生成的指令不是機器相關的指令而是自定義的指令,因此導致在執行階段需要解釋執行。這也就是為什麼V8 引擎的效能如此卓越的根本原因。

從根本上,V8 是包含了一個JIT 編譯器,並且直接有CPU執行生成的體系結構相關的指令,因此才比其他引擎快。

3.V8的前世今生

V8是JavaScript渲染引擎,第一個版本隨著Chrome的釋出而釋出(具體時間為2008年9月2日)。在執行JavaScript之前,相比其它的JavaScript的引擎轉換成位元組碼或解釋執行,V8將其編譯成原生機器碼(IA-32, x86-64, ARM, or MIPS CPUs),並且使用瞭如內聯快取(inline caching)等方法來提高效能。V8可以獨立執行,也可以嵌入到C++應用程式中執行。

3.1 WebKit之V8的詳細介紹 (js與C++互調)  

https://blog.csdn.net/sauphy/article/details/50168737

3.2 v8引擎詳解     

https://blog.csdn.net/swimming_in_it_/article/details/78869549

3.3 WebKit之V8引擎(js排程C++)  

https://blog.csdn.net/sauphy/article/details/50749373

4.理解WebKit和Chromium

https://blog.csdn.net/milado_nju/article/details/7216067

5.WebKit

http://exbrowser.com/?cat=32

6.V8

http://exbrowser.com/?cat=55

7. 編譯v8引擎

7.1 編譯v8引擎

https://blog.csdn.net/zengraoli/article/details/9178219

7.2 windows下 V8 JS引擎 編譯 2016-06-30

https://blog.csdn.net/herorazor/article/details/51792793

7.3 最新 Win7平臺 谷歌v8引擎編譯with GN(2017-9-8)(附編譯後的dll檔案網盤連結)

https://www.jianshu.com/p/48579c0c5d44