Skip to content

Commit 4842b9a

Browse files
committed
Web Inspector Site Isolation Explainer
Second editing session adds more details about Target system.
1 parent 54d9c78 commit 4842b9a

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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

Comments
 (0)