This page provides high level information on our plans to support out-of-process iframes in Chromium, as part of the Site Isolation project.
Many parts of Chromium's architecture will need to change to support rendering and interacting with a frame in a different process from its parent page. Our intended changes include keeping track of frames in multiple processes, routing certain script calls between processes, supporting cross-process navigations in frames, rendering and compositing frames in multiple processes, and sending input events to the correct processes.
Process Models page). BrowsingInstances typically contain only a single tab, but they can include multiple tabs when a page uses window.open or targeted links. Note that BrowsingInstances are not related to the number of tabs in a window, since tabs created manually are in their own BrowsingInstance.
To support cross-process interactions like postMessage, Chromium must keep a "swapped out" version of the page's DOMWindow in each of the other processes of its BrowsingInstance, as a placeholder. As shown in the diagram at right, this allows a page from site A to find a swapped out DOMWindow in its own process for a tab that is currently active on site B. The swapped out DOMWindow can then forward the postMessage call to the browser and then to the correct page in the process for site B.
With out-of-process iframes, Chromium needs to keep track of swapped out DOMWindows for subframes as well as tabs.
In the browser process, Chromium must keep track of the full frame tree for each tab. WebContents will host a tree of FrameTreeNode objects, mirroring the frame tree of the current page. Each FrameTreeNode will contain frame-specific information (e.g., the frame's name). It will be responsible for cross-process navigations in the frame, and it will support routing messages from other processes to the active frame.
We plan to pull the frame-specific logic out of the content module's RenderView and RenderViewHost classes, into new RenderFrame and RenderFrameHost classes. These new classes will allocate their own routing ids, so IPC messages can be targeted to specific frames. We will have a full RenderFrame for every active frame, regardless of process, and we will have a corresponding, slimmed down, "swapped out" RenderFrame as a placeholder in the other processes of the BrowsingInstance. These "swapped out" placeholders are shown with dashed lines in the diagram below, which shows one BrowsingInstance with two tabs, containing two subframes each.
Note: This section is semi-obsolete. See the FrameHandle design doc for more information about some of the Blink changes.
Within Blink, we want to distinguish between active Frames that have a full page and the swapped out Frames that are only placeholders. Conceptually, an active Frame has a normal DOMWindow and a Document, while a swapped out Frame has a RemoteDOMWindow and no Document. We plan to refactor Frame so that the Document is only accessible via the DOMWindow (removing the direct reference from Frame to Document), which could affect large portions of the code.
Using this approach will allow us to eliminate the current swapped out logic for navigating to a "swappedout://" URL and filtering IPC messages, because a RemoteDOMWindow will have no Document.
One major implication of this change is that code in Blink cannot assume that it is possible to walk the entire DOM tree in a single process. This will likely require changes to components such as Editor and focus tracking, among others.
Note: We are investigating ways to reduce the memory requirements of these swapped out RenderFrames and DOMWindows, because there will be many more than in Chromium today. Today, the space required is O(tabs * processes) within a BrowsingInstance, and most BrowsingInstances only contain 1 or 2 tabs. This new model would require O(frames * processes) space. This could be much higher, because the number of frames can be much larger than the number of tabs, and because the number of processes will increase based on cross-site frames. Fortunately, there are many opportunities to reduce the overhead of these placeholder objects, relative to their active equivalents.
A tab's session history also becomes more complicated when subframes may be rendered by different processes. Currently, Blink takes care of tracking the frame tree in each HistoryItem in the renderer process, and the browser process just tracks each back/forward entry using NavigationEntry. We will remove the frame tracking logic from Blink's HistoryController and keep track of each frame's navigations in the browser process directly.
We will also change the representation of a tab's session history to more closely match the HTML5 spec. Rather than cloning the frame tree for each HistoryItem, we will keep track of each frame's session history separately in the browser process, and we will use a separate "joint session history" list for back and forward navigations. Each entry in this list will have a tree of pointers to each frame's corresponding session history item. We expect this to require changes to the session restore logic as well.
All details of navigation refactoring are described in a design document.
To render an iframe in a different process than its parent page, the browser process will pass information back and forth between the renderer processes and help the GPU process composite the images together in the correct sizes and locations. Some of this logic may be adapted or partly reused from BrowserPlugin, which is currently being used by Chrome Packaged Apps.
The design for rendering is encapsulated in a separate document.
We are continuing to investigate the changes required to support hit testing and delivering input events to the correct iframe process. As with rendering, we are considering how to reuse modified versions of BrowserPlugin's input event handling logic.
The mailing list for technical discussions on Site Isolations and Out-of-Process irfames is firstname.lastname@example.org.