|
| 1 | +# Site Isolation Plans |
| 2 | + |
| 3 | +_Last updated Dec 9, 2025._ |
| 4 | + |
| 5 | +This document aims to explain the implications of Site Isolation on the architecture |
| 6 | +of Web Inspector. |
| 7 | + |
| 8 | +## Terminology |
| 9 | + |
| 10 | +`InspectorBackend`: represents a place that command requests can be dispatched or where instrumentation events are emitted. |
| 11 | + |
| 12 | +## Background: Evolution of WebKit Process Model |
| 13 | + |
| 14 | +20 years ago, Web Inspector was introduced in a world where all of WebKit ran in a single process, including |
| 15 | +the `WebInspectorUI` user interface. In the single process model, Web Inspector's frontend sends text JSON-RPC commands |
| 16 | +over a channel to a single `InspectorBackend` associated with a `WebCore::Page`, which then parses and dispatches commands to various |
| 17 | +group command handlers called _agents_ using `InspectorBackendDispatcher`. |
| 18 | + |
| 19 | +WebKit2 introduced the multi-process model where multiple Web Content Processes are coordinated by a central UIProcess. |
| 20 | +Initially this had no effect on the design of targets in Web Inspector, because frontend messages are parsed and dispatched in |
| 21 | +one WebProcess at the WebCore level, with WebInspectorUI connected to WebProcesses directly without UIProcess involvement. |
| 22 | + |
| 23 | +A series of half-measures towards Site Isolation started to complicate this picture of one-frontend and one-backend. |
| 24 | +Process Swap On Navigation (PSON) was one such effort with a simple premise: when a Page navigates to a new origin, |
| 25 | +we should perform the load in a new WebProcess so that a potentially compromised WebProcess won't be reused across the |
| 26 | +different-origin security boundary. For Web Inspector, this meant that the there is still one-frontend and one-backend, but |
| 27 | +the backend instance may change as the inspected page navigates. Without further changes, the debugger (WebInspectorUI) would automatically |
| 28 | +close its connection to InspectorBackend upon such navigations if a new WebProcess is used. |
| 29 | + |
| 30 | +## Background: Inspector Target system |
| 31 | + |
| 32 | +To enable WebInspectorUI debugging session to persist across web process swaps, the concept of Targets was introduced with |
| 33 | +three design goals: |
| 34 | + |
| 35 | +1. provide an opaque handle that WebKit can use to route incoming JSON-RPC messages to the correct InspectorBackend (WebPage, Worker, and now Frame). |
| 36 | +1. allow reuse of command interfaces across multiple types of execution contexts (e.g., `PageRuntimeAgent`, |
| 37 | +`WorkerRuntimeAgent`, `JSGlobalObjectRuntimeAgent` all implement the `RuntimeBackendDispatcherHandler` interface created from `Runtime.json`.) |
| 38 | +1. allow the frontend to reason about the capabilities of each InspectorBackend (e.g., send commands to all "capable" targets) |
| 39 | + |
| 40 | +A `Target` represents an execution context, within the overall `WebPage` debuggable, to which JSON-RPC commands can be sent. During a single debugging session, |
| 41 | +WebInspectorUI will inspect multiple Page instances which may be hosted in different Web Processes. Each Page/WebPage/WebPageProxy for the same |
| 42 | +`WebPageDebuggable` appears as a `PageTarget`. Therefore, WebInspectorUI is able to switch between `PageTarget` instances when a main frame load is committed, while still handling events from both targets as the old page unloads and the new page loads. |
| 43 | + |
| 44 | +Targets also solve the problem of getting a message dispatched to the correct `BackendDispatcher` and corresponding agents. With the introduction of Page targets, the connection to the debugger was moved to UIProcess, but most commands are parsed and handled by agents in WebProcess |
| 45 | +after initial JSON parsing in UIProcess. The target routing system is implemented in the backend as the `Target` domain in `InspectorTargetAgent` |
| 46 | +and instantiated as part of `WebPageInspectorController`. Targets as exposed by TargetAgent have a simplified lifecycle compared to WebPages and Workers, |
| 47 | +but still contain essential concepts such as pausing/resuming, provisional/committed state, and target creation/destruction events. |
| 48 | + |
| 49 | +- Page target: represents a legacy "direct" backend target which does not support multiple Targets. This is for backwards compatibility with old (pre-PSON and WebKitLegacy) backends. |
| 50 | +- WebPage target: represents a WebPageProxy or WKWebView. Associated with multiple transient worker and frame targets. For backwards compatibility with post-PSON backends which lack Frame targets, WebInspectorUI can also use PageTarget as the main Frame target when iterating execution contexts. |
| 51 | +- Worker target: represents a dedicated Web Worker target. Associated with the parent Page target that spawned the worker. |
| 52 | + |
| 53 | +ServiceWorker, ITML, and JavaScript (i.e., `JSContext`) targets are standalone debuggables and not exposed as sub-targets of WebPage target within debuggable. |
| 54 | +The fact that they have target types is for convenience in restricting which domains are supposed to be exposed. |
| 55 | + |
| 56 | +FIXME: describe proxying to workers, before and after |
| 57 | + |
| 58 | + |
| 59 | +## What are the key issues motivating design changes? |
| 60 | + |
| 61 | +Under Site Isolation, |
| 62 | + |
| 63 | +- Web Inspector backend can no longer assume that all frames are in the same process, or that a Page is in the same process as its Frame. |
| 64 | +- One backend in one Web Process only has partial resource data. |
| 65 | +- WebInspectorUI needs to connect to multiple web processes to receive events and fetch resource data. |
| 66 | + |
| 67 | +Concurrently to Site Isolation, WebKit is also gaining support for WebDriver BiDi. The implementation for WebDriver BiDi is |
| 68 | +automation-focused, but ultimately it is just another JSON-RPC debug protocol that we have to support in WebKit. One of the main |
| 69 | +differences is that WebDriver is UIProcess-based, and it includes the ability to target commands to specific `browsing contexts`. |
| 70 | +This is basically the same thing as targeting a command to a specific frame. Similarly, FrameTargetProxy in UIProcess routes its message to the |
| 71 | +correct `InspectorBackend` using `sendMessageToProcessContainingFrame()`. |
| 72 | + |
| 73 | +The rest of this document motivates a modified architectural design based on Frame targets. |
| 74 | + |
| 75 | +## What are the main changes are being proposed? |
| 76 | + |
| 77 | +- [X] Add new `Frame` target type which represents a place that commands can be targeted at. A Page target has one or more Frame targets. |
| 78 | +- [X] Introduce `FrameInspectorController` which owns per-frame agents in WebProcess. |
| 79 | +- [X] Deprecate the 'Page' debuggable type (i.e. remove direct backend support). |
| 80 | +- [X] Transition WebKitLegacy to use in-process proxying backend. |
| 81 | +- [/] Move per-page agents to UIProcess; use 'octopus' design for instrumentation forwarding from WebProcess `InspectorInstrumentation`. |
| 82 | +- [/] Keep per-execution-context agents in WebProcess; dispatch happens from `FrameInspectorController`. |
| 83 | +- [ ] Update resource/frame identifier scheme to work with Site Isolation (currently uses a process-local static uint64...) |
| 84 | +- [ ] Fix uses of `WI.assumingMainTarget()` in WebInspetorUI |
| 85 | + |
| 86 | +FIXME: add diagrams for DirectTargetBackend, ProxyingTargetBackend with Pages, and ProxyingTargetBackend with Frames. |
| 87 | +FIXME: need illustration of octopus hybrid page/network agent and more details |
| 88 | + |
| 89 | +--- |
| 90 | + |
| 91 | +BJB> Everything below this has not yet been rewritten. |
| 92 | + |
| 93 | +## Why do we need Frame target? |
| 94 | + |
| 95 | +- Each frame has its own execution context (Document), but it may or may not co-locate in the same process as other frames. |
| 96 | +- Helps the backend to route agent commands to the appropriate Webcontent process. |
| 97 | +- Frame targets in the frontend abstracts away which actual process is hosting the frame. |
| 98 | +- Reuse existing target routing mechanism for Frame-targeted commands. |
| 99 | +- Backend needs to know for each frame which process that data resides in. |
| 100 | + |
| 101 | +## Can't we use more than one Page target for OOPIF? |
| 102 | + |
| 103 | +- This violates the expectation that WebInspectorUI should not be overly familiar with |
| 104 | + the process model of WebKit and specifically the policy choices for Site Isolation. |
| 105 | +- Frontend code designed to iterate execution contexts (frames), not processes. |
| 106 | +- Reasoning about multiple Page targets, which may or may not be a WKWebView, is error-prone. |
| 107 | + |
| 108 | +## What's the difference between multiple Frame targets vs multiple Page targets? |
| 109 | + |
| 110 | +- WebKitLegacy Frame Target adapter (already done) |
| 111 | +- Moving Network and Page agent to UIProcess (this might be required anyway to provide global page identifiers) |
| 112 | +- Add IPC support for Page and Network events and commands |
| 113 | + |
| 114 | +## What about WebKitLegacy? |
| 115 | + |
| 116 | +- Unable to stop supporting it any time soon, still has 1st party clients that we can't break. |
| 117 | +- Easier to add frame target adapter for single-process mode, |
| 118 | + than to continue supporting direct backend target implementations |
| 119 | + (i.e., have IPC (new) and no-IPC (existing) versions of Page and NetworkAgent) |
| 120 | +- Qianlang added this adapter as part of the Console work, it uses different frame lifecycle instrumentation. |
| 121 | + |
| 122 | +## What about backwards compatibility with shipping Page targets? |
| 123 | + |
| 124 | +- Frontend needs to continue to support shipping Page, Worker, and ServiceWorker targets w/o any frame targets. |
| 125 | +- For Page targets without Frame targets, the frontend assumes it's older and send commands to the Page target. |
| 126 | +- Target iteration assumes Page w/ 1+ Frame target -> send frame messages to frames, otherwise send to Page target. |
| 127 | + |
| 128 | +Example: |
| 129 | + |
| 130 | +For Page.getResourceTree, in shipping Web Inspector, all frame tree nodes are included in one payload. |
| 131 | + |
| 132 | +With Site Isolation, not all resources will be in the same process, so each payload will contain a |
| 133 | +subset of frame tree nodes and their resources. Whether or not we use Frame or Page targets, we still need |
| 134 | +to rework the frontend to merge results from multiple targets. Since Frames are the unit of process isolation, |
| 135 | +it's easier to think about the correct behavior of Inspector backend commands in terms of frames. |
| 136 | + |
| 137 | +The alternative would be to send commands to every sub-page of a page, but this is difficult to reason about because |
| 138 | +the policy for which frames should go into which processes is variable across platforms and releases. |
| 139 | + |
| 140 | + |
| 141 | +What is the plan for each domain? |
| 142 | + |
| 143 | +- Domains to transition to per-frame agents: |
| 144 | + Debugger, Runtime, CSS, DOM, Audit, Animation, DOM, DOMStorage, DOMDebugger, Canvas |
| 145 | +- Domains to be moved to UIProcess: |
| 146 | + Network, Page |
| 147 | +- Domains to stay as-is: |
| 148 | + Target, Browser, Worker, ServiceWorker |
| 149 | +- Domains TBD: |
| 150 | + LayerTree, Heap, Memory, Storage, IndexedDB |
| 151 | +- Domains removed: |
| 152 | + Database, AppCache |
| 153 | + |
| 154 | + |
| 155 | +## Other Deprecations |
| 156 | + |
| 157 | +- AugmentableInspectorController |
| 158 | +- ITML debuggable type |
0 commit comments