浏览器运行机制
灵感胜于汗水 Lv5

浏览器进程

浏览器是多进程的:

  1. Browser进程:浏览器的主进程(负责协调、主控),只有一个。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。

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

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

  4. 渲染进程:核心任务是将 HTMLCSSJavaScript 转换为用户可以与之交互的网页,排版引擎 BlinkJavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。

  5. 网络进程:只有一个,主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。

多进程模型提升了浏览器的稳定性、流畅性和安全性,但同样不可避免地带来了一些问题:

  • 更高的资源占用:因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏览器会消耗更多的内存资源。
  • 更复杂的体系架构:浏览器各模块之间耦合性高、扩展性差等问题,会导致现在的架构已经很难适应新的需求了。

渲染进程

渲染进程下有多个线程:

GUI渲染线程

  • 负责渲染浏览器页面,解析HTMLCSS,构建DOM树、CSSOM树、渲染树和绘制页面
  • 当界面需要重绘或由于某种操作引发回流时,该线程就会执行

注意:GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

JS引擎线程

  • JS引擎线程也称为JS内核,负责处理Javascript脚本程序,解析Javascript脚本,运行代码
  • JS引擎线程一直等待着任务队列中任务的到来,然后加以处理,一个Tab页中无论什么时候都只有一个JS引擎线程在运行JS程序

注意:GUI渲染线程与JS引擎线程的互斥关系,所以如果JS执行的时间过长,会造成页面的渲染不连贯,导致页面渲染加载阻塞。

事件触发线程

  • 属于浏览器而不是JS引擎,用来控制事件循环
  • JS引擎执行代码块如setTimeOut时(也可是来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件触发线程中
  • 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理

注意:由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)

定时器触发线程

  • setIntervalsetTimeout所在线程
  • 浏览器定时计数器并不是由JS引擎计数的,因为JS引擎是单线程的,如果处于阻塞线程状态就会影响记计时的准确性
  • 因此使用单独线程来计时并触发定时器,计时完毕后,添加到事件队列中,等待JS引擎空闲后执行,所以定时器中的任务在设定的时间点不一定能够准时执行,定时器只是在指定时间点将任务添加到事件队列中

注意:W3C在HTML标准中规定,定时器的定时时间不能小于4ms,如果是小于4ms,则默认为4ms

异步http请求线程

  • XMLHttpRequest连接后通过浏览器新开一个线程请求
  • 检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将回调函数放入事件队列中,等待JS引擎空闲后执行

浏览器运行过程

浏览器地址栏输入 URL到回车后发生的行为如下:

  • URL解析
  • DNS 查询
  • TCP 连接
  • HTTP 请求
  • 响应请求
  • 页面渲染

URL解析

首先判断你输入的是一个合法的URL 还是一个待搜索的关键词,并且根据你输入的内容进行对应操作

DNS查询

TCP连接

发送 http 请求

当建立tcp连接之后,就可以在这基础上进行通信,浏览器发送 http 请求到目标服务器

请求的内容包括:

  • 请求行
  • 请求头
  • 请求主体

响应请求

当服务器接收到浏览器的请求之后,就会进行逻辑操作,处理完成之后返回一个HTTP响应消息,包括:

  • 状态行
  • 响应头
  • 响应正文

页面渲染

当浏览器接收到服务器响应的资源后,首先会对资源进行解析:

  • 查看响应头的信息,根据不同的指示做对应处理,比如重定向,存储cookie,解压gzip,缓存资源等等
  • 查看响应头的 Content-Type的值,根据不同的资源类型采用不同的解析方式

关于页面的渲染过程如下:

  • 解析HTML,构建 DOM 树
  • 解析 CSS ,生成 CSS 规则树
  • 合并 DOM 树和 CSS 规则,生成 render 树
  • 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
  • 绘制 render 树( paint ),绘制页面像素信息
  • 浏览器会将各层的信息发送给 GPUGPU 会将各层合成( composite ),显示在屏幕上

参考:

  • 本文标题:浏览器运行机制
  • 本文作者:灵感胜于汗水
  • 创建时间:2022-11-05 22:07:35
  • 本文链接:https://cjhsyc.github.io/2022/11/05/浏览器运行机制/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!