window.open()的奇妙冒险

前言
一个简单的优化需求,竟然引发了window.open()的奇妙化学反应☠️

背景
项目X的A页面需要点击一个区域后,跳转到对应的页面B,这个页面需要新开窗口来展示。B页面成功打开后再起接口还在loading的时候关闭,会造成当前浏览器中所有项目X的页面卡死;反之当B页面所有接口loading完成后再关闭就不会卡死😅。这里跳转尝试了多种方式——window.open();React的<Link />标签;react-router的useHistory等等,除了useHistory正常外其他均以卡死阵亡,但是使用useHistory的跳转效果又不符合产品想要的新窗口展示😱。

调研
经过不限的努力去baidu~😮‍💨终于找到它的关键——进程!😱

进程模型
站点(site):站点的判定规则相当于不严格的同源协议,详见第二篇参考。

站点实例(site instance):站点实例是来自同一站点且有关联关系的页面的集合,详见第二篇参考。

以Chrome浏览器为例,Chrome在4.0.229.1版本的时候引入了多进程架构(现在已经是96.0.4664.55版本了😅),其支持了下面四种进程模型:

[Default]Process-per-site-instance:此模型下Chrome会为每个site instance创建一个渲染进程,来确保不同site instance被独立呈现。如果A、B两个页面在脚本中存在引用,如在http://www.projectX.com/A.html使用JS打开一个新窗口http://www.projectX.com/B.html🎯,浏览器会认为这两个页面存在关联关系,并将其划入同一个site instance。
Process-per-site:此模型以site维度来为分组,同一site的页面使用一个渲染进程。使用方式为Chromium启动时注入--process-per-site命令来启动。
Process-per-tab:此模型每一个选项卡都有一个专属渲染进程,不论页面有没有联系,且不随时间而改变。使用方式为Chromium启动时注入--process-per-tab命令来启动。
Single process:人如其名,此模型是启用单进程,所有选项卡共用一个进程。使用方式为Chromium启动时注入--single-process命令来启动。
原因
了解完进程模型后就大致分析出问题所在了。跳转的落地页需要拉取大量数据用于渲染图表,存在高开销的JS执行内容,提前关闭窗口导致JS某处出错/产生死循环(🧐推测的),从而使整个进程卡死。

下面用个例子在佐证一下我的推测:

A通过onclick事件触发window.open事件,跳转到B页面;B页面有死循环
疯狂关闭B页面
回到A页面,A页面也被卡死
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Page A</title>
</head>
<body>
  This is Page A !
  <button id="grave">TO B</button>
  <script>
    const buttonDom = document.getElementById('grave');
    buttonDom.onclick = () => {
      window.open('./indexB.html');
    }
  </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值