| 4 min read

其实这个话题,对很多人而言,如果之前没有细致了解过 Chrome 设计架构,还真不好说出答案,不过好在 Chrome 官方写了四篇文章,详细的阐释 Chrome 适合实现多进程,以及其具体作用的。

那么 Service Worker 是否运行在沙箱中呢?

我们先看下 Chrome 的多进程架构。

图1 浏览器多进程模型

如图所示,Chrome 包含多个进程,而其中 Browser Process 主要负责浏览器的 UI(比如上面那些插件图标显示,每个tab 的控制,输入框的交互事件等等...),Renderer Process 顾名思义,则是最为核心,我们每个页面渲染的进程,即我们每打开一个 Tab 访问某个页面,就会产生一个 Renderer Process。而 Plugin Process 则是我们在 Chrome 中装的第三方插件,比如 JSON Handler SwitchySharp 这些。

那么,Sandbox 又负责什么?

我们知道,现在很多网站会存在一些非常不安全的脚本,如果让浏览器有直接访问用户文件或者写入等行为是非常危险的,而沙箱的设计,则是为了隔离 JavaScript 的运行环境,让其具备受限的访问能力,Chrome的渲染引擎由SandBox隔离,网页代码要与浏览器内核进程通信、与操作系统通信都需要通过IPC channel,在其中会进行一些安全检查。

图2 沙箱设计模型

如图沙箱一般需要两个进程,

  • The Broker Process
  • The Target Process

在 Chrome 中 The Broker Process则是我们的 Browser Process,负责定义每个 Target Process 的访问限制,以及启动 sandbox 的 IPC (进程间通信) 服务等。而 Target Process 则是我们前面说的 Renderer Process. 因此我们可以大致理解所有执行的代码都是运行在 Sandbox 中。

那么 Service Worker 又是扮演怎样的角色呢?

我们 JS 是单线程语言,而在 Web Worker 发布之前,我们很难去模拟多线程的数据处理,而在引入 Worker 后,整个 Renderer Process 的架构就如下图了:

图3 Renderer Process 内部多线程实例

其中 Main Thread 就再熟悉不过了,就是我们执行 Prase Dom Tree 以及执行 JS 代码的主线程,而其中 Worker Threads 就是我们引入的 Worker 线程。

而 Service Worker 就是其中之一。

我们看下 Service Worker 的官方定义:

A service worker is a type of web worker. It's essentially a JavaScript file that runs separately from the main browser thread, intercepting network requests, caching or retrieving resources from the cache, and delivering push messages.

Service Worker 是一种类型的 Web Worker ,具备了同网络拦截,缓存的能力。

那么既然它是 Web Worker 又是如何实现网络的拦截的呢?

在没有 Service Worker 之前,可能我们的浏览器在请求完成某个页面的 Response 后,就会寻找 Renderer Process 然后开始正常的页面渲染程序,我们平常看到的

而 Service Worker 的出现,则是浏览器在开始启动 Renderer Process 的时候,网络进程会优先查看这个地址是否注册了 Service Worker ,如果注册了,则 UI 线程便会找到一个 Renderer Process 然后去执行 Service Worker 代码,Service Worker便会自己同 Network 线程交互,决定是否从缓存还是网络请求某些资源。

图5 Service Worker 启动通信

感谢 @Mariko Kosaka 的插图很生动形象,

扩展阅读

You Can Speak "Hi" to Me in Those Ways