咱们能够简单的认为 JavaScript 这门语言目前有两个主要的 runtime,一个是 Node.js,另外一个就是浏览器环境。咱们日常所谓的 JavaScript 是单线程的,实际上指的是 JavaScript 运行在 Render process 的 Main thread,什么是 Render process,看完你就明白了。web
先来扯一些背景知识,什么是进程,什么是线程(JavaScript 其实还有个协程的概念,不扯),这个对咱们后面的讲解很重要。面试
好比下面的代码,理论上来讲经过多线程处理要比单线程要快,缘由是由于多线程容许并行处理chrome
const a = 1 + 2;
const b = 20 / 5;
const c = 7 * 8;
console.log(a, b, c);
复制代码
下图展现同一个进程的内存是如何共享的浏览器
不扯之前的旧的浏览器架构,Chrome 浏览器的架构以下图所示(不必定最新)。须要注意的是,像 UI process, Network process 等等这些进程都有可能会被“降级”为 Browser process 的线程(UI thread, Network thread)。安全
When Chrome is running on powerful hardware, it may split each service into different processes giving more stability, but if it is on a resource-constraint device, Chrome consolidates services into one process saving memory footprint.网络
因此当你仅仅打开一个 tab 页的时候的进程信息多是这样的多线程
就是插件运行的进程,每一个插件一个进程,单独隔离出是为了防止插件挂了影响用户架构
主要负责 UI 渲染app
Handles GPU tasks in isolation from other processes. It is separated into different process because GPUs handles requests from multiple apps and draw them in the same surface.dom
负责网络资源加载
负责界面展现,用户交互,子进程管理,文件存取等
Controls anything inside of the tab where a website is displayed.
主要负责将 HTML, CSS, JavaScript 转换为用户可交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 就运行在渲染进程,默认每一个 tab 一个渲染进程(特殊状况下面的进程模式会讲)
Chromium 提供了四种进程模式,不一样的进程模式会对 tab 进程作不一样的处理,好比采用某个模式况会给 tab 分配新进程,而采用另一个模式则不会,下面是四种模式的介绍,Chrome 默认采用第一个模式
这里须要给出 site 和 site-instance 的定义
<a target="_blank">
这种方式点击打开的新页面window.open
)理解了这两个关键字就能够仔细说下上面的四种进程模式
Single process 和 Process-per-tab 就不用说了,意如其名。 若是使用 Process-per-site 模式,当你打开了一个 tab 访问 a.baidu.com,而后再打开一个 tab 访问 b.baidu.com,这两个 tab 其实用的是同一个进程,由于这两个 tab 被分在同一个 group。这就意味着,你在其中一个 tab 写一个死循环,这两个 tab 都会 hang
Process-per-site-instance 是最重要的,由于这个是 Chrome 默认使用的模式,也就是几乎全部的用户都在用的模式。当你打开一个 tab 访问 a.baidu.com,而后再打开一个 tab 访问 b.baidu.com,这两个 tab 会使用两个进程。若是 b.baidu.com 是经过 a.baidu.com 页面的 JavaScript 代码打开的,这两个 tab 会使用同一个进程,好比下图的例子,能够看到两个 tab 的 processId 是相同的
由于这种模型兼顾了性能与易用性,是一个比较中庸通用的模式
同时这么作也知足了 different subdomains or ports of a site to access each other via Javascript 这种需求。
咱们一开始的时候说过,同一个进程的多个线程是共享内存的。因此当两个 tab 使用同一个进程的时候,这两个 tab 就是“通的”。好比 A 页面使用 JavaScript 打开 B 页面,那么 B 页面能够经过 window.opener
访问 A 页面的 window
对象。
这个问题大概是面试出现几率最高的题目之一了,这整个流程其实有个名字叫 Navigation,咱们从进程线程的角度来梳理一下。
首先,在输入框输入 www.mysite.com
而后输入 Enter
这些都是由浏览器进程的 UI thread 来负责处理的,其中还有个额外的处理就是判断输入是一个 URL 仍是个 Query,不管是哪一个都要经过 IPC 通知网络进程发送请求,只不过请求的目标不同(输入的 URL / 搜索引擎)。
通知网络进程后,UI thread 展现 Spinner,Network process 会负责后续网络相关的处理好比 DNS lookup 和 establishing TLS Connection。Network process 有可能会收到 redirect response 好比 HTTP 301,这种状况 Network 会通知 UI thread 对输入框的 URL 作修改。
网络进程会根据 Content-Type(HTTP Header) 和文件的 MIME type 来对不一样的返回作不一样的处理。好比,若是是 HTML 会交给 Renderer process, 若是是 zip 会交给 Download manager。
同时这里会作一些安全检查,好比 SafeBrowsing 和 Cross Origin Read Blocking (CORB)
Network process 完成解析文件类型和安全检查后,会通知 Browser process,而后 browser process 经过 IPC 通知指定的渲染进程提交导航(commit the navigation),同时将网络进程的 data stream 传给渲染进程 so the renderer process can keep receiving HTML data。渲染进程在开始接收 HTML 后,会返回确认信息(confirm message),而后浏览器进程这边就会对 UI 作一些修改,好比 HTTPS 的小锁头,前进后退按钮等等
就像上面说的,Renderer process 收到 commit navigation 的信息后会返回 confirm message 给浏览器主进程,同时接收 HTML 并渲染的过程就开始了,具体细节不讲太复杂,咱们只关心进程间通信。渲染进程结束后而且全部 onload 事件触发后,会发送 IPC 给浏览器进程,而后 tab 页的 spinner 会中止,页面加载完成。