最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating an iframe in separate process so it doesn't block the main thread of the parent window - Stack Ove

programmeradmin2浏览0评论

I recently heard about the rel="noopener" attribute value that can be added to anchor tags so that the new window runs in a separate process. That got me wondering: Is it possible to create an iframe that runs in a separate process so that, for example, an infinite loop in the iframe won't cause the parent window's main thread to be blocked?

Here's some example code to observe the main-thread freeze:

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

,output

Edit: Note that you can prevent the freezing by adding the sandbox attribute to the iframe, which seems to "force" the browser (Chrome, at least) to put the iframe in a separate thread, but I can't do this in my case. I am however serving the code for the iframe under a separate subdomain so I'd have thought that since it's a separate origin Chrome would put it in a separate process as it appears to do if the iframe's src is a different top-level domain.

I recently heard about the rel="noopener" attribute value that can be added to anchor tags so that the new window runs in a separate process. That got me wondering: Is it possible to create an iframe that runs in a separate process so that, for example, an infinite loop in the iframe won't cause the parent window's main thread to be blocked?

Here's some example code to observe the main-thread freeze:

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

https://jsbin./zabecoviwi/1/edit?html,output

Edit: Note that you can prevent the freezing by adding the sandbox attribute to the iframe, which seems to "force" the browser (Chrome, at least) to put the iframe in a separate thread, but I can't do this in my case. I am however serving the code for the iframe under a separate subdomain so I'd have thought that since it's a separate origin Chrome would put it in a separate process as it appears to do if the iframe's src is a different top-level domain.

Share Improve this question edited Jun 13, 2019 at 23:51 asked Jun 13, 2019 at 23:24 user10898116user10898116
Add a ment  | 

2 Answers 2

Reset to default 4

As of early 2021, there is now the Origin-Agent-Cluster header which allows you to request dedicated resources for an iframe. It is currently supported on Chrome (88+) with positive reception from Mozilla and Safari.

Origin-Agent-Cluster is a new HTTP response header that instructs the browser to prevent synchronous scripting access between same-site cross-origin pages. Browsers may also use Origin-Agent-Cluster as a hint that your origin should get its own, separate resources, such as a dedicated process.

[...] For example, if https://customerservicewidget.example. expects to use lots of resources for video chat, and will be embedded on various origins throughout https://*.example., the team maintaining that widget could use the Origin-Agent-Cluster header to try to decrease their performance impact on embedders.

To use the Origin-Agent-Cluster header, configure your web server to send the following HTTP response header: Origin-Agent-Cluster: ?1 The value of ?1 is the structured header syntax for a boolean true value.

More details here: https://web.dev/origin-agent-cluster/

In some browsers, including Chrome, cross-origin iframes already run in a separate process. For example, running the following snippet in Chrome will not prevent you from scrolling in the parent Stack Overflow window:

while (true) {
}

For browsers which don't do this already, or for same origin iframes, you can make the process explicit by running the expensive tasks in a web worker in the iframe:

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
body {
  height: 1000px;
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论