Will a browser give an iframe a separate thread for JavaScript?

Viewed 22861

Do web browsers use separate executional threads for JavaScript in iframes?

I believe Chrome uses separate threads for each tab, so I am guessing that JavaScript in an iframe would share the same thread as its parent window, however, that seems like a security risk too.

10 Answers

Recently tested if JavaScript running in a iFrame would block JavaScript from running in the parent window.

iFrame on same domain as parent:

  • Chrome 68.0.3440.84: Blocks
  • Safari 11.0.2 (13604.4.7.1.3): Blocks
  • Safari 15.1 on iOS: Blocks
  • Firefox 96: Blocks

iFrame on different domain as parent

  • Chrome 68.0.3440.84: Doesn't block
  • Safari 11.0.2 (13604.4.7.1.3): Blocks (outdated, but I don't have a macbook)
  • Safari 15.1 on iOS: Doesn't block
  • Firefox 96: Doesn't block
  • Chrome for Android 96: sometimes Blocks and sometimes Doesn't block (There are some complex rules in Chrome for Android that determine when Chrome for Android does and doesn't isolate a process, see chrome://process-internals and chrome://flags)

parent.html:

    <body>
    <div id="count"></div>
    <iframe src="./spin.html"></iframe>     
    <script>
        let i = 0;
        let div = document.getElementById("count");
        setInterval(() => {
            div.innerText = i++;
        }, 100);
    </script>
    </body>

spin.html:

    <body>
    <button id="spin">spin</button>
    <script>
        const spin = document.getElementById("spin");
        spin.addEventListener('click', () => {
            const start = Date.now();
            while (Date.now() - start < 1000) { }
        })
    </script>
    </body>

2021 Update:

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.com expects to use lots of resources for video chat, and will be embedded on various origins throughout https://*.example.com, 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/

Only chrome & firefox on desktop (no, not mobile) is separating threads.

I've created a small page that run long loop in interval in the main page, and shows an animation both in the main page and in the iframe. You can go to the site from the browser you wish to check.

If the lower animation (under 'crossorigin') runs without stopping, it's have a separate thread.

https://eylonsu.github.io/browser_thread/

2022 Update (Experimental)

Iframes can now be run in parallel in at least Chrome Canary on desktop computers, but this is still experimental.

  1. Download Chrome Canary (https://www.google.com/chrome/canary/).
  2. Navigate to "chrome://flags/".
  3. Enable "Isolated sandboxed iframes".
  4. Create "index.html" with the following content:
<h1>index.html</h1>
<iframe src="index-child.html" sandbox="allow-scripts"></iframe>
<script>
    setInterval(() => {
        console.log("index.html executed one iteration");
    }, 1000)
</script>
  1. Create "index-child.html" with the following content:
<h1>index-child.html</h1>
<script>
    setTimeout(() => {
        console.log("index-child.html started continuous execution");
        while (true) {
        }
    }, 3000)
</script>
  1. Open "index.html" in the browser.
  2. Verify that the console is consistently logging "index.html executed one iteration". Thus, the iframe is executed in parallel.
  3. Disable "Isolated sandboxed iframes" (or just use another browser) and open "index.html" again. The console is no longer consistently logging "index.html executed one iteration". Thus, the iframe is no longer executed in parallel.

Note: The sandbox attribute on the iframe tag must be correctly set for this to work. Additionally, only one extra process per site is currently supported, which means that multiple iframes will not all run in parallel.

The specific instructions from "chrome://flags/":

Isolated sandboxed iframes
When enabled, applies process isolation to iframes with the 'sandbox' attribute and without the 'allow-same-origin' permission set on that attribute. The current isolation model is that all sandboxed iframes from a given site will be placed into the same process, but alternative models may be introduced in future experiments. – Mac, Windows, Linux, Chrome OS, Fuchsia

Related