[前端进阶] - 搞懂浏览器进程和线程

前言

大家好,我是辉夜真是太可爱啦

前端开发工作者几乎天天与浏览器打交道,熟悉浏览器,能让我们的技术提升,有着质的飞越。

在开始之前,让我们先来搞懂进程和线程的概念。

讲个故事

为了方便大家的理解,我们将计算机的资源比喻成一个工业园区。

在工业园区内有很多个工厂,每个工厂都占有着独立的场地,工厂里面有一个或多个工人。

image.png

那么,现在将角色互换,工业园区就是 计算机资源 ,工厂就是进程,工人就是线程。

image.png

可以总结如下的规则:

  1. 计算机资源独立分配到各个进程,进程之间 互相独立(可以通信,但是代价较大)

  2. 一个进程由一个或多个线程组成,是包含关系

  3. 同一进程下的各个线程之间共享程序的内存空间

可以打开任务管理器,能看到当前系统中有很多的进程存在。

image.png

我们可以来看一下比较官方的解释:

进程是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)

线程是cpu调度的最小单位(线程是建立在进程的基础上的一次程序运行单位)

tips:

  • ① 不同进程之间也可以通信,不过代价较大
  • 单线程与多线程,都是指在一个进程内的单和多

多进程的浏览器

浏览器,是一种多进程的架构设计,在浏览器中打开一个网页相当于新起了一个进程,当然,浏览器也有它自己的优化机制,比方说有五个空白页,这五个空白页会合并成同一个进程。

主要包含一下四种进程:

1. Browser进程(主进程)

控制chrome的地址栏,书签栏,返回和前进按钮,同时还有浏览器的不可见部分,例如网络请求和文件访问

2. 第三方插件进程

每种插件一个进程,插件运行时才会创建

3. GPU进程

仅此一个 ,用于3D绘制等

4. 浏览器渲染进程(浏览器内核)

负责界面渲染,脚本执行,事件处理等

多进程的优势

  1. 避免单个页面崩溃造成整个浏览器的卡顿(由于每一个 Tab页 都是独立的进程)

  2. 避免第三方插件崩溃影响整个浏览器(由于第三方插件是独立的进程)

  3. 多进程充分利用多核优势(现在的 CPU 性能都很高)

多线程的浏览器内核

浏览器的内核,是极其复杂的,毕竟浏览器的整个核心,就是它,它主要由以下五种线程组成:

1. GUI渲染线程

负责渲染浏览器界面(解析 HTML ,CSS,构建 DOM树 CSSOM树Render树 ,布局和绘制等)。

GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行,当界面需要重绘或由于某种操作引发的重排时,该线程就会执行。

GUI 渲染线程与 JS 引擎线程是互斥的,这也是造成 JS堵塞 的原因所在。

由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JS 引擎线程和 GUI 渲染线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。

因此为了防止渲染出现不可预期的结果,浏览器设置 GUI 渲染线程与 JavaScript 引擎为互斥的关系,当 JavaScript 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。

如果想了解有关于 CSSJS 的堵塞问题,可以查阅 面试中常问到的CSS堵塞和JS堵塞

2. JS引擎线程

也称为 JS 内核,负责处理 JavaScript 脚本程序。

JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页中无论什么时候都只有一个JS线程在运行JS程序(我们早在之前说过了,JS是一门单线程的语言。至于原因可以查阅 单线程的JS

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

3. 事件触发线程

首先这属于浏览器而不是JS引擎,主要用来控制事件循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)

当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中。

当对应的事件符合触发条件被触发时,该线程会把是事件添加到待处理队列(宏任务)的队尾,等待JS引擎的处理。

同样地,由于 JS 是单线程的,所以需要等到 JS 引擎空闲了之后,才会对待处理队列进行处理。

4. 定时触发器线程

传说中的 setIntervalsetTimeout 所在线程。

因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确。

因此通过单独线程来计时并触发定时,计时完毕后,添加到事件队列(宏任务)中,等待JS引擎空闲后执行。

不禁感叹,懂得 JS 的单线程 原来那么有用。

需要值得注意的是,W3C 在 HTML 标准中规定,规定要求 setTimeout 中低于4ms的时间间隔算为4ms。

5. 异步http请求线程

XMLHttpRequest 在连接后是通过浏览器新开的一个线程请求。

当检测到状态更新时,如果没有设置回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列(微任务)中,等待 JS 引擎执行。

关于这个事件队列的执行机制,以及对于 微任务宏任务 云里雾里的,可以查阅一文搞懂JS系列(六)之微任务与宏任务,Event Loop

一图概览

所以,综上所述,浏览器的进程和线程可以用下面的一张图概括:

image.png

文章参考

从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

浏览器的进程和线程

Guess you like

Origin juejin.im/post/7053974933931556900