0%

浏览器原理学习笔记-Chrome架构演变

chrome 架构

一般我们使用chrome浏览器打开一个网页的时候,打开浏览器的任务管理器可以发现会发现chrome在这个时候会启用多个进程窗口。(同windows一样,chrome任务管理器也是用来展示运行中chrome使用进程信息的。)

这里就会涉及到chrome的多进程架构

并行处理

计算机的并行处理就是指在同一时刻处理多个任务,性能是要高于正常情况下用单线程来处理的。

线程 and 进程

多线程可以并行处理任务,但是线程不能存在的,还需要进程来启动和管理

进程指的是一个程序的运行实例:启动一个程序时,OS会为程序创建一块内存,用来存放代码、运行中的数据、和一个执行任务的主线程,这样的一个环境就可以叫做进程

image-20200513225045754

如图所示,线程是依附于进程的,进程中使用多线程并行处理是能够提升运行效率。

进程和线程的关系有以下几个特点:

  • 进程中的任一线程执行出错,都会导致整个进程的崩溃
  • 线程之间共享进程的数据

    • 线程之间可以对进程的公共数据进行读写操作
  • 当一个进程关闭之后,操作系统会回收进程所占用的内存

    • 当一个进程关闭的时候,操作系统会回收该进程所申请的所有资源;即使线程导致的内存泄漏都会在进程退出之后进行回收
  • 进程之间的内容相互隔离
    • 进程隔离是为了保护OS中进程互不干扰的技术,每个进程都只能访问自己占有的数据
    • 一个进程挂了,是不会影响其他进程的
    • 进程之间进行数据通信,需要依赖IPC机制

浏览器的单进程时代

image-20200513225930714

RT,单进程浏览器是指浏览器所有的功能模块都运行在同一个进程里面。这些模块包括网络、插件、JavaScript 运行环境、渲染引擎和页面等。

缺点:功能都运行在一个进程里面,会导致浏览器不稳定、不流畅、不安全的一个主要因素。

不稳定

浏览器的插件 && 渲染引擎模块的渲染都是导致浏览器不稳定的一个因素之一。如果这些东西崩溃了,那么浏览器也会跟着崩溃。

不流畅

从上面架构图可以看出,如果写一个类似于下面的无限循环脚本:

1
2
3
4
5
6
const freeze = () => {
while (1) {
console.log('freeze')
}
}
freeze()

如果让这个脚本在单进程浏览器里面运行了,它会独占整个浏览器的运行线程,从而导致其他的模块机制没有机会去被执行。这样就会使浏览器变得卡顿。

除了上面的脚本插件会让浏览器变得卡顿,其实页面的内存泄漏也是使得单进程变慢的一个重要的原因。

不安全

  • 插件,当你的页面运行一个插件的时候,这个时候插件能够完全操作你的电脑。如果是个恶意插件,那么它就可以释放病毒、窃取账号密码、引发安全性问题
  • 脚本,类似于XSS攻击

类似于这样一个场景,一个页面的崩溃,导致了你所有的浏览器页面的崩溃。

多进程浏览器时代

早期多进程架构

image-20200513231511743

不稳定?

由于进程之间是彼此相互隔离的,所以当一个页面崩溃的时候,只会影响当前的页面进程和插件进程。并不会影响到浏览器和其他页面。

不流畅?

因为JS也是在渲染进程中进行渲染的,所以即使其阻塞了渲染进程,影响到的也只是当前的渲染页面。并不会影响浏览器和其他页面。

对于内存泄漏的改进: 当整个页面关闭的时候,渲染进程也会被关闭,误操作泄漏的内存也会包括在进程占有的内存中被系统回收回去。

不安全?

多进程架构的额外好处是可以使用安全沙箱,沙箱相当于是OS给进程上了一把锁,沙箱里面的程序可以运行,但不能在硬盘上写入数据,也不能在敏感位置读取任何数据,例如获取你的文档读写权限。Chrome把插件和渲染进程锁在沙箱里面,这样即使在渲染进程或者插件里面执行了恶意程序,它也无法突破沙箱去获取系统权限。

改进的多进程架构

随着时间的发展。目前的Chrome架构也有了许多新的变化:

image-20200513232500284

目前的 Chrome 浏览器包括:1个浏览器(Broswer)主进程、1个GPU进程、1个网络(NetWork)进程、多个渲染进程和多个插件进程。

  • 浏览器进程。负责界面显示、用户交互、子进程管理、同时提供存储功能(localstorage等)
  • 渲染进程。核心任务是将HTML、CSS 和 JavaScript 转换成用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程里面,默认情况下,Chrome 会给每个Tab标签创建一个渲染进程。且渲染进程运行在sandbox里面。
  • GPU进程。GPU使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的UI界面都选择采用GPU来绘制,然后GPU就成了浏览器的普遍需求。最后Chrome也在多进程架构里面引入了 GPU 进程。
  • 网络进程。主要负责网页资源的加载。之前是作为一个模块运行在浏览器进程里面的,直到最近才独立出来,成为一个单独的进程。
  • 插件进程。主要是负责插件的运行,因插件容易崩溃,所以需要插件进程来隔离从而保证其崩溃不会对浏览器和页面造成影响。

带来的问题:

  • 更高的资源占用。因为每个结构都会包含公共基础结构的副本,意味着浏览器会消耗更多的内存资源。所以mbp在没有充电器的情况下写前端是一件非常耗电的事情。
  • 更复杂的体系架构。各模块之间的耦合性高、拓展性差的问题,会导致现在的架构很难以适应新的需求了。

未来面向服务的架构

为了解决这些问题,16年,Chrome官方使用了“面向服务的架构”(Service Oriented Architecture,简称SOA)的思想设计了新的Chrome架构。之后整体的架构都会往这一方面进行迁移:原来所有的模块都会被重构成独立的服务(Service),每个服务(Service)都可在独立的进程中运行,访问服务(Service)必须使用定义好的接口,通过IPC来进行通信。最终要把 UI、数据库、文件、设备、网络等模块重构为基础服务,类似于OS的底层服务。

具体资料可以可以Google搜索。

总结

从Chrome浏览器的进化视角来看,浏览器的进化历史大概可以分为:

单进程架构 -> 多进程结构(早期)->多进程架构(现在)->面向服务的架构(未来)

个人认为之所以会有这方面的进化,起初可能仅仅是因为性能的问题。后面随着技术的进步与发展浏览器架构需要考虑到的问题也越来越多,例如安全,隐私,稳定,流畅等问题。