番外篇:一篇读懂浏览器结构
浏览器结构
浏览器的主要组件:
1、用户界面:包括地址栏、前进/后退按钮,书签菜单等。除了浏览器主窗口用于显示 网页外,其他显示的部分属于用户界面。
2、浏览器引擎:在用户界面和渲染引擎直接传送指令。一方面提供对渲染引擎的高级接口,另一方面提供初始化加载URL和其他用户界面的方法,如刷新后退等 和用户界面提供错误、加载进度等消息。
3、呈现引擎(渲染引擎):一般称为“浏览器内核”,负责显示请求的内容。如果请求的内容是HTML,则负责解析HTML和CSS内容并显示 在屏幕上。其中不用浏览器的渲染引擎存在差异。例如IE使用Trident,Firefox使用的Mozilla公司“自制”的Gecko 渲染引擎,而Safari、Opera和Chrome浏览器则使用的是Webkit,一种开放源代码呈现引擎。
4、网络:基于互联网HTTP和FTP协议,用于处理网络请求,其提供接口用于为所有平台提供底层实现。
5、用户界面后端:用户汇总基本的窗口小部件,如组合框和窗口。
6、JavaScript解析器:用于解析和执行JavaScript代码,并将结果传递到渲染引擎展示。其中 Chrome的JS解析器为基于C++的V8引擎,Firfox的是基于C的Spider-Monkey,而IE的有JScript和VBScript。
7、数据存储:数据持久化。浏览器需要在硬盘上保存各种数据,例如Cookie等。
如今基本上浏览器的每个标签页都分别对应一个渲染引擎实例。即每个标签页除了属于同一站点(即协议和根域名相同) 都有一个独立的渲染进程。
但是如果页面存在多个iframe来自不同站点,会导致不同站点中的内容通过iframe同时运行在一个渲染进程中,导致 幽灵和熔毁的漏洞,所以通过支持站点隔离实现将标签级的渲染进程重构为iframe级的渲染进程,按照同一站点 的策略来分配渲染进程。
浏览器内核
浏览器的核心部分就是渲染引擎,其中有如下的常驻线程:
-
GUI渲染线程:负责解析HTML,CSS,构建DOM树及页面布局和绘制等。
-
JavaScript引擎线程:负责解析JavaScript脚本,运行代码,一个渲染进程中只有一个 JavaScript线程在运行,所以会存在JS阻塞,另外,GUI渲染线程和JS引擎是互斥的,因为 JavaScript可通过操作DOM修改元素,所以当JavaScript执行时,GUI线程会挂起,这种情况会导致 页面渲染阻塞,页面渲染不连贯。
-
事件触发线程:负责维护事件队列,当一些事件被触发时,该线程会把事件添加至事件队列的末尾,等待JS引擎处理。
-
定时器线程:浏览器定时器会通过单独的线程来计时并触发定时任务。
-
异步http请求线程:在XMLHttpRequest在连接后是通过浏览器新开一个线程来实现,通过监听连接 状态的变化来将回调放入事件队列中。
浏览器内部工作原理
渲染一个页面,浏览器内部的工作原理:
-
浏览器进程:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
-
渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页。
-
GPU进程:3D CSS效果,UI界面绘制。
-
网络进程:主要负责页面的网络资源加载。
-
插件进程:负责插件的运行环境。
推荐阅读
浏览器的高级结构:http://taligarsiel.com/Projects/howbrowserswork1.htm#Thebrowserhighlevelstructure
一文看透浏览器架构:https://www.jianshu.com/p/a37990edd38a