浏览器的工作原理

226 阅读7分钟

何为浏览器

浏览器是指可以显示网页服务器或者文件系统的HTML文件内容,并让用户与这些文件交互的一种软件。大部分的浏览器本身支持除了HTML之外的广泛的格式,例如JPEG、PNG、GIF等图像格式,并且能够扩展支持众多的插件(plug-ins)。另外,许多浏览器还支持其他的URL类型及其相应的协议,如FTP、Gopher、HTTPS(HTTP协议的加密版本)。HTTP内容类型和URL协议规范允许网页设计者在网页中嵌入图像、动画、视频、声音、流媒体等。

浏览器的多进程架构

一个好的程序常常被划分为几个相互独立又彼此配合的模块,浏览器也是如此,以 Chrome 为例,它由多个进程组成,每个进程都有自己核心的职责,它们相互配合完成浏览器的整体功能,每个进程中又包含多个线程,一个进程内的多个线程也会协同工作,配合完成所在进程的职责。

在Chrome中,主要的进程有以下5个:

  • 浏览器进程

  • 渲染进程

  • GPU进程

  • 网络进程

  • 插件进程

浏览器进程

浏览器的主进程(负责协调、主控),该进程只有一个,主要负责以下工作:

  • 负责浏览器界面显示,与用户交互。如前进,后退等。

  • 负责各个页面的管理,创建和销毁其他进程。

  • 将渲染(Renderer)进程得到的内存中的Bitmap(位图),绘制到用户界面上。

  • 网络资源的管理,下载等

渲染进程

负责一个Tab内的显示相关的工作,也称渲染引擎,由以下线程组成

  • GUI线程:主要负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。例如当我们修改了一些元素的颜色或者背景色,页面就会重绘(Repaint),当我们修改元素的尺寸,页面就会回流(Reflow),而当页面需要Repaing和Reflow时GUI线程执行,绘制页面。需要注意的是,回流(Reflow)比重绘(Repaint)的成本要高,我们要尽量避免Reflow和Repaint。GUI渲染线程与JS引擎线程是互斥的

  • 定时触发器线程:该线程是setInterval与setTimeout所在线程。浏览器定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就会影响记计时的准确。通过单独线程来计时并触发定时(计时完毕后,添加到事件触发线程的事件队列中,等待JS引擎空闲后执行),这个线程就是定时触发器线程,也叫定时器线程。规定要求setTimeout中低于4ms的时间间隔算为4ms

  • js引擎线程:JS引擎线程就是JS内核,负责处理Javascript脚本程序(例如V8引擎)。JS引擎线程负责解析Javascript脚本,运行代码。JS引擎一直等待着任务队列中任务的到来,然后加以处理。GUI渲染线程与JS引擎线程是互斥的,js引擎线程会阻塞GUI渲染线程

  • 事件触发线程:该线程属于浏览器而不是JS引擎,用来控制事件循环,并且管理着一个事件队列(task queue)。当js执行碰到事件绑定和一些异步操作(如setTimeOut,也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会走事件触发线程将对应的事件添加到对应的线程中(比如定时器操作,便把定时器事件添加到定时器线程),等异步事件有了结果,便把他们的回调操作添加到事件队列,等待js引擎线程空闲时来处理。当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。因为JS是单线程,所以这些待处理队列中的事件都得排队等待JS引擎处理。

  • 异步HTTP请求线程:这个线程负责处理异步的ajax请求,当请求完成后,他也会通知事件触发线程,然后事件触发线程将这个事件放入事件队列给主线程执行。例如XMLHttpRequest在连接后是通过浏览器新开一个线程请求,将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中再由JavaScript引擎执行,当执行到一个http异步请求时,就把异步请求事件添加到异步请求线程,等收到响应(准确来说应该是http状态变化),再把回调函数添加到事件队列,等待js引擎线程来执行

GPU进程

该进程也只有一个,GPU 进程的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程

插件进程

主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

网络进程

主要负责页面的网络资源加载

导航过程发生了什么

浏览器进程负责浏览器 Tab 外的工作,针对工作的不同,Browser Process 划分出不同的工作线程:

  • UI线程:控制浏览器上的按钮及输入框

  • 网络线程:处理网络请求,从网上获取数据

  • storage(存储)线程:控制文件的访问

具体过程如下:

  • 处理输入:UI线程判断用户输入的是URL还是query,判断是链接还是查询

  • 开始导航:当用户点击回车键,UI线程通知网络线程获取网页内容,并控制tab上的loading展示,表示正在加载中,网络线程会执行DNS查询,随后为请求建立TLS连接(如果网络线程接收到了重定向请求头如301,网络线程会通知UI线程服务器要求重定向,之后,另一个URL请求会被触发)

  • 读取响应:当请求响应返回的时候,网络线程会依据Content-Type及MIME Type sniffing判断响应内容的格式(1,如果响应内容是HTML,下一步会把这些数据传递给渲染进程,如果是zip文件或者其他文件,会把相关数据传输给下载管理器。2,Safe Browsing检查也会在此时触发,如果域名或者请求内容匹配到已知的恶意站点,网络线程会展示一个警告页。此外CORB检测也会触发确保敏感数据不会被传递给渲染进程)

  • 查找渲染进程:上述检查完成后,网络请求确信浏览器可以导航到请求网页,网络线程会通知UI线程数据已经准备好了,UI线程会查找到一个渲染进程进行网页的渲染

  • 确认导航:浏览器进程会给渲染进程发送IPC消息来确认导航,一旦浏览器进程收到渲染进程的渲染确认消息,导航过程结束,页面加载过程开始,此时,地址栏会更新,展示出新页面的网页信息。history tab会更新,可通过返回键返回导航来的页面,为了让关闭tab或者窗口后便于恢复,这些信息会存放在硬盘中

  • 额外的步骤:一旦导航被确认,渲染进程会使用相关的资源渲染页面,当渲染进程结束(包括所有的iframe都触发onload时),会发送IPC信号到浏览器进程,UI线程会停止展示tab中的spinner