<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          47 張圖帶你走進瀏覽器的世界!

          共 24120字,需瀏覽 49分鐘

           ·

          2021-07-16 20:45



          大家好,我是零一,每個開發(fā)者(尤其是前端工程師)或多或少會跟瀏覽器打交道,那么你們有沒有想過去深入了解瀏覽器呢?無論是因為好奇還是為了面試,相信你們一定在網(wǎng)上搜過不少關(guān)于瀏覽器相關(guān)的知識和文章,或者也買過不少的課程。但很少有文章能生動形象地帶你去了解瀏覽器的點點滴滴。

          今天就給大家?guī)硪黄彝?nbsp;獨釣寒江雪 帶來的??萬字精品文章,他是思否的優(yōu)秀作者,輸出多篇硬核文章,感興趣的朋友可以點擊文章末尾的「閱讀原文」進行查看~

          作者:獨釣寒江雪

          原文鏈接:https://juejin.cn/post/6983896089703235592

          本文用47張圖帶你了解「瀏覽器的發(fā)展史」「瀏覽器的架構(gòu)」「瀏覽器的基本原理」以及 「瀏覽器的其它小知識」

          ?? 正文開始

          瀏覽器的主要功能就是向服務器發(fā)出請求,在瀏覽器窗口中展示HTML文檔、PDF、圖片、視頻等網(wǎng)絡內(nèi)容。這些網(wǎng)絡資源的位置由用戶使用 URI(統(tǒng)一資源標示符)來指定指定。

          或許在大多數(shù)人眼中,瀏覽器是這樣的:

          大多數(shù)人眼中的瀏覽器

          「一個展示前端,一個未知的中間層連接著網(wǎng)絡世界」;甚至,網(wǎng)絡世界也可以省略:一臺顯示器,一個神秘的幕后黑盒。

          如果你是一個前端開發(fā)者,甚至每天瀏覽器陪伴你度過的時光比女朋友陪伴你的都要久,想想那每一個令人“不是那么期待”的早晨,每一個爭分奪秒完成任務的黃昏,只有瀏覽器和編輯器一直是你忠實的伙伴。而「就連你一直離不開的VS Code編輯器,甚至也與瀏覽器有著莫大的淵源」

          屏幕前的朋友,你熟悉自己身邊的那些人嗎,熟悉那些與你朝夕相伴的朋友嗎?也許熟悉,也許不,那么,你是否愿意花些時間來熟悉一下這個在大量時間里與你有著莫大交集的瀏覽器的內(nèi)心世界呢?

          今天,我們就來一探究竟,走進這個我們與網(wǎng)絡連接最緊密的中間地帶。全文行文結(jié)構(gòu)大概如下:

          目錄結(jié)構(gòu)

          瀏覽器發(fā)展簡史

          瀏覽器的誕生與發(fā)展

          也許你知道,第一款瀏覽器 —— WorldWideWeb,誕生于1990年。但是現(xiàn)代瀏覽器的雛形卻孕育于 1980s年代。

          一位名叫蒂姆·伯納斯-李的英國科學家在 1980 年代初期創(chuàng)建了一個名為 Inquire 的計算機程序,當時他在總部位于瑞士的歐洲核研究組織(CERN,以其法文字母表示)工作。該計劃旨在「使在 CERN 工作的許多不同個人更容易共享信息」

          1990年,第一款瀏覽器問世于Tim Berners-Lee 在 CERN 工作期間。您可能想知道 Web 瀏覽器到底是什么,簡而言之,它是一個計算機程序,其目的是顯示和檢索數(shù)據(jù)。使用分配給存儲在網(wǎng)絡服務器上的每個數(shù)據(jù)集(網(wǎng)頁)的 URL,它可以做到這一點。所以這意味著「當您在瀏覽器中輸入內(nèi)容時,您實際上是在輸入地址」,瀏覽器將使用該地址來獲取您想要查看的信息。「瀏覽器的另一個關(guān)鍵功能是以易于理解的方式向您解釋和呈現(xiàn)計算機代碼」

          下圖簡單羅列了截止2020年瀏覽器的發(fā)展簡史:

          Timeline_of_the_Web_Browsers


          早期比較有名、有意義的瀏覽器主要包括Erwise、ViolaWWW、Mosaic、Netscape Navigator:

          The-Early-Browsers

          1990年瀏覽器誕生之后的故事,想必您已經(jīng)早有耳聞:

          • 「NCSA Mosaic」,或簡稱 Mosaic,是互聯(lián)網(wǎng)歷史上「第一個獲普遍使用和能夠顯示圖片的網(wǎng)頁瀏覽器」。它由伊利諾伊大學厄巴納-香檳分校的NCSA組織在1993年發(fā)表,并于1997年1月7日正式終止開發(fā)和支持,這款瀏覽器在當時大受歡迎。Mosaic的出現(xiàn),算是點燃了后期互聯(lián)網(wǎng)熱潮的火種之一。后來 Netscape Navigator 瀏覽器的開發(fā),聘用了許多原有的 Mosaic 瀏覽器工程師,但是沒有采用 Mosaic 網(wǎng)頁瀏覽器的任何代碼。而傳承網(wǎng)景瀏覽器代碼的后裔為Firefox瀏覽器。
          • Marc Andreesen 與同事 Jim Clark 于 1994 年成立了一家公司,當時 Mosaic 還是最流行的瀏覽器,它們計劃打造出一個比 Mosaic 更好的瀏覽器,占領(lǐng)市場,讓他們變得富有,并改變歷史。他們的第一個瀏覽器被稱為 Mosaic Netscape 0.9,不久更名 Netscape。得益于 JavaScript(JavaScript誕生于1995年,它是Netscape的Brendan Eich 僅花費十天設計實現(xiàn)的。) 和“partial-screen loading”(即使頁面未完全加載,用戶也可以開始閱讀頁面上的詳細信息,這一個新概念極大地豐富了在線體驗)等功能,它很快成為市場領(lǐng)導者,占據(jù)了瀏覽器市場上一半的份額,最瘋狂的時候,網(wǎng)景瀏覽器的市場份額接近百分之九十。

          1995年8月9日,網(wǎng)景公開募股,最初的價格是14美元一股,但后來陰差陽錯,改為28美元一股發(fā)行,當天收盤時,網(wǎng)景的股票成了75美元一股,網(wǎng)景成為了當時世界上市值最高的互聯(lián)網(wǎng)公司,Netscape 的 IPO 也助長了日益增長的網(wǎng)絡泡沫。

          • Netscape 最初的成功向那些在計算機和互聯(lián)網(wǎng)領(lǐng)域工作的人證明時代已經(jīng)永遠改變了,這讓當時業(yè)內(nèi)最強大的參與者感到震驚,一家名為 Microsoft 的西雅圖公司就是其中之一。計算機將通過瀏覽器運行,瀏覽器可以在任何機器上運行,從而使軟件行業(yè)民主化并降低其相當大的進入壁壘,這導致許多人猜測「操作系統(tǒng)的時代已經(jīng)結(jié)束」。Netscape 對微軟來說是一個挑戰(zhàn),微軟在 1990 年代后期創(chuàng)建了自己的瀏覽器 Internet Explorer,當時的IE和現(xiàn)在一樣,通常被視為劣質(zhì)產(chǎn)品。由于「微軟已經(jīng)建立了銷售其專有操作系統(tǒng) Windows 的帝國」,因此將這種由 Netscape 等公司帶頭的發(fā)展視為一種威脅。微軟通過對其產(chǎn)品的大量投資,使其與 Netscape 一樣好,成功地迅速扭轉(zhuǎn)了瀏覽器行業(yè)的局面。Windows 計算機在發(fā)布時已經(jīng)安裝了 Internet Explorer(Microsoft 的瀏覽器),這使其能夠在市場上占據(jù)一席之地并不斷發(fā)展壯大,最終在瀏覽器領(lǐng)域取得了勝利,這便是著名的「第一次瀏覽器大戰(zhàn)」
          Market_Share_During_the_Browser_Wars

          市場份額的快速下滑導致 Netscape 被出售給了 AOL,2003年7月,網(wǎng)景解散,就在解散的當天,Mozilla基金會成立,2004年基于Mozilla源碼的Firefox首次登臺,拉開了第二次瀏覽器大戰(zhàn)的序幕。2008 年Netscape最終滅絕,「當年的瀏覽器帝國正式退出了歷史的舞臺」

          到 2003 年,微軟的 Internet Explorer 控制了 92% 以上的市場,完全扭轉(zhuǎn)了 1995 年的局面。然而,雖然微軟在不到十年的時間里成功地完全接管了瀏覽器市場,但很快就會出現(xiàn)其他競爭,再次重塑網(wǎng)絡瀏覽器的歷史。

          • 微軟在 1990 年代后期崛起并讓 Netscape 等公司屈服之后,瀏覽器的歷史似乎已經(jīng)走到了盡頭。然而,正如最初發(fā)布后的情況一樣,Internet Explorer 正在成為劣質(zhì)產(chǎn)品。谷歌于 2008 年推出了其專有瀏覽器——Chrome。到 2012 年底,即推出僅四年后,谷歌 Chrome 瀏覽器憑借其易用性、跨平臺功能、速度以及與標簽和書簽相關(guān)的特殊功能,取代 Internet Explorer 成為最受歡迎的瀏覽器。
          • 在 2000 年代初期,可能是在微軟將瀏覽器附加到其操作系統(tǒng)之后,Apple 發(fā)布了 Safari,一種專為 Mac 設計的瀏覽器,并成為目前市場上第二大瀏覽器。
          • Internet Explorer 的流行度在 2000 年代后期逐漸減少,主要是因為它變得緩慢和過時,而 Microsoft 發(fā)現(xiàn)自己現(xiàn)在似乎已經(jīng)是在外面觀察瀏覽器世界。該公司不想繼續(xù)錯過,于是著手解決這個問題,但發(fā)現(xiàn)一個關(guān)鍵問題是“Internet Explorer”這個名字已經(jīng)成為劣質(zhì)瀏覽器的同義詞。因此,為了嘗試重新進入游戲,微軟不得不重新命名,是以,Edge 變誕生了。Edge是微軟瀏覽器的最新版本,它受到了很多好評,但對于 Microsoft 來說,Edge 的出現(xiàn)可能為時已晚。
          • 「IE瀏覽器終成時代之淚,Microsoft Edge 成為Windows 11的默認瀏覽器」。這是Windows系統(tǒng)更新20年來,IE的首次缺席,也是最后一次。早在Win10更新時微軟就表示,將放棄更新IE轉(zhuǎn)向開發(fā)新的瀏覽器Microsoft Edge。如今是徹底要和桌面上的IE說再見了。—— IE 瀏覽器將從 Windows 11 中消失,它也將在 2022 年安息。

          瀏覽器市場份額

          截止2021年7月初,瀏覽器市場份額如下所示。

          瀏覽器使用趨勢變化:

          Web_Browser_Usage_Trends

          瀏覽器市場份額:

          Web_Browser_Market_Share

          國內(nèi)瀏覽器市場份額:

          Web_Browser_Market_Share_CHN

          如果你對以上瀏覽器市場份額數(shù)據(jù)有興趣,可以通過以下鏈接進行查看:

          • 國內(nèi)瀏覽器市場份額
            • 瀏覽器市場份額[1]
          • 全球瀏覽器市場份額
            • 全球瀏覽器市場份額[2]
            • w3counter[3]

          瀏覽器架構(gòu)

          計算機的核心

          三層計算機體系結(jié)構(gòu):底部是機器硬件,中間是操作系統(tǒng),頂部是應用程序。

          hw-os-app

          當你在電腦或手機上啟動應用時,是 「CPU 和 GPU 為應用供能」。通常情況下應用是通過操作系統(tǒng)提供的機制在 CPU 和 GPU 上運行。

          CPU

          中央處理器(Central Processing Unit),或簡稱為 CPU。CPU 可以看作是計算機的大腦。「一個 CPU 核心如圖中的辦公人員,可以逐一解決很多不同任務」。它可以在解決從數(shù)學到藝術(shù)一切任務的同時還知道如何響應客戶要求。過去 CPU 大多是單芯片的。隨著現(xiàn)代硬件發(fā)展,你經(jīng)常會有不止一個內(nèi)核,為你的手機和筆記本電腦提供更多的計算能力。

          4 個 CPU 核心作為辦公人員,坐在辦公桌前處理各自的工作:

          CPU

          GPU

          圖形處理器(Graphics Processing Unit,簡稱為 GPU)是計算機的另一部件。與 CPU 不同,GPU 擅長同時處理跨內(nèi)核的簡單任務。顧名思義,「它最初是為解決圖形而開發(fā)的」。這就是為什么在圖形環(huán)境中“使用 GPU” 或 “GPU 支持”都與快速渲染和順滑交互有關(guān)。近年來隨著 GPU 加速計算的普及,僅靠 GPU 一己之力也使得越來越多的計算成為可能。

          下圖中,許多帶特定扳手的 GPU 內(nèi)核意味著它們只能處理有限任務。

          GPU

          進程與線程

          進程可以被描述為是一個應用的執(zhí)行程序。線程是位于進程內(nèi)部并執(zhí)行其進程程序的任意部分。

          啟動應用時會創(chuàng)建一個進程。程序也許會創(chuàng)建一個或多個線程來幫助它工作。操作系統(tǒng)為進程提供了一個可以使用的“一塊”內(nèi)存,所有應用程序狀態(tài)都保存在該私有內(nèi)存空間中。關(guān)閉應用程序時,相應的進程也會消失,操作系統(tǒng)會釋放內(nèi)存(下圖中,邊界框為進程,線程作為抽象魚在進程中游動)。

          memory

          進程可以請求操作系統(tǒng)啟動另一個進程來執(zhí)行不同的任務。此時,內(nèi)存中的不同部分會分給新進程。如果兩個進程需要對話,他們可以通過**進程間通信(IPC)**來進行。許多應用都是這樣設計的,所以如果一個工作進程失去響應,該進程就可以在不停止應用程序不同部分的其他進程運行的情況下重新啟動。

          workerprocess.gif

          瀏覽器的進程/線程架構(gòu)模型

          瀏覽器進程分類

          關(guān)于如何「構(gòu)建 web 瀏覽器并不存在標準規(guī)范」,一個瀏覽器的構(gòu)建方法可能與另一個迥然不同。不同瀏覽器的進程/線程架構(gòu)一般由下圖幾部分:

          browser-arch

          Chrome多進程架構(gòu)

          而當下“瀏覽器世界的王者” Chrome 架構(gòu)如下圖所示,渲染進程下顯示了多個層,表明 Chrome 為每個標簽頁運行多個渲染進程。

          browser-arch-chrome

          上圖中,頂部是瀏覽器進程,它與處理應用其它模塊任務的進程進行協(xié)調(diào)。對于渲染進程來說,創(chuàng)建了多個渲染進程并分配給了每個標簽頁。Chrome 在可能的情況下會給每個標簽頁分配一個進程。而現(xiàn)在它試圖給每個站點分配一個進程,包括 iframe。

          • 瀏覽器進程:控制應用中的 “Chrome” 部分,包括地址欄,書簽,回退與前進按鈕,以及處理 web 瀏覽器中網(wǎng)絡請求、文件訪問等不可見的特權(quán)部分;
          • 渲染進程:控制標簽頁內(nèi)網(wǎng)站展示;
          • 插件進程:控制站點使用的任意插件,如 Flash;
          • GPU進程:處理獨立于其它進程的 GPU 任務。GPU 被分成不同進程,因為 GPU 處理來自多個不同應用的請求并繪制在相同表面。

          可以簡單理解為不同進程對應瀏覽器 UI 的不同部分:

          browserui

          「Chrome 更多的是把自己抽象為一個操作系統(tǒng),網(wǎng)頁或擴展相當于一個個程序」,你甚至可以發(fā)現(xiàn),Chrome 確實自帶了一個任務管理器,在任務管理器面板會列出當前正在運行的進程以及它們當前的 CPU/內(nèi)存使用量情況等信息。

          一般你可以通過兩種方法打開Chrome任務管理器:

          • 通過在瀏覽器頂欄(標簽tab欄)右側(cè)右鍵,選擇任務管理器查看;
          • 點擊 Chrome 瀏覽器右上角的“選項”菜單(一般是三個點的標識),選擇“更多工具”子菜單,點擊“任務管理器”,打開任務管理器窗口。
          task

          前文中提到了 Chrome 使用多個渲染進程,那他有什么優(yōu)勢呢?

          • 穩(wěn)定性:最簡單的情況下,你可以想象每個標簽頁都有自己的渲染進程。假設你打開了三個標簽頁,每個標簽頁都擁有自己獨立的渲染進程。如果某個標簽頁失去響應,你可以關(guān)掉這個標簽頁,此時其它標簽頁依然運行著,可以正常使用。如果所有標簽頁都運行在同一進程上,那么當某個失去響應,所有標簽頁都會失去響應,顯然這樣的體驗會很糟糕。下面是多/單進程架構(gòu)的對比動圖,供你參考。
          tabs.gif
          • 安全性與沙箱化:把瀏覽器工作分成多個進程的另一好處是安全性與沙箱化。由于操作系統(tǒng)提供了限制進程權(quán)限的方法,瀏覽器就可以用沙箱保護某些特定功能的進程。例如,Chrome 瀏覽器可以限制處理用戶輸入(如渲染器)的進程的文件訪問的權(quán)限。

          由于進程有自己的私有內(nèi)存空間,所以它們通常包含公共基礎設施的拷貝(如Chrome V8引擎)。這意味著使用了更多的內(nèi)存,如果它們是同一進程中的線程,就無法共享這些拷貝(同一個進程中的線程不共享堆棧,堆棧是保證線程獨立運行所必須的)。為了節(jié)省內(nèi)存,Chrome 對可啟動的進程數(shù)量有所限制。具體限制數(shù)值依設備可提供的內(nèi)存與 CPU 能力而定,但是「當 Chrome 運行時達到限制時,會開始在同一站點的不同標簽頁上運行同一進程」

          Chrome 正在經(jīng)歷架構(gòu)變革,它轉(zhuǎn)變?yōu)閷g覽器程序的每一模塊作為一個服務來運行,從而可以輕松實現(xiàn)進程的拆解或聚合。具體表現(xiàn)是,當 Chrome 運行在「強力硬件」上時,它會將每個服務分解到不同進程中,從而「提升穩(wěn)定性」,但是如果 Chrome 運行在資源有限的設備上時,它會將服務聚合到一個進程中從而「節(jié)省了內(nèi)存占用」。在這一架構(gòu)變革實現(xiàn)前,類似的整合進程以減少內(nèi)存使用的方法已經(jīng)在 Android 類平臺上使用。

          servicfication.gif

          Chrome 67 版本后,桌面版 Chrome 都默認開啟了「站點隔離」,每個標簽頁的 iframe 都有一個單獨的渲染進程。啟用站點隔離是多年來工程人員努力的結(jié)果。站點隔離并不只是分配不同的渲染進程這么簡單。它從根本上改變了 iframe 的通信方式。在一個頁面上打開開發(fā)者工具,讓 iframe 在不同的進程上運行,這意味著開發(fā)者工具必須在幕后工作,以使它看起來無縫。即使運行一個簡單的 Ctrl + F 來查找頁面中的一個單詞,也意味著在不同的渲染器進程中進行搜索。你可以看到為什么「瀏覽器工程師把發(fā)布站點隔離功能作為一個重要里程碑」

          isolation

          延伸閱讀:Chrome 為什么多進程而不是多線程?[4]

          瀏覽器整體架構(gòu)

          如果您是一名前端工程師,那么,面試時你大概率會被問到過:從 URL 輸入到頁面展現(xiàn)到底發(fā)生了什么?,如果您對這一過程不太熟悉,建議看看下面兩篇文章,在此不過多贅述:

          • 經(jīng)典面試題:從 URL 輸入到頁面展現(xiàn)到底發(fā)生什么?[5]
          • 在瀏覽器輸入 URL 回車之后發(fā)生了什么(超詳細版)[6]

          瀏覽器的主要任務之一就是渲染展示頁面,不同的瀏覽器內(nèi)核,渲染過程也不完全相同,但大致流程都差不多,下面這張圖片是火狐瀏覽器(Firefox,可以認為是Netscapede的涅槃重生)開發(fā)文檔中的一張圖片。

          瀏覽器架構(gòu)

          上面這張圖片大體揭示了瀏覽器的渲染展示流程,但是從瀏覽器的整體架構(gòu)上來說,上面的圖片展示的也許只是瀏覽器體系中的冰山一角。

          通常意義下,瀏覽器架構(gòu)是如下圖這樣的:

          瀏覽器架構(gòu)

          用戶界面

          包括地址欄、前進/后退按鈕、書簽菜單等。除了瀏覽器主窗口顯示的您請求的頁面外,其他顯示的各個部分都屬于用戶界面。

          瀏覽器引擎

          用戶界面和渲染引擎的橋梁,在用戶界面和渲染引擎之間傳送指令。瀏覽器引擎提供了開始加載URL資源 和一些其他高級操作方法,比如:重新加載、前進、后退動作,錯誤信息、加載進度等。

          渲染引擎

          負責顯示請求的內(nèi)容。如果請求的內(nèi)容是 HTML,它就負責解析 HTML 和 CSS 內(nèi)容,并將解析后的內(nèi)容顯示在屏幕上。

          所謂瀏覽器內(nèi)核就是指瀏覽器最重要或者說核心的部分"Rendering Engine",譯為"渲染引擎"。負責對網(wǎng)頁語法的解析,比如HTML、JavaScript,并渲染到網(wǎng)頁上。所以瀏覽器內(nèi)核也就是瀏覽器所采用的渲染引擎,渲染引擎決定這瀏覽器如何顯示頁面的內(nèi)容和頁面的格式信息。不同的瀏覽器內(nèi)核對語法的解釋也不相同,因此同一網(wǎng)頁在不同內(nèi)核的瀏覽器顯示的效果也會有差異(瀏覽器兼容)。這也就是網(wǎng)頁開發(fā)者在不需要同內(nèi)核的瀏覽器中測試網(wǎng)頁顯示效果的原因。

          RENDERING ENGINE

          延伸閱讀:曾紅極一時的紅芯瀏覽器,官網(wǎng)對其介紹是:擁有智能的認證引擎、渲染引擎、管控引擎,而且還有強大的“國密通訊協(xié)議”,支持統(tǒng)一管控、遠程控制。2018年8月15日,紅芯瀏覽器被爆出打開安裝目錄后出現(xiàn)大量和谷歌Chrome瀏覽器一致的同名文件,其安裝程序的文件屬性中也顯示了原始文件名chrome.exe,紅芯瀏覽器的官網(wǎng)已撤下了瀏覽器的下載鏈接。8月16日,紅芯聯(lián)合創(chuàng)始人高婧回應,紅芯瀏覽器“包含‘Chrome’在里面”,但并非抄襲,而是“站在巨人的肩膀上去做創(chuàng)新”。

          hongxin

          言歸正傳,瀏覽器內(nèi)核主要包括以下三個技術(shù)分支:排版渲染引擎、 JavaScript引擎,以及其他。

          排版引擎:

          • KHTML:KHTML,是HTML網(wǎng)頁排版引擎之一,由KDE所開發(fā)。KHTML擁有速度快捷的優(yōu)點,但對錯誤語法的容忍度則比Mozilla產(chǎn)品所使用的Gecko引擎小。蘋果電腦于2002年采納了KHTML,作為開發(fā)Safari瀏覽器之用,并發(fā)布所修改的最新及過去版本源代碼。「后來發(fā)表的開源WebCore及WebKit引擎,它們均是KHTML的衍生產(chǎn)品」
          • WebCore:WebCore是「蘋果公司」開發(fā)的排版引擎,它是在另外一個排版引擎“KHTML”的基礎上而來的。使用WebCore的主要有Safari瀏覽器。

          瀏覽器的內(nèi)核引擎,基本上是四分天下:

          • Trident: IE 以Trident 作為內(nèi)核引擎;
          • Gecko: Firefox 是基于 Gecko 開發(fā);
          • WebKit: 誕生于1998年,并于2005年由Apple公司開源,Safari, Google Chrome,傲游3,獵豹瀏覽器,百度瀏覽器 opera瀏覽器 基于 Webkit 開發(fā)。
          • Presto: Opera的內(nèi)核,但由于市場選擇問題,主要應用在手機平臺--Opera mini。(2013年2月Opera宣布轉(zhuǎn)向WebKit引擎,2013年4月Opera宣布放棄WEBKIT,跟隨GOOGLE的新開發(fā)的blink引擎。)

          需要略作補充的是,我們經(jīng)常還會聽到Chromium、Webkit2、Blink這些引擎。

          • Chromium:基于webkit,08年開始作為Chrome的引擎,Chromium瀏覽器是Chrome的實驗版,實驗新特性。可以簡單地理解為:Chromium為實驗版,具有眾多新特性;Chrome為穩(wěn)定版。
          chromium 架構(gòu)

          圖片來源:萬字詳文:深入理解瀏覽器原理[7]

          • Webkit2:2010年隨OS X Lion一起面世。WebCore層面實現(xiàn)進程隔離與Google的沙箱設計存在沖突。
          • Blink:基于Webkit2分支,是WebKit中WebCore組件的一個分支,13年谷歌開始作為Chrome 28的引擎集成在Chromium瀏覽器里。Android的WebView同樣基于Webkit2,是現(xiàn)在對新特性支持度最好的內(nèi)核。Opera(15及往后版本)和Yandex瀏覽器中也在使用。
          • 移動端基本上全部是 Webkit 或 Blink 內(nèi)核(除去 Android 上騰訊家的 X5),這兩個內(nèi)核對新特性的支持度較高,所以新特性可以在移動端大展身手。

          各內(nèi)核關(guān)系圖:

          KHTML

          下面我們以WebKit為列,進行簡單介紹,以便讓你對渲染引擎有一個更多的理解。WebKit由多個重要模塊組成,通過下圖我們可以對WebKit有個整體的了解:

          WebKit

          WebKit就是一個「頁面渲染以及邏輯處理引擎」,前端工程師把HTML、JavaScript、CSS這“三駕馬車”作為輸入,經(jīng)過WebKit的處理,就輸出成了我們能看到以及操作的Web頁面。從上圖我們可以看出來,WebKit由圖中框住的四個部分組成。而其中最主要的就是WebCore和JSCore(或者是其它JS引擎)。除此之外,WebKit Embedding API是負責瀏覽器UI與WebKit進行交互的部分,而WebKit Ports則是讓Webkit更加方便的移植到各個操作系統(tǒng)、平臺上,提供的一些調(diào)用Native Library的接口,比如在渲染層面,在iOS系統(tǒng)中,Safari是交給CoreGraphics處理,而在Android系統(tǒng)中,Webkit則是交給Skia。

          WebKit的渲染流程:

          WebKit-Rendering

          首先瀏覽器通過URL定位到了一堆由HTML、CSS、JS組成的資源文件,通過加載器把資源文件給WebCore。之后HTML Parser會把HTML解析成DOM樹,CSS Parser會把CSS解析成CSSOM樹。最后把這兩棵樹合并,生成最終需要的渲染樹,再經(jīng)過布局,與具體WebKit Ports的渲染接口,把渲染樹渲染輸出到屏幕上,成為了最終呈現(xiàn)在用戶面前的Web頁面。

          網(wǎng)絡

          用于網(wǎng)絡調(diào)用,比如 HTTP 請求。其接口與平臺無關(guān),并為所有平臺提供底層實現(xiàn),負責網(wǎng)絡通信和安全。

          JavaScript 解釋器

          用于解析和執(zhí)行 JavaScript 代碼,執(zhí)行結(jié)果將傳遞給渲染引擎來展示。

          用戶界面后端

          用于繪制基本的窗口小部件,比如組合框和窗口。其公開了與平臺無關(guān)的通用接口,而在底層使用操作系統(tǒng)的用戶界面方法。

          數(shù)據(jù)存儲

          這是持久層,瀏覽器需要在硬盤上保存各種數(shù)據(jù),例如 Cookie。新的 HTML 規(guī)范 (HTML5) 定義了“網(wǎng)絡數(shù)據(jù)庫”,這是一個完整而輕便的瀏覽器內(nèi)數(shù)據(jù)庫。

          求同存異的瀏覽器架構(gòu)

          下面列出了部分瀏覽器的架構(gòu)圖,也許有些架構(gòu)已經(jīng)改變,有興趣可以簡單參考看看,除了IE之外,大體上各瀏覽器的整體架構(gòu)都是類似的。

          Mosaic架構(gòu):

          Architecture_of_Mosaic

          Firefox架構(gòu):

          Architecture_of_Mozilla

          Chrome架構(gòu):

          Architecture_of_Chrome

          Safari架構(gòu):

          Architecture_of_Safari

          IE架構(gòu):

          IE架構(gòu)

          瀏覽器基本原理

          Chrome V8

          V8一詞最早見于“V-8 engine”,即V8發(fā)動機,一般使用在中高端車輛上。8個氣缸分成兩組,每組4個,成V型排列。是高層次汽車運動中最常見的發(fā)動機結(jié)構(gòu),尤其在美國,IRL,ChampCar和NASCAR都要求使用V8發(fā)動機。

          關(guān)于Chrome V8,筆者曾有一篇筆記做了比較詳細的介紹,全文脈絡如下,感興趣可以參考閱讀[8]

          Chrome-V8

          V8是依托Chrome發(fā)展起來的,后面確不局限于瀏覽器內(nèi)核。發(fā)展至今V8應用于很多場景,例如流行的nodejs,weex,快應用,早期的RN。V8曾經(jīng)歷過一次比較大的架構(gòu)調(diào)整,主要變化在于“從字節(jié)碼的放棄到真香”。

          V8 的早期架構(gòu)

          V8引擎誕生的使命就是要在速度和內(nèi)存回收上進行革命。JavaScriptCore的架構(gòu)是采用生成字節(jié)碼的方式,然后執(zhí)行字節(jié)碼。Google覺得JavaScriptCore這套架構(gòu)不行,生成字節(jié)碼會浪費時間,不如直接生成機器碼快。所以V8在前期的架構(gòu)設計上是非常激進的,采用了直接編譯成機器碼的方式。后期的實踐證明Google的這套架構(gòu)速度是有改善,但是同時也造成了「內(nèi)存消耗問題」

          V8-2010

          早期的V8有Full-Codegen和Crankshaft兩個編譯器。V8 首先用 Full-Codegen把所有的代碼都編譯一次,生成對應的機器碼。JS在執(zhí)行的過程中,V8內(nèi)置的Profiler篩選出熱點函數(shù)并且記錄參數(shù)的反饋類型,然后交給 Crankshaft 來進行優(yōu)化。所以Full-Codegen本質(zhì)上是生成的是未優(yōu)化的機器碼,而Crankshaft生成的是優(yōu)化過的機器碼。

          隨著網(wǎng)頁的復雜化,V8也漸漸的暴露出了自己架構(gòu)上的缺陷:

          • Full-Codegen 編譯直接生成機器碼,導致「內(nèi)存占用大」
          • Full-Codegen 編譯直接生成機器碼,導致「編譯時間長」,導致「啟動速度慢」
          • Crankshaft 無法優(yōu)化try,catch和finally等關(guān)鍵字劃分的代碼塊;
          • Crankshaft 新加語法支持,需要為此編寫適配不同的Cpu架構(gòu)代碼。

          V8 的現(xiàn)有架構(gòu)

          為了解決上述缺點,V8借鑒JavaScriptCore的架構(gòu),生成字節(jié)碼。V8采用生成字節(jié)碼的方式后,整體流程如下圖:

          V8-2017

          現(xiàn)在的 V8 是一個非常復雜的項目,有超過 100 萬行 C++代碼。它由許多子模塊構(gòu)成,其中這 4 個模塊是最重要的:

          • Parser[9]:負責將 JavaScript 源碼轉(zhuǎn)換為 Abstract Syntax Tree (AST)

            確切的說,在“Parser”將 JavaScript 源碼轉(zhuǎn)換為 AST前,還有一個叫”Scanner“的過程,具體流程如下:

            Scanner
          • Ignition[10]:interpreter,即解釋器,負責將 AST 轉(zhuǎn)換為 Bytecode,解釋執(zhí)行 Bytecode;同時收集 TurboFan 優(yōu)化編譯所需的信息,比如函數(shù)參數(shù)的類型;解釋器執(zhí)行時主要有四個模塊,內(nèi)存中的字節(jié)碼、寄存器、棧、堆。Ignition的原始動機是減少移動設備上的內(nèi)存消耗。在Ignition之前,V8的Full-codegen基線編譯器生成的代碼通常占據(jù)Chrome整體JavaScript堆的近三分之一。這為Web應用程序的實際數(shù)據(jù)留下了更少的空間。Ignition的字節(jié)碼可以直接用TurboFan生成優(yōu)化的機器代碼,而不必像Crankshaft那樣從源代碼重新編譯。Ignition的字節(jié)碼在V8中提供了更清晰且更不容易出錯的基線執(zhí)行模型,簡化了去優(yōu)化機制,這是V8 自適應優(yōu)化的關(guān)鍵特性。最后,由于生成字節(jié)碼比生成Full-codegen的基線編譯代碼更快,因此激活I(lǐng)gnition通常會改善腳本啟動時間,從而改善網(wǎng)頁加載。

          • TurboFan[11]:compiler,即優(yōu)化編譯器,利用 Ignition 所收集的類型信息,將 Bytecode 轉(zhuǎn)換為優(yōu)化的匯編代碼;TurboFan項目最初于2013年底啟動,旨在解決Crankshaft的缺點。Crankshaft只能優(yōu)化JavaScript語言的子集。例如,它不是設計用于使用結(jié)構(gòu)化異常處理優(yōu)化JavaScript代碼,即由JavaScript的try,catch和finally關(guān)鍵字劃分的代碼塊。很難在Crankshaft中添加對新語言功能的支持,因為這些功能幾乎總是需要為九個支持的平臺編寫特定于體系結(jié)構(gòu)的代碼。

          • Orinoco[12]:garbage collector,垃圾回收模塊,負責將程序不再需要的內(nèi)存空間回收。

          采用新的Ignition+TurboFan架構(gòu)后,比Full-codegen+Crankshaft架構(gòu)內(nèi)存降低一半多,且70%左右的網(wǎng)頁速度得到了提升。

          在運行 C、C++以及 Java 等程序之前,需要進行編譯,不能直接執(zhí)行源碼;但對于 JavaScript 來說,我們可以直接執(zhí)行源碼(比如:node test.js),它是在運行的時候先編譯再執(zhí)行,這種方式被稱為「即時編譯(Just-in-time compilation)」,簡稱為 JIT。因此,V8 也屬于 「JIT 編譯器」

          JavaScriptCore

          V8未誕生之前,早期主流的JavaScript引擎是JavaScriptCore引擎。JavaScriptCore(以下簡稱JSCore)主要服務于Webkit瀏覽器內(nèi)核,他們都是由蘋果公司開發(fā)并開源出來。JSCore是WebKit默認內(nèi)嵌的JS引擎,之所以說是默認內(nèi)嵌,是因為很多基于WebKit分支開發(fā)的瀏覽器引擎都開發(fā)了自家的JS引擎,其中最出名的就是前文提到的Chrome的V8。這些「JS引擎的使命都是解釋執(zhí)行JS腳本」。而在渲染流程上,JS和DOM樹之間存在著互相關(guān)聯(lián),這是因為瀏覽器中的JS腳本最主要的功能就是操作DOM樹,并與之交互。我們可以通過下圖看下它的工作流程:

          JavaScriptCore

          JavaScriptCore主要模塊:「Lexer 詞法分析器,將腳本源碼分解成一系列的Token;Parser 語法分析器,處理Token并生成相應的語法樹;LLInt 低級解釋器,執(zhí)行Parser生成的二進制代碼;Baseline JIT 基線JIT(just in time 實時編譯);DFG 低延遲優(yōu)化的JIT;FTL 高通量優(yōu)化的JIT」

          可以看到,相比靜態(tài)編譯語言生成語法樹之后,還需要進行鏈接,裝載生成可執(zhí)行文件等操作,解釋型語言在流程上要簡化很多。這張流程圖右邊畫框的部分就是JSCore的組成部分:Lexer(詞法分析)、Parser(語法分析)、LLInt以及JIT(解釋執(zhí)行)的部分(之所以JIT的部分是用橙色標注,是因為并不是所有的JSCore中都有JIT部分)。

          • 「詞法分析」很好理解,就是「把一段我們寫的源代碼分解成Token序列的過程」,這一過程也叫「分詞」。在JSCore,詞法分析是由Lexer來完成(有的編譯器或者解釋器把分詞叫做Scanner,比如Chrome v8)。
          • 跟人類語言一樣,我們講話的時候其實是按照約定俗成,交流習慣按照一定的語法講出一個又一個詞語。那類比到計算機語言,計算機要理解一門計算機語言,也要理解一個語句的語法。「Parser會把Lexer分析之后生成的token序列進行語法分析,并生成對應的一棵抽象語法樹(AST)」。之后,ByteCodeGenerator會根據(jù)AST來生成JSCore的字節(jié)碼,完成整個「語法解析」步驟。
          • JS源代碼經(jīng)過了詞法分析和語法分析這兩個步驟,轉(zhuǎn)成了字節(jié)碼,其實就是經(jīng)過任何一門程序語言必經(jīng)的步驟–編譯。但是不同于我們編譯運行OC代碼,JS編譯結(jié)束之后,并不會生成存放在內(nèi)存或者硬盤之中的目標代碼或可執(zhí)行文件。生成的指令字節(jié)碼,會被立即被JSCore這臺虛擬機進行逐行「解釋執(zhí)行」。運行指令字節(jié)碼(ByteCode)是JS引擎中很核心的部分,各家JS引擎的優(yōu)化也主要集中于此。

          PS:嚴格的講,語言本身并不存在編譯型或者是解釋型,因為語言只是一些抽象的定義與約束,并不要求具體的實現(xiàn),執(zhí)行方式。這里講JS是一門“解釋型語言”只是JS一般是被JS引擎動態(tài)解釋執(zhí)行,而并不是語言本身的屬性。

          如果對JavaScriptCore有更多興趣,關(guān)于JavaScriptCore的更多細節(jié),建議延伸閱讀以下幾篇博文:

          • 深入理解JSCore[13]
          • 深入剖析 JavaScriptCore[14]
          • JavaScriptCore 全面解析[15]
          • 深入淺出 JavaScriptCore[16]

          瀏覽器與JavaScript

          這一小結(jié),還是以Chrome V8為例,簡單闡述瀏覽器與JavaScript的關(guān)系。

          「V8 出現(xiàn)之前,所有的 JavaScript 虛擬機所采用的都是解釋執(zhí)行的方式,這是 JavaScript 執(zhí)行速度過慢的一個主要原因」。而 V8 率先引入了「即時編譯(JIT)**的**雙輪驅(qū)動」的設計(混合使用編譯器和解釋器的技術(shù)),這是一種權(quán)衡策略,「混合編譯執(zhí)行和解釋執(zhí)行這兩種手段」,給 JavaScript 的執(zhí)行速度帶來了極大的提升。V8 出現(xiàn)之后,各大廠商也都在自己的 JavaScript 虛擬機中引入了 JIT 機制,所以目前市面上 JavaScript 虛擬機都有著類似的架構(gòu)。另外,「V8 也是早于其他虛擬機引入了惰性編譯、內(nèi)聯(lián)緩存、隱藏類等機制,進一步優(yōu)化了 JavaScript 代碼的編譯執(zhí)行效率」

          V8 執(zhí)行一段 JavaScript 的流程

          V8 執(zhí)行一段 JavaScript 的流程如下圖所示:

          V8執(zhí)行一段JavaScript流程圖

          結(jié)合上文介紹的Chrome V8 架構(gòu),聚焦到JavaScript上,瀏覽器拿到JavaScript源碼,Parser,Ignition 以及 TurboFan 可以將 JS 源碼編譯為匯編代碼,其流程圖如下:

          V8流程

          簡單地說,Parser 將 JS 源碼轉(zhuǎn)換為 AST,然后 Ignition 將 AST 轉(zhuǎn)換為 Bytecode,最后 TurboFan 將 Bytecode 轉(zhuǎn)換為經(jīng)過優(yōu)化的 Machine Code(實際上是匯編代碼)。

          • 如果函數(shù)沒有被調(diào)用,則 V8 不會去編譯它。
          • 如果函數(shù)只被調(diào)用 1 次,則 Ignition 將其編譯 Bytecode 就直接解釋執(zhí)行了。TurboFan 不會進行優(yōu)化編譯,因為它需要 Ignition 收集函數(shù)執(zhí)行時的類型信息。這就要求函數(shù)至少需要執(zhí)行 1 次,TurboFan 才有可能進行優(yōu)化編譯。
          • 如果函數(shù)被調(diào)用多次,則它有可能會被識別為「熱點函數(shù)」,且 Ignition 收集的類型信息證明可以進行優(yōu)化編譯的話,這時 TurboFan 則會將 Bytecode 編譯為 Optimized Machine Code(已優(yōu)化的機器碼),以提高代碼的執(zhí)行性能。

          圖片中的紅色虛線是逆向的,也就是說 Optimized Machine Code 會被還原為 Bytecode,這個過程叫做 「Deoptimization」。這是因為 Ignition 收集的信息可能是錯誤的,比如 add 函數(shù)的參數(shù)之前是整數(shù),后來又變成了字符串。生成的 Optimized Machine Code 已經(jīng)假定 add 函數(shù)的參數(shù)是整數(shù),那當然是錯誤的,于是需要進行 Deoptimization。

          function add(x, y{
            return x + y;
          }

          add(12);
          add('1''2');

          「V8 本質(zhì)上是一個虛擬機」,因為計算機只能識別二進制指令,所以要讓計算機執(zhí)行一段高級語言通常有兩種手段:

          • 第一種是將高級代碼轉(zhuǎn)換為二進制代碼,再讓計算機去執(zhí)行;
          • 另外一種方式是在計算機安裝一個解釋器,并由解釋器來解釋執(zhí)行。
          • 解釋執(zhí)行和編譯執(zhí)行都有各自的優(yōu)缺點,「解釋執(zhí)行啟動速度快,但是執(zhí)行時速度慢,而編譯執(zhí)行啟動速度慢,但是執(zhí)行速度快」。為了充分地利用解釋執(zhí)行和編譯執(zhí)行的優(yōu)點,規(guī)避其缺點,「V8 采用了一種權(quán)衡策略,在啟動過程中采用了解釋執(zhí)行的策略,但是如果某段代碼的執(zhí)行頻率超過一個值,那么 V8 就會采用優(yōu)化編譯器將其編譯成執(zhí)行效率更加高效的機器代碼」

          簡單總結(jié)如下,「V8 執(zhí)行一段 JavaScript 代碼所經(jīng)歷的主要流程」包括:

          • 初始化基礎環(huán)境;
          • 解析源碼生成 AST 和作用域;
          • 依據(jù) AST 和作用域生成字節(jié)碼;
          • 解釋執(zhí)行字節(jié)碼;
          • 監(jiān)聽熱點代碼;
          • 優(yōu)化熱點代碼為二進制的機器代碼;
          • 反優(yōu)化生成的二進制機器代碼。

          Chrome V8 的事件機制

          關(guān)于異步編程和消息隊列,UI 線程提供一個消息隊列,并將待執(zhí)行的事件添加到消息隊列中,然后 UI 線程會不斷循環(huán)地從消息隊列中取出事件、執(zhí)行事件,通用 UI 線程宏觀架構(gòu)如下圖所示:

          v8-ui

          瀏覽器的不同形態(tài)

          WebView

          「WebView 是一種嵌入式瀏覽器,原生應用可以用它來展示網(wǎng)絡內(nèi)容」。WebView 只是一個「可視化的」組件/控件/微件等。這樣我們可以用它來作為我們原生 app 的視覺部分。當你使用原生應用時,WebView 可能只是被隱藏在普通的原生 UI 元素中,你甚至用不到注意到它。

          如果你把瀏覽器想象成兩部分,一部分是 UI(地址欄,導航欄按鈕等),其它部分是把標記跟代碼轉(zhuǎn)換成我們可見和可交互視圖的引擎。「WebView 就是瀏覽器引擎部分」,你可以像插入 iframe 一樣將 Webview 插入到你的原生應用中,并且編程化的告訴它將會加載什么網(wǎng)頁內(nèi)容。

          運行在你的 WebView 中的 JavaScript 有能力調(diào)用原生的系統(tǒng) API。這意味著你不必受到 Web 代碼通常必須遵守的傳統(tǒng)瀏覽器安全沙箱的限制。下圖解釋了使用這種技術(shù)后的架構(gòu)差異:

          webview and webapp

          默認情況下,在 WebView 或 Web 瀏覽器中運行的任何 Web 代碼都與應用的其余部分保持隔離。這樣做是出于安全原因,主要是為降低惡意的 JavaScript 代碼對系統(tǒng)造成的傷害。對于任意 Web 內(nèi)容,這種安全級別很有意義,因為你永遠不能完全信任加載的 Web 內(nèi)容。但 WebView 的情況并非如此,對于 WebView 方案,開發(fā)人員通常可以完全控制加載的內(nèi)容。惡意代碼進入并在設備上造成混亂的可能性非常低。

          「這就是為什么對于 WebView,開發(fā)人員可以使用各種受支持的方式來覆蓋默認的安全行為,并讓 Web 代碼和原生應用代碼相互通信。這種溝通通常稱為 bridge」。你可以在上文的圖片中看到 bridge 可視化為 Native Bridge 和 JavaScript Bridge 的一部分。

          WebView 非常好,雖然它看起來像是完全特殊和獨特的,但請記住,它們只不過是一個在應用中設置好位置和大小的、沒有任何花哨 UI 的瀏覽器,這就是它的精髓。大多數(shù)情況下,除非您調(diào)用原生 API,否則您不必在 WebView 中專門測試您的 Web 應用程序。此外,您在 WebView 中看到的內(nèi)容與您在瀏覽器中看到的內(nèi)容相同,尤其是使用同一渲染引擎時:

          • 在 iOS 上,Web 渲染引擎始終是 WebKit,與 Safari 和 Chrome 相同。是的,你沒看錯。iOS 上的 Chrome 實際上使用了 WebKit。
          • 在 Android 上的渲染引擎通常是 Blink,與 Chrome 相同。
          • 在 Windows,Linux 和 macOS 上,由于這些是更寬松的桌面平臺,因此在選擇 WebView 風格和渲染引擎時會有很大的靈活性。你看到的流行渲染引擎將是 Blink(Chrome)和 Trident(Internet Explorer),但是沒有一個引擎可以依賴。這完全取決于應用以及它正在使用的 WebView 引擎。

          WebView 的應用:

          • WebView 最常見的用途之一是顯示鏈接的內(nèi)容;
          • 廣告仍然是原生應用最流行的賺錢方式之一,大多數(shù)廣告是通過 WebView 提供的 Web 內(nèi)容進行投放的;
          • Hybrid Apps,混合應用程序很受歡迎有幾個原因,最大的一個是提高開發(fā)人員的生產(chǎn)力。如果你有一個可以在瀏覽器中運行的響應式 Web 應用程序,那么讓相同的應用程序在各種設備上與混合應用程序一起運行是相當簡單的;當你對 Web 應用進行更新時,所有使用它的設備都可以立即使用該更改,因為內(nèi)容來自一個集中的服務器,而如果是純原生應用,部署和更新時,你將不得不經(jīng)歷針對每個平臺的構(gòu)建、審核;
          • 原生應用擴展,如 Microsoft Office 中類似維基百科這樣的基于網(wǎng)絡的擴展就是通過一個 WebView 實現(xiàn)的。

          如果你對 WebView 感興趣,可通過以下幾篇文章繼續(xù)了解:

          • 7.5.1 WebView(網(wǎng)頁視圖)基本用法[17]
          • Android:這是一份全面 & 詳細的Webview使用攻略[18]

          Headless browser

          「無頭瀏覽器」是一種未配置圖形用戶界面 (GUI) 的 Web 瀏覽器,通常通過命令行或網(wǎng)絡通信來執(zhí)行。它主要由軟件測試工程師使用,沒有 GUI 的瀏覽器執(zhí)行速度更快,因為它們不必繪制視覺內(nèi)容。無頭瀏覽器的最大好處之一是它們能夠在沒有 GUI 支持的服務器上運行。

          Headless 瀏覽器對于測試網(wǎng)頁特別有用,因為它們能夠像瀏覽器一樣呈現(xiàn)和理解超文本標記語言,包括頁面布局、顏色、字體選擇以及JavaScript和AJAX的執(zhí)行等樣式元素,這些元素在使用其他測試方法時通常是不可用的。

          Headless_architecture

          Headless 瀏覽器有兩個主要可交付成果:

          • 無頭庫,它允許嵌入應用程序控制瀏覽器并與網(wǎng)頁交互。
          • 一個無頭外殼,它是一個示例應用程序,用于執(zhí)行無頭 API 的各種功能。
          Architecture_of_Puppeteer

          Puppeteer 是一個 Node 庫,他提供了一組用來操縱 Chrome 的 API, 通俗來說就是一個 headless chrome 瀏覽器 (當然你也可以配置成有 UI 的,默認是沒有的)。既然是瀏覽器,那么我們手工可以在瀏覽器上做的事情 Puppeteer 都能勝任, 另外,Puppeteer 翻譯成中文是”木偶”意思,所以聽名字就知道,操縱起來很方便,你可以很方便的操縱她去實現(xiàn):

          1) 生成網(wǎng)頁截圖或者 PDF 2) 高級爬蟲,可以爬取大量異步渲染內(nèi)容的網(wǎng)頁 3) 實現(xiàn) UI 自動化測試,模擬鍵盤輸入、表單自動提交、點擊、登錄網(wǎng)頁等 4) 捕獲站點的時間線,以便追蹤你的網(wǎng)站,幫助分析網(wǎng)站性能問題 5) 模擬不同的設備 6) ...

          Puppeteer 跟 webdriver 以及 PhantomJS 最大的 的不同就是它是站在用戶瀏覽的角度,而 webdriver 和 PhantomJS 最初設計就是用來做自動化測試的,所以它是站在機器瀏覽的角度來設計的,所以它們 使用的是不同的設計哲學。

          • Headless Chrome architecture[19]
          • puppeteer[20]
          • Puppeteer 入門教程[21]
          • 結(jié)合項目來談談 Puppeteer[22]

          Electron

          Electron(原名為Atom Shell)是 GitHub 開發(fā)的一個開源框架。它通過使用 Node.js(作為后端)和Chromium 的渲染引擎(作為前端)完成跨平臺的桌面 GUI 應用程序的開發(fā)。現(xiàn)已被多個開源 Web 應用程序用于前端與后端的開發(fā),著名項目包括 GitHub 的 Atom 和微軟的 Visual Studio Code。

          Electron

          Electron Architecture 由多個 Render Process 和一個 Main 進程組成。Main Process 啟動Render Process,它們之間的通信是通過IPC [Inter Process Communication],如下圖所示。

          Electron_Architecture

          我們常用的IDE VSCode 就是基于 Electron (原來叫 Atom Shell) 進行開發(fā)的。如下圖所示,(點擊 VSCode 幫助【Help】 下的 切換開發(fā)人員工具即可打開以下面板)。

          VSCode

          VS Code 的其他的主要組件有:

          • 殼:Monaco Editor[23]
          • 內(nèi)核:Language Server Protocol[24](一個代碼編輯器)
          • Debug Adapter Protocol[25]
          • Xterm.js[26]

          延伸閱讀:Electron | Build cross-platform desktop apps with JavaScript, HTML, and CSS[27]

          瀏覽器代碼兼容性測試

          • caniuse[28]
          • browseemall[29]
          • html5test[30]

          延伸閱讀

          • 瀏覽器簡史[31]
          • Web 瀏覽器相關(guān)的一些概念[32]
          • 瀏覽器的工作原理:新式網(wǎng)絡瀏覽器幕后揭秘[33]
          • 從瀏覽器多進程到 JS 單線程,JS 運行機制最全面的一次梳理[34]
          • ?? 移動端 JS 引擎哪家強?美國硅谷找......
          • 從 V8 角度揭秘你不知道的面試八股文
          • 高性能 JavaScript 引擎 V8 - 垃圾回收
          • Inside look at modern web browser[35]【一共四篇,可供參考】

          參考資料

          • Inside look at modern web browser[36]
          • 瀏覽器是如何工作的:Chrome V8 讓你更懂 JavaScript[37]
          • 深入理解JSCore[38]
          • The Story of the Web: A History Of Internet Browsers[39]
          • PPT - Browser Architecture[40]
          • JavaScript 引擎 V8 執(zhí)行流程概述[41]
          • Understanding WebViews[42]
          • Quantum Up Close: What is a browser engine?[43]

          本文首發(fā)于個人博客[44],歡迎指正和star[45]

          參考資料

          [1]

          瀏覽器市場份額: https://link.juejin.cn/?target=https%3A%2F%2F#baidu.com%2Fresearch%2Fsite

          [2]

          全球瀏覽器市場份額: https://link.juejin.cn/?target=https%3A%2F%2Fgs.statcounter.com%2F

          [3]

          w3counter: https://link.juejin.cn/?target=https%3A%2F%2Fwww.w3counter.com%2Fglobalstats.php

          [4]

          Chrome 為什么多進程而不是多線程?: https://link.juejin.cn/?target=https%3A%2F%2Fwww.zhihu.com%2Fquestion%2F368712837

          [5]

          經(jīng)典面試題:從 URL 輸入到頁面展現(xiàn)到底發(fā)生什么?: https://link.juejin.cn/?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F57895541

          [6]

          在瀏覽器輸入 URL 回車之后發(fā)生了什么(超詳細版): https://link.juejin.cn/?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F80551769

          [7]

          萬字詳文:深入理解瀏覽器原理: https://link.juejin.cn/?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F96986818

          [8]

          參考閱讀: https://link.juejin.cn/?target=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000037435824

          [9]

          Parser: https://link.juejin.cn/?target=https%3A%2F%2Fv8.dev%2Fblog%2Fscanner

          [10]

          Ignition: https://link.juejin.cn/?target=https%3A%2F%2Fv8.dev%2Fdocs%2Fignition

          [11]

          TurboFan: https://link.juejin.cn/?target=https%3A%2F%2Fv8.dev%2Fdocs%2Fturbofan

          [12]

          Orinoco: https://link.juejin.cn/?target=https%3A%2F%2Fv8.dev%2Fblog%2Ftrash-talk

          [13]

          深入理解JSCore: https://link.juejin.cn/?target=https%3A%2F%2Ftech.meituan.com%2F2018%2F08%2F23%2Fdeep-understanding-of-jscore.html

          [14]

          深入剖析 JavaScriptCore: https://link.juejin.cn/?target=https%3A%2F%2Fming1016.github.io%2F2018%2F04%2F21%2Fdeeply-analyse-javascriptcore%2F

          [15]

          JavaScriptCore 全面解析: https://juejin.cn/post/6844903765582053384

          [16]

          深入淺出 JavaScriptCore: https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2Fac534f508fb0

          [17]

          7.5.1 WebView(網(wǎng)頁視圖)基本用法: https://link.juejin.cn/?target=https%3A%2F%2Fwww.runoob.com%2Fw3cnote%2Fandroid-tutorial-webview.html

          [18]

          Android:這是一份全面 & 詳細的Webview使用攻略: https://link.juejin.cn/?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2F3c94ae673e2a%2F

          [19]

          Headless Chrome architecture: https://link.juejin.cn/?target=https%3A%2F%2Fwww.cnblogs.com%2Fbigben0123%2Fp%2F13880254.html

          [20]

          puppeteer: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fpuppeteer%2Fpuppeteer%2F

          [21]

          Puppeteer 入門教程: https://link.juejin.cn/?target=https%3A%2F%2Fwww.r9it.com%2F20171106%2Fpuppeteer.html

          [22]

          結(jié)合項目來談談 Puppeteer: https://link.juejin.cn/?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F76237595

          [23]

          Monaco Editor: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fmonaco-editor

          [24]

          Language Server Protocol: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FMicrosoft%2Flanguage-server-protocol

          [25]

          Debug Adapter Protocol: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fdebug-adapter-protocol

          [26]

          Xterm.js: https://link.juejin.cn/?target=https%3A%2F%2Fxtermjs.org%2F

          [27]

          Electron | Build cross-platform desktop apps with JavaScript, HTML, and CSS: https://link.juejin.cn/?target=https%3A%2F%2Fdelftswa.gitbooks.io%2Fdesosa2018%2Fcontent%2Felectron%2Fchapter.html

          [28]

          caniuse: https://link.juejin.cn/?target=https%3A%2F%2Fwww.caniuse.com%2F

          [29]

          browseemall: https://link.juejin.cn/?target=https%3A%2F%2Fwww.browseemall.com%2FResources

          [30]

          html5test: https://link.juejin.cn/?target=https%3A%2F%2Fhtml5test.com%2F

          [31]

          瀏覽器簡史: https://link.juejin.cn/?target=http%3A%2F%2Fwww.cnw.com.cn%2Fzhuanti%2F2009-ie%2F

          [32]

          Web 瀏覽器相關(guān)的一些概念: https://link.juejin.cn/?target=https%3A%2F%2Fkeqingrong.cn%2Fblog%2F2019-11-24-concepts-related-to-web-browsers

          [33]

          瀏覽器的工作原理:新式網(wǎng)絡瀏覽器幕后揭秘: https://link.juejin.cn/?target=https%3A%2F%2Fwww.html5rocks.com%2Fzh%2Ftutorials%2Finternals%2Fhowbrowserswork%2F

          [34]

          從瀏覽器多進程到 JS 單線程,JS 運行機制最全面的一次梳理: https://link.juejin.cn/?target=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000012925872

          [35]

          Inside look at modern web browser: https://link.juejin.cn/?target=https%3A%2F%2Fdevelopers.google.com%2Fweb%2Fupdates%2F2018%2F09%2Finside-browser-part1

          [36]

          Inside look at modern web browser: https://link.juejin.cn/?target=https%3A%2F%2Fdevelopers.google.com%2Fweb%2Fupdates%2F2018%2F09%2Finside-browser-part1

          [37]

          瀏覽器是如何工作的:Chrome V8 讓你更懂 JavaScript: https://link.juejin.cn/?target=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000037435824

          [38]

          深入理解JSCore: https://link.juejin.cn/?target=https%3A%2F%2Ftech.meituan.com%2F2018%2F08%2F23%2Fdeep-understanding-of-jscore.html

          [39]

          The Story of the Web: A History Of Internet Browsers: https://link.juejin.cn/?target=https%3A%2F%2Fwww.internetadvisor.com%2Fthe-story-of-the-web-a-history-of-internet-browsers

          [40]

          PPT - Browser Architecture: https://link.juejin.cn/?target=https%3A%2F%2Fsangbui.com%2Fsb-files%2FBrowserArchitecture_ClientSide.pdf

          [41]

          JavaScript 引擎 V8 執(zhí)行流程概述: https://link.juejin.cn/?target=http%3A%2F%2Fblog.itpub.net%2F69912579%2Fviewspace-2668277%2F

          [42]

          Understanding WebViews: https://link.juejin.cn/?target=https%3A%2F%2Fwww.kirupa.com%2Fapps%2Fwebview.htm

          [43]

          Quantum Up Close: What is a browser engine?: https://link.juejin.cn/?target=https%3A%2F%2Fhacks.mozilla.org%2F2017%2F05%2Fquantum-up-close-what-is-a-browser-engine%2F

          [44]

          個人博客: https://link.juejin.cn/?target=https%3A%2F%2Fking-hcj.github.io%2F2021%2F07%2F11%2Fweb-browser%2F

          [45]

          指正和star: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fking-hcj%2Fking-hcj.github.io



          創(chuàng)作不易,加個點贊、在看 支持一下哦!

          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲人妻系列 | 影音先锋午夜性爱av | MFYD-013 肉食人妻女上司が部下を誘惑し | 青青草做爱视频 | 91人人人 |