浏览器的工作原理(进阶必备知识) | 8月更文挑战

385 阅读7分钟

简介

网络浏览器是使用特别广的软件,目前使用的主流浏览器有五个:Internet Explorer、Firefox、Safari、Chrome 浏览器和 Opera。我们就从Chrome浏览器来讲解浏览器的工作原理。

CPU 与 GPU

CPU 和 GPU 作为计算机中最重要的两个计算单元直接决定了计算性能。
  1. CPU: 中央处理器,解析计算机指令,负责处理各种不同的任务,它可以串行地一件接着一件处理交给他的任务,CPU的核⼼数是指物理上,也就是硬件上存在着⼏个核⼼。⽐如,双核就是包括2个相对独⽴的CPU核⼼单元组,四核就包含4个相对独⽴的CPU核⼼单元组

  2. GPU: 图形处理器, 单个GPU核⼼只能处理⼀些简单的任务,不过它胜在数量多,单⽚GPU上会有很多很多的核⼼可以同时⼯作,也就是说它的并⾏计算能⼒是⾮常强的

  3. 进程 & 线程 进程 - 可以看成正在被执⾏的应⽤程序(executing program)。

线程 - 是跑在进程⾥⾯的,⼀个进程⾥⾯可能有⼀个或者多个线程,这些线程可以执⾏任何⼀部分应⽤程序的代码

当应用被启动,进程就被创建出来,程序可以创建线程来帮助其工作,当你启动⼀个应⽤程序的时候,操作系统会为这个程序创建⼀个进程同时还为这个进程分配⼀⽚私 有的内存空间,这⽚空间会被⽤来存储所有程序相关的数据和状态。

当你关闭这个程序的时候,这个程序对应的进程也会随之消失,进程对应的内存空间也会被操作系 统释放掉。

很多应⽤程序都会采取多进程的⽅式来⼯作,因为进程和进程之间是互相独⽴的,它们互不影响。 换句话来说,如果其中⼀个⼯作进程挂掉了,其他进程不会受到影响,⽽且挂掉的进程还可以重启

浏览器架构

借助进程和线程,浏览器可以被设计成单进程、多线程架构,或者利用 IPC 实现多进程、多线程架构。

image.png

我们以 Chrome 多进程架构介绍,在 Chrome 中存在这不同种类型的进程,它们各司其职。

image.png

Browser(⼀个) - 浏览器进程, 只有⼀个浏览器进程,负责浏览器的主体部分,包括导航栏,书签, 前进和后退按钮, 提供存储等功能

Network(⼀个) - ⽹络进程, 主要负责⻚⾯的⽹络资源加载,之前是作为⼀个模块运⾏在浏览器进程⾥ ⾯的,直⾄最近才独⽴出来,成为⼀个单独的进程

GPU(⼀个) - 图像渲染进程, 负责独⽴于其它进程的GPU任务。它之所以被独⽴为⼀个进程是因为它要处理来⾃于不同tab的渲染请求并把它在同⼀个界⾯上画出来。

Renderer(多个) - 渲染进程, 负责tab内和⽹⻚展⽰相关的所有⼯作, ⽐如将 HTML、CSS 和

JavaScript 转换为⽤⼾可以与之交互的⽹⻚, 默认情况下每个tab都有⼀个独⽴的渲染进程。

Plugin(多个) - 插件进程

Extensions(多个) - 扩展程序进程

其他进程 - ⼯具进程,辅助框架等等

可以在chrome浏览器 更多⼯具 - 任务管理器 查看当前浏览器所开启的进程, 以及内存和cpu消耗

多进程架构的好处

当我们访问一个站点时,渲染进程会负责运行站点的代码,渲染站点的页面,同时响应用户的交互动作,当我们在 Chrome 中打开三个页签同时访问三个站点时,如果其中一个没有响应,我们可以关闭它然后使用其他的页签,这是因为 Chrome 为每个站点创建一个独立的渲染进程,专门处理当前站点的渲染工作。如果所有的页面运行在同一个进程中,当有一个页面没有响应时,所有的页面就都卡住了。

image.png

1. 容错性

Chrome会为每个tab单独分配⼀个属于它们的渲染进程(render process)。举个例⼦,假如你有三个tab,你就会有三个独⽴的渲染进程。

当其中⼀个tab的崩溃时,你可以随时关闭这个tab并且其他tab不受到影响。可是如果所有的tab都跑 在同⼀个进程的话,它们就会有连带关系,⼀个挂全部挂。

2. 安全性和沙盒性

因为操作系统可以提供⽅法让你限制每个进程拥有的能⼒,所以浏览器可以让某些进程不具备某些 特定的功能。例如,由于tab渲染进程可能会处理来⾃⽤⼾的随机输⼊,所以Chrome限制了它们对 系统⽂件随机读写的能⼒。

3. 每个进程可以拥有更多内存

因为每个进程都会分配⼀块独⽴的内存空间, 所以理所当然的, 每个进程都会有更多的内存。

多进程架构的坏处

其实上⾯已经提到了, 每个进程都会拥有⾃⼰独⽴的内存空间, 他们并不能像同⼀个进程中的线程⼀样共享内存空间。

⽽⼀些基础的东西⽐如V8 Javascript引擎, 会在不同进程的内存空间中同时存在, 所以就消耗了不必要的内存。

多进程架构内存的优化

  • Chrome是怎么优化这种情况的呢? 限制启动的进程数⽬,当进程数⽬达到⼀定界限后, Chrome会将访问同⼀个⽹站的tab都放在⼀个进程⾥⾯跑。

  • Chrome的服务化, 节省更多的内存

image.png

Chrome浏览器的架构正在发⽣⼀些改变,⽬的是将和浏览器本⾝(Chrome)相关的部分拆分为⼀ 个个不同的服务,服务化之后,这些功能既可以放在不同的进程⾥⾯运⾏也可以合并为⼀个单独的 进程运⾏。

Chrome浏览器的架构正在发⽣⼀些改变,⽬的是将和浏览器本⾝(Chrome)相关的部分拆分为⼀ 个个不同的服务,服务化之后,这些功能既可以放在不同的进程⾥⾯运⾏也可以合并为⼀个单独的 进程运⾏。

导航时发生了什么

  1. 处理输入 当我们在地址栏中输入时,UI 线程会先判断我们输入的内容是要搜索的内容还是要访问一个站点,因为地址栏同时也是一个搜索框。
  1. 开始导航 当我们按下回车开始访问时,UI 线程将借助网络线程访问站点资源.

这时tab上icon会展示一个提示资源正在加载的旋转圈圈,而且网络进程会进行一系列诸如DNS寻址以及为请求建立TLS连接的操作

  1. 读取响应
  • 响应类型的判断
  • 不同响应类型的处理
  • 安全检查
  1. 寻找一个进程来绘制页面 在网络进程做完所有的检查后并能告诉浏览器应该导航到该请求的站点,它就会告诉UI线程所有的数据都已经被准备好了。
  1. 提交导航 到这一步的时候,数据和渲染进程都已经准备好了,浏览器进程会通过IPC告诉浏览器渲染进程去提交本次导航
  1. 加载完成 当导航提交完成以后,渲染进程开始着手加载资源以及渲染页面,一旦渲染进程王成渲染(load),它会通过IPC告知浏览器进程,然后UI线程就会停止导航栏上旋转的圈圈。

访问不同的站点

一次普通的访问到此就结束了。当我们输入另外一个地址时,浏览器进程会重复上面的过程。但是在开始新的访问前,会确认当前的站点是否关心beforeunload事件。 beforeunload事件可以提醒用户是否要访问新的站点或者关闭页签,如果用户拒绝则新的访问或关闭会被阻止。 由于所有的包括渲染、运行 Javascript 的工作都发生在渲染进程中,浏览器进程需要在新的访问开始前与渲染进程确认当前的站点是否关心unload。