Will a browser give an iframe a separate thread for JavaScript?
JavascriptMultithreadingBrowserJavascript Problem Overview
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.
Javascript Solutions
Solution 1 - Javascript
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
andchrome://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>
Solution 2 - Javascript
Before chrome came along, all tabs of any browser shared the same single thread of JavaScript. Chrome upped the game here, and some others have since followed suit.
This is a browser implementation detail, so there is no solid answer. Older browsers definitely don't. I don't know of any browser that definitely uses another thread for iframes, but to be honest I've never really looked into it.
It isn't a security risk, as no objects are brought along with the thread execution.
Solution 3 - Javascript
To sum up the other answers: No, iFrames usually run in the same thread/process as the main page.
However, it appears the Chromium team are working on further isolation in this area:
Chromium Issue 99379: Out of process iframes [sorry, link not working - if you can find a link to the issue that works, please let me know]
Solution 4 - Javascript
I've had the same question myself this night, before checking for any existing answers. In the project I'm currently working we have to load an iFrame that uses a different framework and I was curios if that iFrame could somehow block the thread and affect my app. The answer is yes, it can.
My test was done in Chrome. In the parent I've loaded a child iFrame. In the parent I've set an interval to console.log a text every amount time. Then in the iFrame I've used a timeout to launch a 'while' that blocks the thread. The answer: the iFrame uses the same thread.
Example:
In the parent:
setInterval(() => {
console.log('iFrame still using the thread');
}, 3000)
In the iFrame:
setTimeout(() => {
console.log('now the thread is not working in the iFrame anymore');
while (true) {
}
}, 10000)
Solution 5 - Javascript
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.
Solution 6 - Javascript
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/
Solution 7 - Javascript
Late on this but... good point, cause iframe js seems to be concurrent in Firefox 16.
Try with alert function (blocking), you'll see dialogs opening together.
You won't see that in Chrome or IE.
iframe js may access the parent window in Firefox 16 as usual, so I can think of possible race conditions arising.
Solution 8 - Javascript
Did some experimenting with this today in Chrome 28 in Ubuntu. Used this command to see Chrome's threads and processes
ps axo pid,nlwp,cmd | grep "chrome"
It looks like Chrome does not spawn new threads or processes for iframes. An interesting note is that it does spawn a new process for the dev tools pane.
Solution 9 - Javascript
2022 Update (Experimental)
Iframes can now be run in parallel in at least Chrome Canary on desktop computers, but this is still experimental.
- Download Chrome Canary (https://www.google.com/chrome/canary/).
- Navigate to "chrome://flags/".
- Enable "Isolated sandboxed iframes".
- 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>
- 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>
- Open "index.html" in the browser.
- Verify that the console is consistently logging "index.html executed one iteration". Thus, the iframe is executed in parallel.
- 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
Solution 10 - Javascript
For iFrames, no. However if you want to use threads in JavaScript you can use Web Workers, a working html5 draft supported by the new browsers. http://www.w3.org/TR/2009/WD-workers-20091029/