浏览器工作原理与实践--浏览上下文组:如何计算Chrome中渲染进程的个数

news2024/11/26 20:39:08

经常有朋友问到如何计算Chrome中渲染进程个数的问题,那么今天就来完整地解答这个问题。

在前面“04 | 导航流程”这一讲中我们介绍过了,在默认情况下,如果打开一个标签页,那么浏览器会默认为其创建一个渲染进程。不过我们在“04 | 导航流程”中还介绍了同一站点的概念,如果从一个标签页中打开了另一个新标签页,当新标签页和当前标签页属于同一站点的话,那么新标签页会复用当前标签页的渲染进程。

具体地讲,如果我从极客邦(www.geekbang.org) 的标签页中打开新的极客时间(time.geekbang.org) 标签页,由于这两个标签页属于同一站点(相同协议、相同根域名),所以他们会共用同一个渲染进程。你可以看下面这张Chrome的任务管理器截图:

多个标签页运行在同一个渲染进程

观察上图,我们可以看到,极客邦官网和极客时间标签页都共用同一个渲染进程,该进程ID是84748。

不过如果我们分别打开这两个标签页,比如先打开极客邦的标签页,然后再新建一个标签页,再在这个新标签页中打开极客时间,这时候我们可以看到这两个标签页分别使用了两个不同的渲染进程。你可以参看下图:

多个标签页运行在不同的渲染进程中

那么到了这里,你一定会很好奇,既然都是同一站点,为什么从A标签页中打开B标签页,就会使用同一个渲染进程,而分别打开这两个标签页,又会分别使用不同的渲染进程?

标签页之间的连接

要搞清楚这个问题,我们要先来分析下浏览器标签页之间的连接关系。

我们知道,浏览器标签页之间是可以通过JavaScript脚本来连接的,通常情况下有如下几种连接方式:

第一种是通过<a>标签来和新标签建立连接,这种方式我们最熟悉,比如下面这行代码是从极客邦标签页里面拷贝过来的:

<a  href="https://time.geekbang.org/" target="_blank" class="">极客时间</a>

这是从极客邦官网中打开极客时间的链接,点击该链接会打开新的极客时间标签页,新标签页中的window.opener的值就是指向极客邦标签页中的window,这样就可以在新的极客时间标签页中通过opener来操作上个极客邦的标签页了。这样我们可以说,这两个标签页是有连接的。

另外,还可以通过JavaScript中的window.open方法来和新标签页建立连接,演示代码如下所示:

new_window = window.open("http://time.geekbang.org")

通过上面这种方式,可以在当前标签页中通过new_window来控制新标签页,还可以在新标签页中通过window.opener来控制当前标签页。所以我们也可以说,如果从A标签页中通过window.open的方式打开B标签页,那么A和B标签页也是有连接的。

其实通过上述两种方式打开的新标签页,不论这两个标签页是否属于同一站点,他们之间都能通过opener来建立连接,所以他们之间是有联系的。在WhatWG规范中,把这一类具有相互连接关系的标签页称为浏览上下文组( browsing context group)。

既然提到浏览上下文组,就有必要提下浏览上下文,通常情况下,我们把一个标签页所包含的内容,诸如window对象,历史记录,滚动条位置等信息称为浏览上下文。这些通过脚本相互连接起来的浏览上下文就是浏览上下文组。如果你有兴趣,可以参考下规范文档。

也就是说,如果在极客邦的标签页中,通过链接打开了多个新的标签页,不管这几个新的标签页是否是同一站点,他们都和极客邦的标签页构成了浏览上下文组,因为这些标签页中的opener都指向了极客邦标签页。

Chrome浏览器会将浏览上下文组中属于同一站点的标签分配到同一个渲染进程中,这是因为如果一组标签页,既在同一个浏览上下文组中,又属于同一站点,那么它们可能需要在对方的标签页中执行脚本。因此,它们必须运行在同一渲染进程中。

现在我们清楚了浏览器是怎么分配渲染进程的了,接下来我们就可以来分析文章开头提的那个问题了:

既然都是同一站点,为什么从A标签页中打开B标签页,就会使用同一个渲染进程? 而分别打开这两个标签页,又会分别使用不同的渲染进程?

首先来看第一种,在极客邦标签页内部通过链接打开极客时间标签页,那么极客时间标签页和极客邦标签页属于同一个浏览上下文组,且它们属于同一站点,所以浏览器会将它们分配到同一个渲染进程之中。

而第二种情况就简单多了,因为第二个标签页中并没有第一个标签页中的任何信息,第一个标签页也不包含任何第二个标签页中的信息,所以他们不属于同一个浏览上下文组,因此即便他们属于同一站点,也不会运行在同一个渲染进程之中。下面是我画的计算标签页的流程图,你可以参考下:

计算标签页使用的渲染进程数目

一个“例外”

好了,现在我们清楚了Chrome浏览器为标签页分配渲染进程的策略了:

  1. 如果两个标签页都位于同一个浏览上下文组,且属于同一站点,那么这两个标签页会被浏览器分配到同一个渲染进程中。

  2. 如果这两个条件不能同时满足,那么这两个标签页会分别使用不同的渲染进程来渲染。

现在你可以想一下,如果从A标签页中打开B标签页,那我们能肯定A标签页和B标签页属于同一浏览上下文组吗?

答案是“不能”,下面我们就来看个例子,在“04 | 导航流程”的留言区中,ID为“芳华年月”的朋友就提出了这样的一个问题:

请问老师,https://linkmarket.aliyun.com内新开的标签页都是新开一个渲染进程,能帮忙解释下吗?

我们先来复现下“芳华年月”所描述的现象,首先打开linkmarket.aliyun.com这个标签页,再在这个标签页中随便点击两个链接,然后就打开了两个新的标签页了,如下图所示:

“例外”情况

我通过A标签页中的链接打开了两个新标签页,B和C,而且我们也可以看出来,A、B、C三个标签页都属于同一站点,正常情况下,它们应该共用同一个渲染进程,不过通过上图我们可以看出来,A、B、C三个标签页分别使用了三个不同的渲染进程。

既然属于同一站点,又不在同一个渲染进程中,所以可以推断这三个标签页不属于同一个浏览上下文组,那么我们接下来的分析思路就很清晰了:

  1. 首先验证这三个标签页是不是真的不在同一个浏览上下文组中;

  2. 然后再分析它们为什么不在同一浏览上下文组。

为了验证猜测,我们可以通过控制台,来看看B标签页和C标签标签页的opener的值,结果发现这两个标签页中的opener的值都是null,这就确定了B、C标签页和A标签页没有连接关系,当然也就不属于同一浏览上下文组了。

验证了猜测,接下来的我们就是来查查,阿里的这个站点是不是采用了什么特别的手段,移除了这两个标签页之间的连接关系。

我们可以看看实现链接的HTML文件,如下图所示:

链接使用了rel = noopener

通过上图,我们可以发现,a链接的rel属性值都使用了noopener 和 noreferrer,通过noopener,我们能猜测得到这两个值是让被链接的标签页和当前标签页不要产生连接关系。

通常,将noopener的值引入rel属性中,就是告诉浏览器通过这个链接打开的标签页中的opener值设置为null,引入noreferrer是告诉浏览器,新打开的标签页不要有引用关系。

好了,到了这里我们就知道了,通过linkmarket.aliyun.com标签页打开新的标签页要使用单独的一个进程,是因为使用了rel= noopener的属性,所以新打开的标签页和现在的标签页就没有了引用关系,当然它们也就不属于同一浏览上下文组了。这也同时解答了“芳华年月”所提出的问题。

站点隔离

上面我们都是基于标签页来分析渲染进程的,不过我在“35|安全沙箱”中介绍过了,目前Chrome浏览器已经默认实现了站点隔离的功能,这意味着标签页中的iframe也会遵守同一站点的分配原则,如果标签页中的iframe和标签页是同一站点,并且有连接关系,那么标签页依然会和当前标签页运行在同一个渲染进程中,如果iframe和标签页不属于同一站点,那么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浏览器中打开上面这个标签页,然后观察Chrome的任务管理,我们会发现这个标签页使用了四个渲染进程,如下图所示:

iframe使用单独的渲染进程

结合上图和HTML代码,我们可以发现,由于InfoQ、极客邦两个iframe与父标签页不属于同一站点,所以它们会被分配到不同的渲染进程中,而iframe.html和源标签页属于同一站点,所以它会和源标签页运行在同一个渲染进程中。下面是我画的计算iframe使用渲染进程数目的流程图,你可以对照着参考下:

计算iframe所使用的渲染进程数目

总结

好了,本节的内容就介绍到这里,下面我来总结下本文的主要内容:

首先我们使用了两种不同的方式打开两个标签页,第一种是从A标签页中通过链接打开了B标签页,第二种是分别打开A和B标签页,这两种情况下的A和B都属于同一站点。

通过Chrome的任务管理器我们发现,虽然A标签页和B标签页都属于同一站点,不过通过第一种方式打开的A标签页和B标签页会共用同一个渲染进程,而通过第二种方式打开的两个标签页却分别使用了两个不同的渲染进程。

这是因为,使用同一个渲染进程需要满足两个条件:首先A标签页和B标签页属于同一站点,其次A标签页和B标签页需要有连接关系。

接着,我们分析了一个“例外”,如果在链接中加入了rel=noopener属性,那么通过链接打开的新标签页和源标签页之间就不会建立连接关系了。

最后我们还分析了站点隔离对渲染进程个数的影响,如果A标签页中的iframe和A标签页属于同一站点,那么该iframe和A标签页会共用同一个渲染进程,如果不是,则该iframe会使用单独的渲染进程。

好了,到了这里相信你已经会计算渲染进程的个数了。

在最后我们还要补充下同源策略对同一站点的限制,虽然Chrome会让有连接且属于同一站点的标签页运行在同一个渲染进程中,不过如果A标签页和B标签页属于同一站点,却不属于同源站点,那么你依然无法通过opener来操作父标签页中的DOM,这依然会受到同源策略的限制。

简单地讲,极客邦和极客时间属于同一站点,但是他们并不是同源的,因为同源是需要相同域名的,虽然根域名geekbang.org相同,但是域名却是不相同的,一个是time.geekbang.org,一个是www.geekbang.org, 因此浏览器判断它们不是同源的,所以依然无法通过time.geekbang.org标签页中的opener来操作www.geekbang.org中的DOM。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1606769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜维尔科技:【工业仿真】煤矿机械安全事故VR警示教育系统

产品概述 搜维尔科技 煤矿机械安全事故VR警示教育系统 系统内容&#xff1a; 系统采用虚拟现实技术模拟矿井井下机械安全技术及事故&#xff0c;展现井下常见机械伤害事故&#xff0c;表现伤害事故的隐患点&#xff0c;能够模拟事故发生和发展过程&#xff1b;营造井下灾害发…

C#基于SSE传递消息给Vue前端实现即时单向通讯

一、简述 通常前端调用后端的API&#xff0c;调用到了&#xff0c;等待执行完&#xff0c;拿到返回的数据&#xff0c;进行渲染&#xff0c;流程就完事了。如果想要即时怎么办&#xff1f;如果你想问什么场景非要即时通讯&#xff0c;那可就很多了&#xff0c;比如在线聊天、实…

HQL,SQL刷题,尚硅谷(中级)

目录 相关表结构&#xff1a; 1、order_info表 2、order_detail表 题目及思路解析&#xff1a; 第一题&#xff0c;查询各品类销售商品的种类数及销量最高的商品 第二题 查询用户的累计消费金额及VIP等级 第三题 查询首次下单后第二天连续下单的用户比率 总结归纳&#xff1a…

C#版Facefusion:让你的脸与世界融为一体!-02 获取人脸关键点

C#版Facefusion&#xff1a;让你的脸与世界融为一体&#xff01;-02 获取人脸关键点 目录 说明 效果 模型信息 项目 代码 下载 说明 C#版Facefusion一共有如下5个步骤&#xff1a; 1、使用yoloface_8n.onnx进行人脸检测 2、使用2dfan4.onnx获取人脸关键点 3、使用arcfa…

【MATLAB源码-第36期】matlab基于BD,SVD,ZF,MMSE,MF,SLNR预编码的MIMO系统误码率分析。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. MIMO (多输入多输出)&#xff1a;这是一个无线通信系统中使用的技术&#xff0c;其中有多个发送和接收天线。通过同时发送和接收多个数据流&#xff0c;MIMO可以增加数据速率和系统容量&#xff0c;同时提高信号的可靠性。…

算法1: 素数个数统计

统计n以内的素数个数 素数&#xff1a;只能被1和自身整除的自然数&#xff0c;0和1除外&#xff1b; 举例&#xff1a; 输入&#xff1a;100 输出&#xff1a;25 import java.util.*; class Test1{public static void main(String[] args){int a 100; //输入数字//…

41、二叉树-二叉树的层序遍历

思路&#xff1a; 层序遍历就是从左到右依次遍历。这个时候就可以使用队列的方式。例如先把头节点入队&#xff0c;然后遍历开始&#xff0c;首先计算队列长度&#xff0c;第一层&#xff0c;长度为了&#xff0c;遍历一次&#xff0c;依次出队&#xff0c;头结点出队&#xff…

Redis的RedisObject和对外可见的5种数据结构

目录 RedisObject Redis的编码方式 对外可见的5种数据结构 1.string string结构的源码 为什么是小于44字节会采用embstr编码&#xff1f; embstr和raw区别 2.list list结构的源码 3.set set结构的源码 4.zset zset结构的源码 5.hash hash结构的源码 Redis中…

淘宝客订单产品设计:连接商家与推广者的智能桥梁

随着电商行业的迅速发展&#xff0c;淘宝客作为一种常见的推广方式&#xff0c;为商家引流、提升销量发挥了重要作用。而淘宝客订单产品的设计&#xff0c;则是连接商家与推广者的智能桥梁&#xff0c;本文将对其进行探讨与分析。 ### 1. 淘宝客订单产品的定义 淘宝客订单产品…

梯度提升树(Gradient Boosting Trees)

通过5个条件判定一件事情是否会发生&#xff0c;5个条件对这件事情是否发生的影响力不同&#xff0c;计算每个条件对这件事情发生的影响力多大&#xff0c;写一个梯度提升树&#xff08;Gradient Boosting Trees&#xff09;模型程序,最后打印5个条件分别的影响力。 示例一 梯…

【目标检测】Focal Loss

Focal Loss用来解决正负样本不平衡问题&#xff0c;并提升训练过程对困难样本的关注。 在一阶段目标检测算法中&#xff0c;以YOLO v3为例&#xff0c;计算置信度损失&#xff08;图中第3、4项&#xff09;时有目标的点少&#xff0c;无目标的点多&#xff0c;两者可能相差百倍…

WSL(Ubuntu)、PC物理机,linux开发板三个设备通讯,镜像模式

文章目录 一、前言二、使用2.1 需要的系统信息2.2 添加 .wslconfig 文件 三、如何从局域网访问WSL中的服务 一、前言 最近在使用Linux开发板的环境下&#xff0c;由于使用的 WSL的子系统&#xff0c;并不是虚拟机&#xff0c;导致 网络传输 这方面不是很方便&#xff0c;由于 W…

AGM AG32 MCU在汽车UWB应用方案

AG32的汽车UWB应用方案 汽车电子产品的日益成熟&#xff0c;包括ADAS和车载信息娱乐&#xff0c;正在推动对CPLD的需求。例如&#xff0c;利用安装在车上的各种传感器&#xff08;如雷达、摄像头和激光雷达等&#xff09;来感知周围环境&#xff0c;实现实时监测和数据处理。这…

docker容器技术篇:数据卷的常用操作

Docker数据卷的使用 在docker中&#xff0c;为了方便查看容器内产生的数据或者将多个容器中的数据实现共享&#xff0c;就涉及到容器数据卷管理&#xff0c;那什么是数据卷呢&#xff0c;往下看&#xff01;&#xff01;&#xff01; 1 数据卷概念 数据卷是一个共给容器使用…

一款挺不错网站维护页面HTML源码

一款挺不错网站维护页面源码&#xff0c;单HTML不需要数据库&#xff0c;上传到你的虚拟机就可以用做维护页面还不错&#xff0c;用处多。。 源码下载 一款挺不错网站维护页面源码

C# - 反射动态添加/删除Attribute特性

API: TypeDescriptor.AddAttributes TypeDescriptor.GetAttributes 注意&#xff1a;TypeDescriptor.AddAttributes添加的特性需要使用 TypeDescriptor.GetAttributes获取 根据api可以看到&#xff0c;该接口不仅可以给指定类&#xff08;Type&#xff09;添加特性&#xf…

设计模式——模版模式21

模板方法模式在超类中定义了一个事务流程的框架&#xff0c; 允许子类在不修改结构的情况下重写其中一个或者多个特定步骤。下面以ggbond的校招礼盒发放为例。 设计模式&#xff0c;一定要敲代码理解 模版抽象 /*** author ggbond* date 2024年04月18日 17:32* 发送奖品*/ p…

华为框式交换机S12700E系列配置CSS集群

搭建集群环境 a.为两台交换机上电&#xff0c;按照数据规划分别对两台框式交换机进行配置 <HUAWEI> system-view [HUAWEI] sysname Switch1 [Switch1] set css id 1 [Switch1] set css priority 150 //框1的集群优先级配置为150 [Switch1] interface css-port 1 [Sw…

后端-MySQL-week11 多表查询

tips: distinct————紧跟“select”之后&#xff0c;用于去重 多表查询 概述 一对多&#xff08;多对一&#xff09; 多对多 一对一 多表查询概述 分类 连接查询 内连接 外连接 自连接 必须起别名&#xff01; 联合查询-union&#xff0c;union all 子查询 概念 分类 …

家庭营销广告Criteo公司首次获得MRC零售媒体测量认证

家庭营销广告Criteo公司首次获得零售媒体测量MRC认证 商业媒体公司Criteo2024年3月28日宣布&#xff0c;它首次获得媒体评级委员会&#xff08;MRC&#xff09;的认证&#xff0c;在其企业零售媒体平台commerce Max和commerce Yield上&#xff0c;在桌面、移动网络和移动应用内…