浏览器进程和线程
浏览器进程和线程
1. 浏览器进程
1.1 浏览器进程 main
浏览器的主进程,负责协调、主控,只有一个(无论打开几个tab或几个弹窗),主要作用:
- 负责浏览器界面显示,与用户交互,如前进,后退等;
- 负责各个页面的管理,创建和销毁其他进程;
- 将 Renderer 进程得到的内存中的 Bitmap,绘制到用户界面上;
- 网络资源的管理,下载等;
1.2 CPU进程
用于 3D 绘制等,可禁用掉,只有一个。
1.3 第三方插件进程
每种类型的插件对应一个进程,仅当使用该插件时才创建。
1.4 浏览器渲染进程
浏览器渲染进程(Renderer 进程),即通常所说的浏览器内核,主要作用:页面渲染、脚本执行、事件处理等。每一个标签页的打开都会创建一个Renderer 进程,且互不影响。默认一个标签页一个 Renderer 进程,但是,有时候浏览器会将多个进程合并(暂时没查到合并的依据),比如打开多个空白标签页。
作为前端开发,最关心的自然是页面渲染、脚本执行、事件处理等过程,这就不得不介绍 Renderer 进程。
首先,Renderer 进程包含以下5种线程:
1.4.1 GUI渲染线程
负责渲染浏览器界面,解析 HTML,CSS,构建 DOM 树和 RenderObject 树,布局和绘制等;
当界面需要重绘(Repaint)或由于某种操作引发回流(Reflow)时,该线程就会执行;
注意:GUI 渲染线程与 JS 引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起(相当于被冻结了),GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行。
1.4.2 js 引擎线程
- JS 引擎线程也称为 JS 内核,负责处理 Javascript 脚本程序,解析 Javascript 脚本,运行代码;
- JS 引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个 JS 线程在运行 JS 程序;
注意:GUI 渲染线程与 JS 引擎线程的互斥关系,所以如果 JS 执行的时间过长,会造成页面的渲染不连贯,导致页面渲染加载阻塞。
实例:
function demo() { const now = Date.now(); document.body.style.backgroundColor = 'red'; while(Date.now() - now <= 2000) { continue; } document.body.style.backgroundColor = 'blue'; }
正确答案:2s后直接变蓝。
解释:Js 线程执行到 document.body.style.backgroundColor = 'red';
,Js 线程知道这个是 GUI 线程该做的事,于是把该任务放到 GUI 线程中的任务队列里(并未执行),然后 Js 线程直到while循环,在这忙等了 2s。然后碰到 document.body.style.backgroundColor = 'blue';
GUI 线程把它压到任务队列里(并未执行)。此时 Js执行已经完毕,于是 GUI 线程执行,清空 GUI 线程的任务,最后一个任务是变蓝,于是是 2s 后直接变蓝。
1.4.3 事件触发线程
归属于浏览器而不是 JS 引擎,用来控制事件循环(可以理解,JS 引擎自己都忙不过来,需要浏览器另开线程协助);
当 JS 引擎执行代码块如 setTimeOut 时(也可是来自浏览器内核的其他线程,如鼠标点击、AJAX 异步请求等),会将对应任务添加到事件触发线程中;
当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待 JS 引擎的处理;
注意:由于 JS 的单线程关系,所以这些待处理队列中的事件都得排队等待 JS 引擎处理(当 JS 引擎空闲时才会去执行);
1.4.4 定时器触发线程
即 setInterval 与 setTimeout 所在线程;
浏览器定时计数器并不是由 JS 引擎计数的,因为 JS 引擎是单线程的,如果处于阻塞线程状态就会影响记计时的准确性;
因此使用单独线程来计时并触发定时器,计时完毕后,添加到事件队列中,等待 JS 引擎空闲后执行,所以定时器中的任务在设定的时间点不一定能够准时执行,定时器只是在指定时间点将任务添加到事件队列中;
注意:W3C 在 HTML 标准中规定,定时器的定时时间不能小于 4ms,如果是小于 4ms,则默认为4ms。
1.4.5 异步HTTP请求线程
XMLHttpRequest 连接后通过浏览器新开一个线程请求;
检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将回调函数放入事件队列中,等待 JS 引擎空闲后执行;
综上所述,浏览器各进程线程关系大致如下图:
2. 浏览器为什么是多进程
对于简单的网页,一个进程处理多个网页是可行的。
但是把很多复杂的网页放进一个进程,浏览器面临在健壮性,响应速度,安全性方面的挑战。如果一个tab页崩溃,将导致同进程的其他页面崩溃,极其影响用户体验。
另外进程之间是不共享资源和地址空间的,所以不会存在太多的安全问题。
当然,多进程相对于单进程,内存等资源消耗更大,有点空间换时间的意思。这大概也是浏览器中存在多个tab页共用一个进程的情况的原因吧。
浏览器