Iframes and Process Allocation<!-- --> | <!-- -->Web Performance Tips

Iframes and Process Allocation

A common question I've encountered when consulting with teams that utilize <iframe> in their web application architecture is: Does an <iframe> execute in parallel on a separate thread / in a dedicated process?

Web application process management is handled by the browser, and this can lead to interesting and unexpected performance implications when using <iframe> elements.

In this tip, I detail a few different considerations regarding how Chromium browsers group frames together into shared processes and how an iframe based web architecture may have unique performance considerations when compared to ordinary web applications.

Example: A Third Party Add-On / Extension

Many web applications are becoming Platforms that host other applications. Consider Microsoft Teams Apps, Stripe Apps, Slack Apps, Google Workspace Extensions, and so on. Platforms expose an Extension API and allow web developers to build custom extensions with access to certain privileged data, APIs, and authorization contexts.

For example, consider the Monday.com integration for Microsoft Teams or the DocuSign integration for Stripe

Platform/Host applications do not directly execute these third-party extensions and instead expose the APIs to the Extension (for example, allowing a hosted extension to read User or Message data from Microsoft Teams, or Invoice Details from Stripe).

This is usually modeled as a hosted <iframe> and a postMessage based API contract.

A diagram of a hosted extension hosting an extension application in an iframe, using a postMessage channel to communication

How does the browser facilitate this?

The answer is that it will vary depending on how the <iframe> element is configured within a Host!

Chromium uses a combination of tab-based isolation and site-based isolation. Generally, this means:

  1. Each new browser tab will be granted a dedicated Renderer process (and Main Thread) to run the web application in the address bar
  2. Iframes within a browser tab, if they differ in site origin (i.e., microsoft.com and monday.com differ in site origin), will run in separate Renderer processes
  3. Iframes within a browser tab, if they share the same site origin (i.e. dashboard.stripe.com and dashboard.stripe.com/extension share the same origin of stripe.com) and will run in the same Renderer process

Let's look a bit more closely at a few examples!

The Host Application

A Host Application runs directly in the user's browser tab. (i.e., the Microsoft Teams, Slack, Stripe Dashboard, etc.). When a user opens the Host Application, the browser will create a new Renderer process.

A diagram of Microsoft Teams running in a dedicated Renderer process

If the user opens another browser tab to a separate instance of the Host application, the browser will allocate another renderer process.

A diagram of Microsoft Teams running in a dedicated Renderer process

In this scenario:

  1. The two Renderer processes may execute JavaScript code and update their respective DOM instances in parallel; they each have dedicated Main Threads
  2. The two Renderer processes may not share code execution or DOM (i.e. a <script> tag or Document Node in one tab does not become available to the other process)

Opening a Hosted extension with different origin

Let's consider what happens when a user opens the third-party extension application iframe hosted on a different origin. This is the model that the Microsoft Teams / Microsoft 365 Apps framework has taken.

<!-- Within teams.microsoft.com host -->

<iframe src="https://www.monday.com/teams_extension"></iframe>

Now, there's an iframe embedded in the page, pointing to a different origin, hosting the third-party application.

How does the browser allocate processes for this case?

A Dedicated Renderer Process

When an iframe is opened within a site of a different origin, a new Renderer process must be created. This also creates a new Main Thread (and other threads) for that hosted extension to use for its isolated execution context.

This has interesting performance side-effects!

  1. The hosted extension does not share resources with the hosting process. This means it has its own threads to execute scripts, etc. and generally its execution should not impede the performance of the host application
  2. The hosted extension does not share memory with the hosting process (security feature). This also means that memory allocation within the hosted extension won't affect the host application. (Running out of memory in the hosted extension will not degrade the host)
  3. Processes must communicate with each other through postMessage -- they cannot directly access each other's DOM

A process view of a hosted extension hosting an extension application in an iframe, using a postMessage channel to communication

Note: You may see this case referred to as an OOPIF in Chromium source code. This stands for Out-of-Process Iframe.

Iframes + Tabs of Different Origin

Let's expand our example and observe some other unique considerations. Users often have multiple tabs open at once, even at times to the same application.

Consider the case where the user opens two tabs to Microsoft Teams, and in each tab, the user opens the Monday.com extension iframe. Chromium browsers will actually re-use the existing Monday.com Renderer process to host the two Monday.com iframes, while keeping the Microsoft Teams applications in separate processes!

A process view of two tabs of a host application hosting an extension application in an iframe, using a postMessage channels to communication

In general, this means that the Monday.com extensions are now competing for resources on the same threads and memory! For example:

  1. A Long Task in one Iframe will affect the performance of the other
  2. JavaScript execution will interleave on the same Main Thread, despite different execution contexts and DOM instances
  3. Running out of memory in the one iframe will crash all iframes of the Monday.com extension hosted iframes

If your application is using a similar cross-origin iframe based approach, be aware that your hosted extension across the entire set of browser tabs will be competing for shared resources; you may want to throttle execution or release memory of inactive iframes.

It's important to note that although the Monday.com process is being re-used across each iframe, the browser is able to create separate execution contexts for each instance of the <iframe> within the same process. Execution contexts within a process will share resources in the process (thread time and memory).

A Hosted extension on the same origin

Let's consider a different hosted iframe architecture. In this architecture, hosted extensions are hosted on the same origin as the host. For example, these all share the same origin:

  • dashboard.stripe.com
  • www.stripe.com
  • dashboard.stripe.com/extension?extensionId=abc123

In fact, this is the model used by Stripe Apps! How does the browser manage processes in this case?

Sharing Origins between Iframe and Tab

If both the host and the iframe within a host share the same origin, the browser will group their executions within the same process (even if the hosted iframe is sandboxed!).

This means that a host and a hosted extension within the same tab will:

  1. Compete for execution time on the same thread (i.e. a Long Task in one will degrade the other, as they interleave on the same thread)
  2. Share memory (i.e. running out of memory in the hosted extension will crash the host tab)

A diagram of Stripe Dashboard running an extension of the same origin

Although the browser will maintain separate execution contexts for the iframe and the host, the extension can directly degrade the performance of the host and vice-versa!

Same origin considering multiple tabs

As mentioned previously, browsers will generate a new process for each browser tab, to host the site execution for that origin. In cases where there are multiple tabs, each hosting a same origin iframe, the iframes will not be shared (unlike same-origin cross origin iframes!).

A diagram of Stripe Dashboard running an extension of the same origin within multiple tabs

This means that iframes executing within a host of the same origin compete with the host for thread time and memory resources, but not other iframes across the browser. Hosts do not share threads with each other because they are granted dedicated processes at the tab level.

Origin Agent Clusters

A new browser API is available, called, Origin-Agent Clusters to signal to the browser that certain applications would perform better with dedicated resourcing rather than grouped.

Exploring for yourself

Chromium exposes a tool for inspecting this process grouping! See this section for more details.

A note about other browsers and exceptions

Browsers all differ in implementation, and other browsers will group processes across tabs and iframes differently! For example, Safari (as of writing) places iframes of separate origin in the same process as their host but doesn't share across tab!

Chromium also has exceptions to the general behavior explained above, such as in memory constrained environments (like low-end Android devices).

Conclusion

We explored how Chromium groups iframes and tabs into processes based on origin, and how this may affect the performance of a web architecture; with iframes being used more frequently to facilitate micro-frontend and third-party extension host architectures on the web, this is particularly important.

Understanding these process fundamentals and trade-offs can help web developers decide on an architecture that best fits their requirements and can help understand bugs and performance degradations in complex frontend systems.

That's all for this tip! Thanks for reading! Discover more similar tips matching Browser Internals and CPU.