关于浏览器调度进程与线程的一些记录
1.查看浏览器进程快捷键
shirft + Esc
2.浏览器进程
从上面的图我们可以很明显的看出== Chrome 是一个多进程的架构==,我们打开一个浏览器时会启动多个不同的进程协助浏览器将页面为我们呈现出来:
- 浏览器进程
- 插件进程
- GPU进程
- 渲染进程
浏览器进程
浏览器最核心的进程,负责管理各个标签页的创建和销毁、页面显示和功能(前进,后退,收藏等)、网络资源的管理,下载等。
插件进程
负责每个第三方插件的使用,每个第三方插件使用时候都会创建一个对应的进程、这可以避免第三方插件crash影响整个浏览器、也方便使用沙盒模型隔离插件进程,提高浏览器稳定性。
GPU进程
负责3D绘制和硬件加速
渲染进程
浏览器会为每个窗口分配一个渲染进程、也就是我们常说的浏览器内核,这可以避免单个 page crash 影响整个浏览器。
3.浏览器内核的多线程
浏览器内核就是浏览器渲染进程,从接收下载文件后再到呈现整个页面的过程,由浏览器渲染进程负责。浏览器内核是多线程的,在内核控制下各线程相互配合以保持同步,一个浏览器通常由以下常驻线程组成:
- GUI 渲染线程
- 定时触发器线程
- 事件触发线程
- 异步http请求线程
- JavaScript 引擎线程
Javascript引擎线程
Javascript 引擎,也可以称为JS内核,主要负责处理 Javascript 脚本程序,例如V8引擎。Javascript 引擎线程理所当然是负责解析 Javascript 脚本,运行代码。
由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和UI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置 GUI 渲染线程与 JavaScript 引擎为互斥的关系,当 JavaScript 引擎执行时 GUI 线程会被挂起, GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。
4.JavaScript 为何设计成单线程
为什么 JavaScript 不设计成多个线程呢?这样不是效率更高?
作为浏览器脚本语言, JavaScript 的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定 JavaScript 同时有两个线程,一个线程在某个 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
所以,为了避免复杂性,从一诞生, JavaScript 就是单线程,这已经成了这门语言的核心特征,将来也不会改变。
5.web worker多线程解决方案
JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,尤其是多核 CPU 的出现,单线程带来很大的不便,无法充分发挥计算机的计算能力。
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
具体用法参考阮一峰日志