从一个标签页中打开另一个标签页,如果这两个标签页属于同一站点(相同协议,相同根域名),则他们会共用一个渲染进程。
为什么分别打开的两个相同站点在不同的渲染进程?
这与标签之间的连接方式有关。
标签之间的连接
- 通过 a 标签来和新标签建立连接。
<a href="https://time.geekbang.org/" target="_black" class=""> geek time </a>
这种方式会使新标签中的 window.opener 指向老标签页中的 window。这样在新 tab 页中就可以通过 opener 操作老 tab。即这两个 tab 存在连接。
- 通过 window.open 在 A 中打开 B
这样也是有连接的。
上述两种方式,即使不属于同一站点,也能通过 opener 建立连接。在 whatWG 规范中,把这种有相互连接关系的标签页称为浏览上下文组。一个 tab 中所包含的内容(window 对象、历史记录、滚动条位置等信息)称为浏览上下文。
Chrome 会讲浏览上下文组中属于同一站点的标签分配到同一个渲染进程中。这是因为如果一组标签页,既在同一个浏览上下文组中,又属于同一站点,那么它们可能需要在对方的标签页中执行脚本。因此,它们必须运行在同一渲染进程中。
结论:
分别打开的两个同一站点的 tab,由于它们之间没有连接关系,故不在同一个渲染进程。
例外
如果 a 连接的 rel 属性值使用了 noopener 和 noreferrer,则不会产生连接。
noopener 告诉浏览器通过这个链接打开的 tab 中的 opener 为 null。
noreferrer 告诉浏览器新打开的标签页不要有引用关系。
- 示例
站点隔离
Chrome 中实现了站点隔离的功能,意味着在标签页中的 iframe 也会遵守同一站点的分配原则。若有 tab 中的 iframe 与 tab 是同一站点且有连接关系,那么则运行在同一渲染进程。否则 iframe 运行在单独的渲染进程。
- 例子
<head><title> 站点隔离:demo</title><style>iframe {width: 800px;height: 300px;}</style></head><body><div><iframe src="iframe.html"></iframe></div><div><iframe src="https://www.infoq.cn/"></iframe></div><div><iframe src="https://time.geekbang.org/"></iframe></div><div><iframe src="https://www.geekbang.org/"></iframe></div></body></html>
在 Chrome 中的任务管理器里可以看到效果。
- iframe 中渲染进程个数的计算
同源策略对同一站点的限制
如果 A、B tab 属于同一站点,却不属于同源站点,AB 会处于同一渲染进程,但无法通过 opener 操作父标签页中的 DOM。
同一站点:根域名相同。(www.geek.com,time.geek.com)
思考题
- Chrome 为什么使用同一站点划分渲染进程,而不是使用同源策略来划分?
同一站点安全性有保障,资源复用方便,节约进程。
- 阿里云为什么要把 tab 做成无连接?
防止一个 tab 沦陷,导致其他 tab 全部沦陷。


