# 1-宏观视角下的浏览器
# 01|chrome架构:仅仅打开了一个页面,为什么有4个进程
前提明白一下线程和进程的区别
进程包含线程,线程是进程的一个子级。线程是不能单独存在的,它是由进程来启动和管理的。
进程:一个进程就是一个程序的运行实例; 详细解释就是,启动一个程序的时候,操作系统会为该程序创建一块内存, 用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。
线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。线程——程序执行的最小单位。 线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率。
# 进程与线程之间关系有4个特点
- 进程中的任意一线程执行出错,都会导致整个进程的崩溃。
- 线程之间共享进程中的数据。
- 当一个进程关闭之后,操作系统会回收进程所占用的空间。(即使线程内存泄露,也会回收掉)
- 进程之间的内容相互隔离。(进程间通信IPC)。
# 浏览器打开后会打开四个进程
- 浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
- 渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页, 排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中, 默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。 出于安全考虑,渲染进程都是运行在沙箱模式下。
- GPU进程。 其实,Chrome 刚开始发布的时候是没有 GPU 进程的。 而 GPU 的使用初衷是为了实现 3D CSS 的效果, 只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制, 这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
- 网络进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
- 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。
# 多进程对比
虽然多进程模型提升了浏览器的稳定性、流畅性和安全性,但同样不可避免地带来了一些问题:
- 更高的资源占用。因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏览器会消耗更多的内存资源。
- 更复杂的体系架构。浏览器各模块之间耦合性高、扩展性差等问题,会导致现在的架构已经很难适应新的需求了。
# 02|TCP协议:如何保证页面内容能够被完整的送达浏览器?
# 一个数据包的旅程
- IP: 把数据包送达目的主机
- UDP:把数据包送达应用程序
- TCP:把数据完整的送达应用程序
TCP为了保证数据的可靠性,牺牲了数据包的传输速度,因为三次握手和数据包校验机制。
# 03|HTTP请求流程:为什么很多站点第二次打开速度会很快?
核心:DNS缓存和页面资源缓存。
# 04|从输入URl到页面展示,这中间发生了什么?
- url输入,校验合法性-校验完整性
- DNS解析
- TCP连接
- SSL/TLS连接
- 服务器响应
- 浏览器渲染
- 断开连接
总结来说,打开一个新页面采用的渲染进程策略就是:
- 通常情况下,打开新的页面都会使用单独的渲染进程;
- 如果从 A 页面打开 B 页面,且 A 和 B 都属于同一站点的话,那么 B 页面复用 A 页面的渲染进程; 如果是其他情况,浏览器进程则会为 B 创建一个新的渲染进程。
# 05|渲染流程
- 构建DOM树。因为浏览器无法直接理解和使用 HTML,所以需要将 HTML 转换为浏览器能够理解的结构——DOM 树。
- 样式计算。和 HTML 文件一样,浏览器也是无法直接理解这些纯文本的 CSS 样式,、 所以当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets。
- 布局阶段 那么接下来就需要计算出 DOM 树中可见元素的几何位置,使其都保存在布局树中。我们把这个计算过程叫做布局。
- 分层。渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)
- 合成和显示