Skip to content

[Site Isolation] Web Inspector: Introduce a Timeline agent for frame targets - #78734

Open
the-chenergy wants to merge 2 commits into
WebKit:mainfrom
the-chenergy:eng/Site-Isolation-Web-Inspector-Introduce-a-Timeline-agent-for-frame-targets
Open

the-chenergy wants to merge 2 commits into
WebKit:mainfrom
the-chenergy:eng/Site-Isolation-Web-Inspector-Introduce-a-Timeline-agent-for-frame-targets

Conversation

@the-chenergy

@the-chenergy the-chenergy commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

7b95374

[Site Isolation] Web Inspector: Introduce a Timeline agent for frame targets
rdar://191252635
https://bugs.webkit.org/show_bug.cgi?id=329362

Reviewed by NOBODY (OOPS!).

Introduce FrameTimelineAgent to report each frame's Timeline records
on its own frame target under Site Isolation. Before this, Timeline
records from cross-origin iframes were not reported at all.

Under Site Isolation, make a frame's Timeline instrumentation for
timers, events, script, animation frames and console never fall back
to the page's agent, so each of these records reaches the frame's own
agent or nothing. The rule is set before any script runs in the frame,
so a "will" hook and its "did" hook always reach the same agent. The
page's agent stays registered for page-level records (rendering
frames, composite and screenshots), auto-capture, and layout, paint
and style records until those move to frame targets.

A frame's agent starts only the Timeline instrument for now, because
the other instruments would start the page's agents. Under Site
Isolation, this removes the ScriptProfiler and Heap start events from
inspector/timeline/setInstruments-programmatic-capture.html.

In the frontend, the Script timeline adds a target on its first record,
not only on its first sample. Under Site Isolation, the Script view
shows a frame target by default, because the page target reports only
page-level data there, such as garbage collections and microtasks.

Tests: http/tests/site-isolation/inspector/timeline/frame-added-and-removed-during-recording.html
       http/tests/site-isolation/inspector/timeline/frame-target-records.html
       http/tests/site-isolation/inspector/timeline/provisional-frame-target-removed-during-recording.html
       http/tests/site-isolation/inspector/timeline/same-process-frame-added-during-recording.html

* Source/JavaScriptCore/inspector/protocol/Timeline.json:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/inspector/agents/frame/FrameTimelineAgent.cpp: Added.
(WebCore::FrameTimelineAgent::FrameTimelineAgent):
(WebCore::FrameTimelineAgent::setAutoCaptureEnabled):
(WebCore::FrameTimelineAgent::shouldToggleInstrument const):
(WebCore::FrameTimelineAgent::nodeIdForNode):
* Source/WebCore/inspector/agents/frame/FrameTimelineAgent.h: Added.
Add the Timeline agent for frame targets. It toggles only the Timeline
instrument, because the other instruments belong to domains that frame
targets do not have yet, so their getters would reach the page's
agents. It sends no node in Largest Contentful Paint records yet,
because the frontend resolves node IDs only through the page target.

* Source/WebCore/inspector/agents/InspectorTimelineAgent.cpp:
(WebCore::InspectorTimelineAgent::didEnqueueLargestContentfulPaint):
(WebCore::InspectorTimelineAgent::nodeIdForNode):
(WebCore::InspectorTimelineAgent::toggleScriptProfilerInstrument):
(WebCore::InspectorTimelineAgent::toggleHeapInstrument):
(WebCore::InspectorTimelineAgent::toggleCPUInstrument):
(WebCore::InspectorTimelineAgent::toggleMemoryInstrument):
(WebCore::InspectorTimelineAgent::toggleAnimationInstrument):
* Source/WebCore/inspector/agents/InspectorTimelineAgent.h:
(WebCore::InspectorTimelineAgent::shouldToggleInstrument const):
Add two virtual functions for FrameTimelineAgent to override:
shouldToggleInstrument(), checked before toggling each instrument
other than Timeline, and nodeIdForNode(), whose default keeps the
existing Largest Contentful Paint behavior.

* Source/WebCore/inspector/InstrumentingAgents.cpp:
(WebCore::InstrumentingAgents::siteIsolationFirstEnabled):
* Source/WebCore/inspector/InstrumentingAgents.h:
Under Site Isolation, a frame's enabled and tracking Timeline slots no
longer fall back to the page's. A Timeline agent fills its tracking
slot only while it is recording, and the page's agent records in
almost every recording for its page-level records, so with the
fallback a frame's records would go to the page's agent whenever the
frame's own agent is not recording, such as before the frame target
starts or after it stops.

* Source/WebCore/inspector/FrameInspectorController.cpp:
(WebCore::FrameInspectorController::siteIsolationFirstEnabled):
Turn on the rule above, before any script runs in the frame.
(WebCore::FrameInspectorController::createLazyAgents):
Create the FrameTimelineAgent after the frame's debugger, which it
observes while recording.

* Source/WebInspectorUI/UserInterface/Models/ScriptTimeline.js:
(WI.ScriptTimeline.prototype.addRecord):
(WI.ScriptTimeline.prototype.updateCallingContextTrees):
(WI.ScriptTimeline.prototype._createCallingContextTrees):
(WI.ScriptTimeline.prototype._addTarget):
* Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js:
(WI.ScriptClusterTimelineView):
(WI.ScriptClusterTimelineView.prototype._sortedTargetPathComponents):
(WI.ScriptClusterTimelineView.prototype._sortTargetPathComponents):
(WI.ScriptClusterTimelineView.prototype._defaultTarget):
(WI.ScriptClusterTimelineView.prototype._handleTargetAdded):
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-added-and-removed-during-recording-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-added-and-removed-during-recording.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-target-records-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-target-records.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-target-timestamps.html:
* LayoutTests/http/tests/site-isolation/inspector/timeline/provisional-frame-target-removed-during-recording-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/provisional-frame-target-removed-during-recording.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/resources/frame-timeline-test-utilities.js: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/resources/timeline-events.js: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/resources/timeline-frame.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/same-process-frame-added-during-recording-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/same-process-frame-added-during-recording.html: Added.
* LayoutTests/inspector/timeline/timeline-recording-multiple-targets-expected.txt:
* LayoutTests/inspector/timeline/timeline-recording-multiple-targets.html:
* LayoutTests/platform/mac-site-isolation/TestExpectations:
* LayoutTests/platform/mac-site-isolation/inspector/timeline/setInstruments-programmatic-capture-expected.txt: Added.

66576ac

See #78530

Web Inspector: Make the frontend handle Timeline recording start and stop per target
rdar://191156320
https://bugs.webkit.org/show_bug.cgi?id=329182

7b95374

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win ✅ 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-cmake-debug ✅ 🧪 wpe-wk2 ⏳ 🧪 win-tests ✅ 🛠 mac-apple
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe ✅ 🛠 vision-apple
⏳ 🧪 ios-wk2-wpt ⏳ 🧪 api-mac-cmake-debug loading 🧪 jsc-wpe
✅ 🧪 jsc-x86-64 loading 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk3-gcc
✅ 🛠 🧪 jsc-debug-arm64 ✅ 🛠 ios-safer-cpp ⏳ 🧪 mac-cmake-debug-wk2 ✅ 🛠 gtk
✅ 🛠 vision ❌ 🧪 mac-wk2-stress loading 🧪 gtk-wk2
✅ 🛠 vision-sim ⏳ 🧪 mac-intel-wk2 ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🛠 mac-safer-cpp ⏳ 🛠 playstation
✅ 🛠 tv ✅ 🧪 mac-site-isolation
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

Web Inspector: Make the frontend handle Timeline recording start and stop per target
rdar://191156320
https://bugs.webkit.org/show_bug.cgi?id=329182
…targets

rdar://191252635
https://bugs.webkit.org/show_bug.cgi?id=329362

Reviewed by NOBODY (OOPS!).

Introduce FrameTimelineAgent to report each frame's Timeline records
on its own frame target under Site Isolation. Before this, Timeline
records from cross-origin iframes were not reported at all.

Under Site Isolation, make a frame's Timeline instrumentation for
timers, events, script, animation frames and console never fall back
to the page's agent, so each of these records reaches the frame's own
agent or nothing. The rule is set before any script runs in the frame,
so a "will" hook and its "did" hook always reach the same agent. The
page's agent stays registered for page-level records (rendering
frames, composite and screenshots), auto-capture, and layout, paint
and style records until those move to frame targets.

A frame's agent starts only the Timeline instrument for now, because
the other instruments would start the page's agents. Under Site
Isolation, this removes the ScriptProfiler and Heap start events from
inspector/timeline/setInstruments-programmatic-capture.html.

In the frontend, the Script timeline adds a target on its first record,
not only on its first sample. Under Site Isolation, the Script view
shows a frame target by default, because the page target reports only
page-level data there, such as garbage collections and microtasks.

Tests: http/tests/site-isolation/inspector/timeline/frame-added-and-removed-during-recording.html
       http/tests/site-isolation/inspector/timeline/frame-target-records.html
       http/tests/site-isolation/inspector/timeline/provisional-frame-target-removed-during-recording.html
       http/tests/site-isolation/inspector/timeline/same-process-frame-added-during-recording.html

* Source/JavaScriptCore/inspector/protocol/Timeline.json:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/inspector/agents/frame/FrameTimelineAgent.cpp: Added.
(WebCore::FrameTimelineAgent::FrameTimelineAgent):
(WebCore::FrameTimelineAgent::setAutoCaptureEnabled):
(WebCore::FrameTimelineAgent::shouldToggleInstrument const):
(WebCore::FrameTimelineAgent::nodeIdForNode):
* Source/WebCore/inspector/agents/frame/FrameTimelineAgent.h: Added.
Add the Timeline agent for frame targets. It toggles only the Timeline
instrument, because the other instruments belong to domains that frame
targets do not have yet, so their getters would reach the page's
agents. It sends no node in Largest Contentful Paint records yet,
because the frontend resolves node IDs only through the page target.

* Source/WebCore/inspector/agents/InspectorTimelineAgent.cpp:
(WebCore::InspectorTimelineAgent::didEnqueueLargestContentfulPaint):
(WebCore::InspectorTimelineAgent::nodeIdForNode):
(WebCore::InspectorTimelineAgent::toggleScriptProfilerInstrument):
(WebCore::InspectorTimelineAgent::toggleHeapInstrument):
(WebCore::InspectorTimelineAgent::toggleCPUInstrument):
(WebCore::InspectorTimelineAgent::toggleMemoryInstrument):
(WebCore::InspectorTimelineAgent::toggleAnimationInstrument):
* Source/WebCore/inspector/agents/InspectorTimelineAgent.h:
(WebCore::InspectorTimelineAgent::shouldToggleInstrument const):
Add two virtual functions for FrameTimelineAgent to override:
shouldToggleInstrument(), checked before toggling each instrument
other than Timeline, and nodeIdForNode(), whose default keeps the
existing Largest Contentful Paint behavior.

* Source/WebCore/inspector/InstrumentingAgents.cpp:
(WebCore::InstrumentingAgents::siteIsolationFirstEnabled):
* Source/WebCore/inspector/InstrumentingAgents.h:
Under Site Isolation, a frame's enabled and tracking Timeline slots no
longer fall back to the page's. A Timeline agent fills its tracking
slot only while it is recording, and the page's agent records in
almost every recording for its page-level records, so with the
fallback a frame's records would go to the page's agent whenever the
frame's own agent is not recording, such as before the frame target
starts or after it stops.

* Source/WebCore/inspector/FrameInspectorController.cpp:
(WebCore::FrameInspectorController::siteIsolationFirstEnabled):
Turn on the rule above, before any script runs in the frame.
(WebCore::FrameInspectorController::createLazyAgents):
Create the FrameTimelineAgent after the frame's debugger, which it
observes while recording.

* Source/WebInspectorUI/UserInterface/Models/ScriptTimeline.js:
(WI.ScriptTimeline.prototype.addRecord):
(WI.ScriptTimeline.prototype.updateCallingContextTrees):
(WI.ScriptTimeline.prototype._createCallingContextTrees):
(WI.ScriptTimeline.prototype._addTarget):
* Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js:
(WI.ScriptClusterTimelineView):
(WI.ScriptClusterTimelineView.prototype._sortedTargetPathComponents):
(WI.ScriptClusterTimelineView.prototype._sortTargetPathComponents):
(WI.ScriptClusterTimelineView.prototype._defaultTarget):
(WI.ScriptClusterTimelineView.prototype._handleTargetAdded):
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-added-and-removed-during-recording-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-added-and-removed-during-recording.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-target-records-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-target-records.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/frame-target-timestamps.html:
* LayoutTests/http/tests/site-isolation/inspector/timeline/provisional-frame-target-removed-during-recording-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/provisional-frame-target-removed-during-recording.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/resources/frame-timeline-test-utilities.js: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/resources/timeline-events.js: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/resources/timeline-frame.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/same-process-frame-added-during-recording-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/timeline/same-process-frame-added-during-recording.html: Added.
* LayoutTests/inspector/timeline/timeline-recording-multiple-targets-expected.txt:
* LayoutTests/inspector/timeline/timeline-recording-multiple-targets.html:
* LayoutTests/platform/mac-site-isolation/TestExpectations:
* LayoutTests/platform/mac-site-isolation/inspector/timeline/setInstruments-programmatic-capture-expected.txt: Added.
@the-chenergy the-chenergy self-assigned this Oct 29, 2026
@the-chenergy the-chenergy added the Web Inspector Bugs related to the WebKit Web Inspector. label Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Web Inspector Bugs related to the WebKit Web Inspector.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants