在单独的进程中创建 iframe,这样它就不会阻塞父窗口的主线程

5 html javascript

我最近听说rel="noopener"可以添加到锚标记的属性值,以便新窗口在单独的进程中运行。这让我想知道:是否可以创建一个在单独进程中运行的 iframe,以便 iframe 中的无限循环不会导致父窗口的主线程被阻塞?

下面是一些观察主线程冻结的示例代码:

<progress></progress>
<iframe srcdoc="<script>function loop() { i=0; while(i<700000000){i++}; setTimeout(loop, 2000) }; loop();</script>"></iframe>
Run Code Online (Sandbox Code Playgroud)

https://jsbin.com/zabecoviwi/1/edit?html,输出

编辑:请注意,您可以通过向 iframe 添加属性来防止冻结sandbox,这似乎“强制”浏览器(至少是 Chrome)将 iframe 放在单独的线程中,但在我的情况下我不能这样做。然而,我在一个单独的子域下提供 iframe 的代码,所以我认为,由于它是一个单独的源,Chrome 会将其放入一个单独的进程中,就像 iframe 是src不同的顶级域时那样。

Cer*_*nce 2

在某些浏览器(包括 Chrome)中,跨域 iframe已经在单独的进程中运行。例如,在 Chrome 中运行以下代码片段不会阻止您在父 Stack Overflow 窗口中滚动:

对于尚未执行此操作的浏览器,或者对于同源 iframe,您可以通过在 iframe 中的 Web Worker 中运行昂贵的任务来使该过程变得明确:

const workerFn = () => {
  // something expensive
  while (true) {
  }
};
const workerFnStr = `(${workerFn})();`;
const blob = new Blob([workerFnStr], { type: 'text/javascript' });
const worker = new Worker(window.URL.createObjectURL(blob));

// The worker has been created, and will continuously consume resources,
// but will not block the iframe window or the iframe's parent
Run Code Online (Sandbox Code Playgroud)
body {
  height: 1000px;
}
Run Code Online (Sandbox Code Playgroud)