導語:本文從市面主流的瀏覽器及相應的內核引擎開始,介紹了Chromium為代表的瀏覽器架構及Blink內核的功能架構。Chromium為多進程架構,用戶從啟動運行瀏覽器后,先后經過頁面導航、渲染、資源加載、樣式計算、布局、繪制、合成到柵格化,最后完成GPU展示。而頁面渲染完成后,瀏覽器如何響應頁面操作事件也進行了深入的介紹。良心推薦! 本文第二至五部分內容根據 Mariko Kosaka 的英文原版《Inside look at modern web browser》,進行翻譯、理解、總結提煉、條理化、加入應用示例、進行相關知識補充擴展而來。
一、瀏覽器概論瀏覽器經歷了很多年的發展,瀏覽器引擎也在不停地迭代和演進。從PC時代到移動端,以獨立瀏覽器的形態還是以系統WebView組件內嵌的形態存在,在互聯網的生態系統中一直扮演著重要的角色。了解瀏覽器及其原理可以讓我們打開另一個世界。
1.瀏覽器引擎
以下是市面留存的主流瀏覽器的引擎介紹。
1.1 瀏覽器引擎
Trident:IE瀏覽器引擎
Gecko:Firefox瀏覽器引擎
Presto:Opera瀏覽器引擎
Webkit:Safari,Google Chrome瀏覽器引擎。
1) Chromium:基于webkit,08年開始作為Chrome的引擎,Chromium瀏覽器是Chrome的實驗版,實驗新特性。 2) Webkit2:2010年隨OS X Lion一起面世。WebCore層面實現進程隔離與Google的沙箱設計存在沖突。 3) Blink:基于Webkit2分支,13年谷歌開始作為Chrome 28的引擎集成在Chromium瀏覽器里。Android的WebView同樣基于Webkit2。 1.2 微軟瀏覽器目前PC場景操作系統仍是windows一統天下,對桌面用戶來說,雖然IE的市場份額在下降,但是IE曾經也風光過。IE內核以Trident為主,最新的Edge也兼容了Chromium內核。 Microsoft Edge:內核為:EDGE,Windows 10默認瀏覽器,不能單獨下載安裝。兼容Chromium內核,同時保留EDGE內核來兼容企業網站
Internet Explorer 11:Windows 8.1,引擎Trident 7.0
Internet Explorer 10:Windows 8默認瀏覽器,引擎Trident
Internet Explorer 9
Internet Explorer 8:Windows 7集成
Internet Explorer 7:Windows Vista集成,2016年停止支持
Internet Explorer 6:2014年停止支持
2. 瀏覽器架構
目前chromium瀏覽器的架構主要由下以幾個部分構成。
以下為架構的介紹:
操作系統:WebKit可以運行在不同的操作系統上,如Chromium瀏覽器支持Windows、Linux、Android等系統;
第三方庫:這些庫是WebKit運行的基礎,包括2D圖形庫、3D圖形庫、網絡庫、存儲庫、音視頻庫等;
WebCore:WebKit加載和渲染網頁的基礎,是不同瀏覽器所使用的WebKit中共享的部分,包括HTML解析器、CSS解析器、SVG、布局、渲染樹等等;
JavaScript引擎:JavaScript解析器,WebKit默認的引擎是JavaScriptCore,Google的Blink為V8引擎;
WebKit Ports:WebKit中的移植部分,包括網絡棧、音視頻解碼、硬件加速等模塊,這部分對WebKit的功能和性能影響比較大。
WebKit嵌入式接口:WebKit對外暴露的接口層,這個接口是提供給瀏覽器調用的,如給chromium調用,因為接口與具體的移植也有關系,所以中間會有一個WebKit綁定層
JavaScriptCore(用于Safari)
JavaSript Parser,JSON Parser
字節編譯器:使用內部字節碼格式
匯編程序:在運行時使用代碼修補 - >它需要可寫代碼內存
數據流圖:基于編譯時推測優化生成代碼的新舉措
解釋器:運行生成的字節碼
Regexp引擎:支持JIT
垃圾收集器:標記和掃描
運行時:所有JS全局對象(日期,字符串,數字等)
調試器,Profiler
WebCore
資源加載器:HTML和XML解析器,DOM
SVG和SMIL
CSS:分析器,選擇器,動畫
渲染和布局
綁定生成器:IDL文件:JSC,V8,ObjC
WebInspector
平臺集成:圖形,字體,聲音,視頻
相關資料
Blink內核:https://src.chromium.org/viewvc
2.1 多進程架構
圖片引自chromium-design-doc https://www.chromium.org/developers/design-documents/multi-process-architecture 2.1.1 Chromium多進程架構早期的web瀏覽器頁面行為不當、瀏覽器錯誤、瀏覽器插件錯誤都會引起整個瀏覽器或當前運行的選項卡關閉。因此將chromium應用程序放在相互隔離的獨立的進程中:
單個程序崩潰不會損害其他應用程序
不影響操作系統完整性
每個用戶不能訪問其他用戶數據(內存保護、訪問控制)
2.1.2 架構組成
UI主進程:頁面選項卡、插件進程作為瀏覽器進程。
渲染進程:特定選項卡作為渲染進程(渲染器),使用Blink(Webkit)開源布局引擎解釋和布局HTML。
2.1.3 渲染過程管理
RenderProcess:每個渲染進程都有一個全局對象,管理與父瀏覽器的通信并維護全局狀態
RenderProcessHost:瀏覽器為每個渲染進程維護相應的渲染進程宿主,為每個渲染器管理瀏覽器狀態和IPC(IPC已棄用,最新用Mojo)通信
RenderView:每個渲染進程有一或多個RenderView對象,對應內容選項卡。RenderProcessHost為渲染器的每個視圖(RenderView)維護一個RenderViewHost。每個視圖用一個ID區分。
2.1.4 運行流程
渲染進程共享:開啟瀏覽器新窗口或新選項卡時,創建新的瀏覽器進程,并創建RenderView。不同頁面/iframe可共享同個渲染進程。
崩潰監視:瀏覽器的IPC連接會監視進程句柄,如句柄對應的渲染進程已崩潰,會向標簽發送通知,瀏覽器會顯示“悲傷標簽”
沙箱運行:渲染器在單獨的進程中運行,通過沙箱限制其對系統資源(文件、網絡、顯示、擊鍵)的訪問,而須通過父瀏覽器進程訪問
內存交回:進程最小化、隱藏的選項卡將其內存自動放入“可用內存”,內存不足時,windows會將該可用內存數據寫磁盤,內存被用于更高優先級任務,以提高可見程序的響應速度。
2.1.5 插件擴展第三方編寫的NPAPI插件因存在不穩定,同時需控制對系統資源的訪問,在各自獨立的進程中運行,與渲染器分開。 插件設計文檔:https://www.chromium.org/developers/design-documents/plugin-architecture 2.2 Webkit(Blink)架構Blink是Web平臺的渲染引擎,實現了瀏覽器選項卡中呈現的內容:
HTML:實現Web平臺規范,HTML規范(DOM、CSS、Web IDL)
JavaScript:嵌入V8并運行JavaScript
網絡:從底層網絡堆棧請求資源
渲染:構建DOM樹,計算樣式和布局,嵌入合成器并繪制圖形
通過內容公共Api對外提供公共能力。
2.2.1 Blink的運行流程多進程架構,有一個瀏覽器進程和N個沙盒渲染器進程,Blink在沙盒渲染中運行。瀏覽器選項卡、iframe可共享同個渲染器進程。 沙箱運行:在沙箱中,須通過父瀏覽器進程來調度使用資源(文件訪問、網絡、音視頻播放、用戶配置文件讀取(cookie,密碼)等。Blink將瀏覽器進程抽象為一組服務,使用Mojo與服務、瀏覽器進程交互。 2.2.2 渲染進程中的線程
1個主線程:運行JavaScript、DOM、CSS、樣式布局計算
N個工作線程:運行Web Worker,ServiceWorker,Worklet
內部線程:Blink和V8會創建幾個線程處理web audio,數據庫,GC等
跨線程通信:使用PostTask API,不鼓勵共享內存編程除非性能原因。
2.2.3 Blink的運行和退出
運行:任何使用Blink的場景都需調用 BlinkInitializer::Initialize() 初始化
退出:渲染器被強制退出,而不會被清理
2.2.4 Blink的項目代碼結構
platform:低級功能集合,如單片內核、幾何、圖形工具
core:core與DOM緊密結合
web:實現規范中的web平臺功能
modules:包含獨立的功能,如web audio,indexed db等。
bindings / core:大量使用V8 API
controller:一組使用core、modules的高級庫,如devtools。
依賴關系:Chromium -> controller -> modules / bindings -> core / bindings -> platform -> 低級單元(base、V8、cc)
2.2.5 platform內部構成1) WTF:統一編碼原語,如WTF::Vector, WTF::HashSet, WTF::HashMap, WTF::String and WTF::AtomicString來代替std:vector 等。 2) 內存管理:a. PartitionAlloc b.Oilpan(Blink GC) c.malloc/free/new/delete 3) 任務調度:為提高渲染引擎的響應,應執行異步。所有任務都應發布到Blink Scheduler任務隊列,指定正確類型并設置優先級,以使得能巧妙地安排任務。 4) Page/Frame/Document/ExecutionContext/DOMWindow 分別對應選項卡、iframe、window.document、主線程和工作線程上下文、JavaScript中的窗口對象。
渲染進程中各種數量關系
渲染器進程/Page = 1/N
頁數/幀= 1/M
框架/DOMWindow/文檔(或ExecutionContext)= 1/1/1 (會隨時變化)
5) 進程外iframe 站點隔離:為每個站點創建一個渲染器進程(相同一二級域名)。跨站點由兩個渲染器托管。 6) 分離的iframe/文件
doc = iframe.contentDocumentiframe.remove() //iframe 與 dom 樹分離doc.createElement('div'); //仍可在分離的框架上運行腳本 左滑可查看完整代碼,下同
7) Web IDL綁定
8) V8
Isolate:一一對應物理線程。主線程、工作線程都有自己的獨立線程。
Context:對應全局對象,如為Frame時對應Frame的窗口對象,每個幀都有自己的窗口對象
World:支持Chrome擴展程序內容腳本
關系:一個frame = N個窗口對象 = 用于N個world。Context對應該窗口對象 V8的API低級且難以使用,在platform/bindings中提供很多V8 API輔助類。每個C++ DOM對象,如Node都有其對應的V8包裝器。V8包裝器對應的C++ DOM對象具有強引用。C++ DOM對象只對V8包裝器弱引用。
2.3 V8V8是Google的開源高性能JavaScript和WebAssembly引擎,用C++編寫,它實現ECMAScript和WebAssembly,可獨立運行或嵌入到任何C++應用程序中,如Chrome和Node.js。
相關資料 ECMAScript:https://tc39.es/ecma262/ WebAssembly:https://webassembly.github.io/spec/core/
二、Chrome的多進程架構
注意:以下內容根據 Mariko Kosaka 的英文原版《Inside look at modern web browser》(見參考文獻),進行翻譯、理解、總結提煉、條理化、加入應用示例、進行相關知識補充擴展而來。
1. 背景:計算機的核心是CPU和GPU
CPU:Center Processing Unit,同時支持并行、串行操作,需很強通用性處理不同數據類型、要支持復雜通用邏輯判斷,需引入大量分支和中斷處理,結構異常復雜。 GPU:Graphics Processing Uint,專為執行圖形渲染必須的復雜的數學和幾何計算而設計。
圖片引自Mariko Kosaka的《Inside look at modern web browser》
圖片引自Mariko Kosaka的《Inside look at modern web browser》
三層計算機體系結構 圖片引自Mariko Kosaka的《Inside look at modern web browser》
2. 基礎:在Process和Thread執行程序
啟動應用程序時,創建一個進程,并提供”slab”內存,所有應用程序狀態保存在該專用內存中,關閉程序時,系統釋放內存。
應用程序可能會創建多個線程完成工作任務。
圖片引自Mariko Kosaka的《Inside look at modern web browser》
圖片引自Mariko Kosaka的《Inside look at modern web browser》
3. 瀏覽器架構
瀏覽器架構沒有統一標準規范,不同瀏覽器可能使用不同線程或多個不同進程來構建web。少數線程間通過IPC通信。
3.1 不同瀏覽器實現的體系結構
圖片引自Mariko Kosaka的《Inside look at modern web browser》
3.2 Chrome的多進程架構
圖片引自Mariko Kosaka的《Inside look at modern web browser》
4. 不同進程作用
瀏覽器:控制應用程序chrome部分,包括地址欄,書簽,后退和前進按鈕。及處理Web瀏覽器的不可見特權部分,例如網絡請求和文件訪問
渲染:控制顯示網站的選項卡內的任何內容
插件:控制網站使用的任何插件,例如flash。
GPU:獨立于其他進程處理GPU任務。它被分成不同的進程,因為GPU處理來自多個應用程序的請求并將它們繪制在同表面中。
其他進程:瀏覽器右上角更多 -> 更多工具 -> 任務管理器,查看其他進程,如實用程序網絡服務、輔助框架
圖片引自Mariko Kosaka的《Inside look at modern web browser》
5. 多進程架構
優點:
防一個頁面崩潰影響整個瀏覽器
安全性和沙箱:操作系統提供了限制進程權限的方法,因此瀏覽器可以從某些功能中對某些進程進行沙箱處理。如任意訪問文件
進程有自己的私有內存空間,可以擁有更多的內存。為了節省內存,Chrome限制了它可以啟動的進程數量。限制因設備的內存和CPU功率而異,但當Chrome達到限制時,它會在一個進程中開始從同一站點運行多個選項卡
圖片引自Mariko Kosaka的《Inside look at modern web browser》
6. 服務化 - 節省更多內存
瀏覽器程序中相同的功能方法,正在將瀏覽器的每個部分作為一項服務運行,可以輕松拆分為不同進程或聚合成一個進程。 當Chrome在強大的硬件上運行時,它可能會將每個服務拆分為不同的流程,從而提供更高的穩定性,但如果它位于資源約束設備上,Chrome會將服務整合到一個流程中,從而節省內存占用。
Android的平臺上已經使用了類似的方法來整合流程以減少內存使用。
圖片引自Mariko Kosaka的《Inside look at modern web browser》
7.給Iframe分配單獨渲染進程 - 站點隔離
站點隔離:因不同站點之間共享內存空間會存在同源策略繞過(Meltdown and Spectre)安全問題:https://blog.csdn.net/wlmnzf/article/details/79319509%22%20/t%20%22_blank。因此為每個跨網站iframe運行單獨的渲染器進程。
站點隔離難點:從根本上改變iframe的通信方式,包括ctrl+F查找、打開devtools等需在不同渲染器進程訪問。【重大版本】。
圖片引自Mariko Kosaka的《Inside look at modern web browser》
三、頁面導航過程
1. 瀏覽器進程運行
多進程架構啟動多個進程處理不同的任務。選項卡外部的所有內容都由瀏覽器進程處理(包含UI線程、網絡線程、存儲線程)。在地址欄輸入url時,由瀏覽器進程的UI線程處理。
圖片引自Mariko Kosaka的《Inside look at modern web browser》
2. 處理輸入
當用戶開始輸入地址欄時,UI線程需判斷是搜索查詢還是URL。
查詢:發送到搜索引擎
URL:請求URL的網站
3.開始導航
用戶點擊進入時:
有注冊設置Service Worker從緩存加載頁面,渲染進程中運行JavaScript代碼,從緩存加載頁面,無需請求網絡
未設置Service Worker時:
1) UI線程啟動網絡調用以獲取站點內容,選項卡加載轉圈
2) 網絡線程通過DNS查找域名對應IP及建立http連接
3) 網絡線程接收處理301重定向頭。網絡線程與請求重定向的UI線程通信,啟動另一個URL請求
Service Worker
Service Worker注冊后,保留其范圍為參考。當導航時,網絡線程根據注冊的范圍檢查域名,若url已注冊Service Worker,UI線程找到渲染進程執行ServiceWorker代碼,從緩存加載數據或從網絡加載新資源。生命周期見:https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle
導航預加載
如果ServiceWorker最終決定從網絡請求數據,瀏覽器進程與渲染進程間的往返可能導致延時,通過與ServiceWorker啟動并行加載資源加速來減少延時,允許標記這些請求,允許服務器決定為這些請求發送不同的內容。
圖片引自上面ServiceWorker的生命周期
4. 讀取響應結果
4.1 確定文件MIME類型
網絡線程查看流的前幾個字節,響應頭中Content-Type頭確定MIME數據類型。因此數據可能丟失,因此用MIME嗅探方式來查看資源。https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
4.2 處理不同MIME文件
響應文件是HTML,則將數據傳遞給渲染器進程。如果為.zip或其他文件則將數據傳遞給下載管理器。
4.3 安全檢查
惡意名單檢查:如果域和響應數據在惡意站點名單中,則網絡線程發出和顯示警告頁面。
跨域讀取檢查:CrossOriginReadBlock檢查,敏感的跨站點數據不進入渲染器進程
5. 查找渲染進程
所有檢查完成后,網絡線程告知UI線程數據已準備就緒,UI線程找到渲染進程以繼續渲染網頁。 由于網絡請求可能需要幾百毫秒才能得到響應,為加速此過程,在開始導航網絡線程發送url請求時,已經主動進行查找、啟動渲染進程,數據接收完成后,渲染進程已備用。
6. 提交導航
現在數據和渲染器進程已準備就緒,IPC將從瀏覽器進程發送到渲染進程以提交導航。渲染進程確認提交完成,導航完成。文檔加載開始。 1、UI更新:地址欄更新、安全指示器、站點設置UI會反映新頁面站點信息 2、選項卡的會話歷史記錄更新(前進/后退),為便于關閉瀏覽器后恢復,歷史記錄到磁盤
7. 初始化 load complete
提交導航后,渲染器進程將繼續加載資源并呈現頁面,一旦渲染器進程“完成”(onload事件在所有幀上觸發執行完成后)渲染,它就會將IPC發送回瀏覽器進程。 UI線程停止選項卡的加載轉圈。
8.導航到其他站點
導航完成后,再次將不同的URL放到地址欄導航,瀏覽器會檢查當前渲染網站的beforeunload事件。如有設置導航或關閉選項卡時發出警報“離開這個網站嗎?” 包含JavaScript代碼的選項卡內的所有內容都由渲染進程處理。
渲染進程導航操作 單擊鏈接或客戶端JavaScript已運行window.location = “https://newsite.com“ ,過程與流程器進程啟動導航過程相同,不同點在于導航請求是從渲染進程啟動到瀏覽器進程。
頁面生命周期:https://developers.google.com/web/updates/2018/07/page-lifecycle-api#overview_of_page_lifecycle_states_and_events
圖片引自上面的頁面生命周期
四、頁面渲染
1. 渲染進程處理頁面內容
渲染進程負責選項卡內發生的所有事情。在渲染器進程中
主線程:處理您發送給用戶的大部分代碼。
工作線程:處理WebWorker或ServiceWorker
排版線程:Compositor
柵格線程
圖片引自Mariko Kosaka的《Inside look at modern web browser》
2. 解析
2.1 構建DOM
當渲染進程接收提交的導航消息和HTML數據,主線程開始解析文本串(HTML),使之成為一個DOM。解析中遇到html能優雅容錯。
DOM:瀏覽器頁面內部表示,提供給開發人員通過JS與DOM交互的數據結構和API。
圖片引自Mariko Kosaka的《Inside look at modern web browser》
2.2 子資源加載
網站通常使用圖像,CSS和JavaScript等外部資源,需要從網絡或緩存加載。在解析構建DOM時,主線程可以逐個請求它們。為了加快速度“預加載掃描器”同時運行。
2.3 JavaScript阻塞解析
當遇到 主站蜘蛛池模板: 午夜福利国产一级毛片| 在线播放你懂| 女色专区| 亚洲 欧美 丝袜 制服 在线| 91操视频| www.福利| 国产伦精品一区二区免费| 天天插天天干天天操| 一级片在线免费看| 丁香综合| 国产精品99r8在线观看| 经典三级一区二区三区视频| 欧美三级黄视频| 日韩啪啪电影| 天堂在线中文网| 亚洲国产精品综合久久久| 69国产| 国产精品久久久久久久久免费观看| 亚洲一区有码| 69 hd xxxx日本| 久久精品国产亚洲婷婷| 国产精品午夜自在在线精品| aⅴ一区二区三区| 色综合天天色综合| 三浦理惠子中文在| 日韩精品另类天天更新影院| 欧美1314www伊人久久香网| 国产美女一区| sese久久| 999毛片| h录音 国产 在线| 天天爽夜夜爽人人爽免费| 午夜影院在线观看免费| 午夜秒播| a一级日本特黄aaa大片| 美女扒开尿囗给男人玩的动图| 热re99久久国产精品| 美女扒开尿口给男人爽免费视频| 亚洲国产色图| 久青草视频在线| 国产精品久久久久久久久ktv|