我最近听说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不同的顶级域时那样。
在某些浏览器(包括 Chrome)中,跨域 iframe已经在单独的进程中运行。例如,在 Chrome 中运行以下代码片段不会阻止您在父 Stack Overflow 窗口中滚动:
while (true) {
}Run Code Online (Sandbox Code Playgroud)
对于尚未执行此操作的浏览器,或者对于同源 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 parentRun Code Online (Sandbox Code Playgroud)
body {
height: 1000px;
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3264 次 |
| 最近记录: |