Let's get this out of the way. An
iframe is an inline frame that allows embedded HTML documents. This somewhat recursive definition covered 90% of pages I visited while learning about iframes. But the question remained - what is an
This blog touches on the interesting things I discovered in search of a satisfying answer; the parallels between this 90s HTML tag and today's in Vogue technology, Chrome's amazing way of making iframes secure and whether iframes will be around for another thirty years.
Before iframes, there were frames. A
frame is a little window to a webpage. A
frameset element fits these little webpages into a bigger a webpage. For example, a
frameset could have a header, footer, navigation and content frame. Because each frame is a window, it has its own location and can change location independent of other frames. This allows parts of a website to change content and only download the resources for the new part. Thirty years later we call this code splitting and it's very cutting edge.
A document with a frameset is different to other HTML documents. These "frameset documents" can only have frameset or frame elements, no body or other HTML elements. This creates a problem where you're all-in on framesets and frames or not using them at all.
This sets the stage for the hero of our story. Enter the Inline Frame.
iframe is a frame that can be placed alongside other elements in "normal" HTML documents. It ushered in a new era of embedded content on the web. An
So now we know what's on the tin, what's in the tin? Google Chrome produces over 60% of the world's iframes. Are these iframes humanely raised? What's the square-foot to
iframe ratio? I took a trip to Chrome to find out.
As we touched on earlier, an
iframe is a little window that shows a web page. This is a decent way of reasoning about the implementation and performance characteristics. If there's a page with two iframes on it, that's like having three pages open.
To get a bit more detailed, we'll have to talk about how Chrome works. Chrome is a multi-process application. There's a "browser" process responsible for things like rendering the browser's UI and handling network requests. There are "render" processes responsible for everything related to a web page. The render process handles things like the DOM, CSSOM, V8 VM(s), painting pixels, making triangles from pixels and sending lots of triangles to the GPU. GPUs love triangles.
Modern versions of Chrome are built on the site-isolation policy. This means each site has its own render process. If you have ever wondered why your activity monitor looks like a Chrome ad, this is the reason. Having a render process per site is overwhelmingly a good thing. It brings the same sandboxing and safety guarantees that your OS makes about programs to websites. Feel good knowing there's nothing technically wrong with online banking and shopping on a dodgy e-commerce site at the same time.
iframes are no exception to the site-isolation policy. A render process gets created for each
iframe element. This isolates iframes from each other and the parent page. Again, this is a good thing for you and I. Chrome on the other hand has gone from 1:1 page-to-render process to 1:N page-to-render processes. This is an explosion in complexity.
A page with an
iframe always pays a memory overhead. There's overhead for a new process and essentials that are in every render process. Objects like Frame, Window and Document get created regardless of what's in the
iframe. On my computer, a render process for a "hello world" web page used roughly 17MB of memory. Each
A page with an
iframe greatly increases the complexity of rendering that page. There's no single render process in control of rendering the entire screen. Chrome solves this by getting each render process to paint its local view of the world. Each render process passes that information to the browser process which composes the final result shown to the user.
A page with an
iframe suddenly makes handling user input much harder. When the user clicks somewhere on the page, the browser process works out what render process "owns" the part of the screen that was clicked on. Only once that is determined, the correct render process can start to handle the event.
On top of all this, iframes still want to talk to other frames! All of this incredible work to isolate frames from one another, then there's this requirement:
Think about the layers of computer required to implement this. This innocuous 'lol' goes from a thread running V8, sent over IPC, through the OS, back up to
window.parent's render process, to finally end up in that process' V8 thread. And there's no guarantee that the JS context is listening to the "message" event listener.
Sadly, iframes are struggling to keep up with the demands of today's web. The rise of the web app has created a host of new requirements for iframes. For example, any web app that wants to allow 3rd party UI extensions - iframes are the de facto technology. This pushes past embedded content on a web page to embedded extensions in a web app. For this use-case, iframes are looking long in the tooth.
Take the description "single page application". This seems incompatible with an element that is literally another page. Terminology aside, the more integrated an extension the host web app, the more wrestling with the reality that an
iframe is a different frame. Selection, focus, layout, dialogs - all these things require coordination between the
iframe and the main frame.
"Isolated yet integrated" best sums up the mixed bag of UI extension requirements. WASM is a technology that supports this idea for code running in the browser. It's a sandbox with a controllable level of integration with the main JS context. Integration can look like calling WASM functions from JS, sharing memory between WASM and JS or a combination of both. An equivalent level of control isn't afforded to UI extensions.
Regardless of what happens in this area, iframes are not going away anytime soon. Sentenced to support the requirements of the web thirty years ago. Bent and twisted to support the requirements of today's web. The
iframe is the jack of all trades. It's the whole expression that best tells the story of the
iframe. Jack of all trades, master of none - often better than master of one.
Thanks for reading!
If you liked this, you might enjoy reading about my "Haskell phase".
Here are some links to the resources I used to put this blog together.