chrome-devtools-frontend 1.0.1515796 → 1.0.1515988
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/contributing/infrastructure.md +131 -82
- package/front_end/Tests.js +3 -29
- package/front_end/core/common/Progress.ts +73 -55
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/protocol_client/InspectorBackend.ts +2 -0
- package/front_end/core/root/Runtime.ts +0 -1
- package/front_end/core/sdk/CSSMatchedStyles.ts +12 -10
- package/front_end/core/sdk/CSSModel.ts +1 -31
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +27 -7
- package/front_end/core/sdk/DebuggerModel.ts +1 -31
- package/front_end/core/sdk/EnhancedTracesParser.ts +81 -50
- package/front_end/core/sdk/NetworkManager.ts +1 -31
- package/front_end/core/sdk/NetworkRequest.ts +1 -31
- package/front_end/core/sdk/RehydratingConnection.snapshot.txt +1003 -0
- package/front_end/core/sdk/RehydratingConnection.ts +13 -18
- package/front_end/core/sdk/RehydratingObject.ts +8 -31
- package/front_end/core/sdk/RemoteObject.ts +1 -31
- package/front_end/core/sdk/ResourceTreeModel.ts +1 -31
- package/front_end/core/sdk/RuntimeModel.ts +1 -31
- package/front_end/core/sdk/ServiceWorkerManager.ts +1 -31
- package/front_end/core/sdk/SourceMap.ts +1 -31
- package/front_end/core/sdk/TraceObject.ts +8 -3
- package/front_end/entrypoints/main/MainImpl.ts +0 -2
- package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -3
- package/front_end/models/ai_assistance/ConversationHandler.ts +4 -6
- package/front_end/models/ai_assistance/agents/AiAgent.ts +4 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +107 -72
- package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +2 -2
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +2 -2
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +178 -85
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +308 -218
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +100 -100
- package/front_end/models/ai_assistance/data_formatters/UnitFormatters.ts +10 -1
- package/front_end/models/ai_assistance/performance/AIContext.ts +19 -21
- package/front_end/models/bindings/ContentProviderBasedProject.ts +6 -4
- package/front_end/models/breakpoints/BreakpointManager.ts +3 -3
- package/front_end/models/har/Writer.ts +11 -11
- package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +3 -3
- package/front_end/models/persistence/IsolatedFileSystem.ts +4 -4
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +7 -7
- package/front_end/models/persistence/PersistenceImpl.ts +8 -8
- package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
- package/front_end/models/trace/ModelImpl.ts +2 -16
- package/front_end/models/trace/Processor.ts +15 -9
- package/front_end/models/trace/handlers/AuctionWorkletsHandler.ts +4 -4
- package/front_end/models/trace/handlers/FramesHandler.ts +2 -2
- package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +7 -10
- package/front_end/models/trace/handlers/MetaHandler.ts +11 -9
- package/front_end/models/trace/handlers/ScreenshotsHandler.ts +1 -1
- package/front_end/models/trace/handlers/ScriptsHandler.ts +5 -5
- package/front_end/models/trace/handlers/UserInteractionsHandler.ts +2 -14
- package/front_end/models/trace/handlers/UserTimingsHandler.ts +3 -4
- package/front_end/models/trace/insights/CLSCulprits.ts +1 -1
- package/front_end/models/trace/insights/DocumentLatency.ts +3 -4
- package/front_end/models/trace/insights/DuplicatedJavaScript.ts +1 -1
- package/front_end/models/trace/insights/INPBreakdown.ts +1 -1
- package/front_end/models/trace/insights/ImageDelivery.ts +1 -1
- package/front_end/models/trace/insights/LCPBreakdown.ts +1 -1
- package/front_end/models/trace/insights/LCPDiscovery.ts +1 -1
- package/front_end/models/trace/insights/ModernHTTP.ts +1 -1
- package/front_end/models/trace/insights/NetworkDependencyTree.ts +1 -1
- package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
- package/front_end/models/trace/insights/types.ts +2 -0
- package/front_end/models/trace/types/TraceEvents.ts +41 -64
- package/front_end/models/trace_source_maps_resolver/trace_source_maps_resolver.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +21 -99
- package/front_end/panels/application/ServiceWorkersView.ts +0 -1
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +2 -3
- package/front_end/panels/common/GdpSignUpDialog.ts +6 -3
- package/front_end/panels/console/ConsoleView.ts +23 -28
- package/front_end/panels/console/ConsoleViewport.ts +2 -2
- package/front_end/panels/console/consoleView.css +11 -1
- package/front_end/panels/coverage/CoverageView.ts +2 -2
- package/front_end/panels/elements/ElementsTreeOutline.ts +2 -2
- package/front_end/panels/elements/StyleEditorWidget.ts +8 -19
- package/front_end/panels/elements/StylePropertyTreeElement.ts +39 -25
- package/front_end/panels/elements/StylesSidebarPane.ts +2 -2
- package/front_end/panels/elements/stylePropertiesTreeOutline.css +4 -3
- package/front_end/panels/layer_viewer/Layers3DView.ts +2 -2
- package/front_end/panels/layers/LayerTreeModel.ts +3 -3
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +4 -4
- package/front_end/panels/network/NetworkLogView.ts +1 -1
- package/front_end/panels/network/NetworkLogViewColumns.ts +3 -3
- package/front_end/panels/network/NetworkSearchScope.ts +6 -6
- package/front_end/panels/search/SearchView.ts +33 -32
- package/front_end/panels/settings/components/SyncSection.ts +6 -1
- package/front_end/panels/sources/SourcesSearchScope.ts +4 -4
- package/front_end/panels/sources/TabbedEditorContainer.ts +5 -5
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +10 -5
- package/front_end/panels/timeline/TimelineFlameChartView.ts +18 -15
- package/front_end/panels/timeline/TimelinePanel.ts +41 -22
- package/front_end/panels/timeline/TracingLayerTree.ts +4 -5
- package/front_end/panels/timeline/components/ExportTraceOptions.ts +37 -22
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +17 -7
- package/front_end/third_party/axe-core/README.chromium +1 -0
- package/front_end/third_party/codemirror/README.chromium +1 -0
- package/front_end/third_party/codemirror.next/README.chromium +1 -0
- package/front_end/third_party/csp_evaluator/README.chromium +1 -0
- package/front_end/third_party/diff/README.chromium +1 -0
- package/front_end/third_party/i18n/README.chromium +1 -0
- package/front_end/third_party/intl-messageformat/README.chromium +1 -0
- package/front_end/third_party/json5/README.chromium +1 -0
- package/front_end/third_party/legacy-javascript/README.chromium +1 -0
- package/front_end/third_party/lighthouse/README.chromium +1 -0
- package/front_end/third_party/lit/README.chromium +1 -0
- package/front_end/third_party/marked/README.chromium +1 -0
- package/front_end/third_party/puppeteer-replay/README.chromium +1 -0
- package/front_end/third_party/third-party-web/README.chromium +1 -0
- package/front_end/third_party/vscode.web-custom-data/README.chromium +1 -0
- package/front_end/third_party/wasmparser/README.chromium +1 -0
- package/front_end/third_party/web-vitals/README.chromium +1 -0
- package/front_end/ui/components/tooltips/Tooltip.ts +17 -1
- package/front_end/ui/legacy/ContextMenu.ts +2 -2
- package/front_end/ui/legacy/GlassPane.ts +7 -3
- package/front_end/ui/legacy/ProgressIndicator.ts +29 -16
- package/front_end/ui/legacy/TabbedPane.ts +2 -2
- package/front_end/ui/legacy/Treeoutline.ts +10 -5
- package/front_end/ui/legacy/UIUtils.ts +42 -10
- package/front_end/ui/legacy/components/color_picker/Spectrum.ts +14 -14
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +6 -6
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +3 -29
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +14 -14
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/inspector_overlay/highlight_common.ts +1 -27
- package/inspector_overlay/highlight_grid_common.ts +1 -27
- package/inspector_overlay/tool_highlight.ts +1 -27
- package/inspector_overlay/tool_persistent.ts +1 -27
- package/inspector_overlay/tool_source_order.ts +1 -27
- package/package.json +1 -1
@@ -59,7 +59,7 @@ export class Writer {
|
|
59
59
|
const compositeProgress = new Common.Progress.CompositeProgress(progress);
|
60
60
|
|
61
61
|
const content = await Writer.harStringForRequests(requests, options, compositeProgress);
|
62
|
-
if (progress.
|
62
|
+
if (progress.canceled) {
|
63
63
|
return;
|
64
64
|
}
|
65
65
|
await Writer.writeToStream(stream, compositeProgress, content);
|
@@ -69,8 +69,8 @@ export class Writer {
|
|
69
69
|
requests: SDK.NetworkRequest.NetworkRequest[], options: BuildOptions,
|
70
70
|
compositeProgress: Common.Progress.CompositeProgress): Promise<string> {
|
71
71
|
const progress = compositeProgress.createSubProgress();
|
72
|
-
progress.
|
73
|
-
progress.
|
72
|
+
progress.title = i18nString(UIStrings.collectingContent);
|
73
|
+
progress.totalWork = requests.length;
|
74
74
|
|
75
75
|
// Sort by issueTime because this is recorded as startedDateTime in HAR logs.
|
76
76
|
requests.sort((reqA, reqB) => reqA.issueTime() - reqB.issueTime());
|
@@ -82,9 +82,9 @@ export class Writer {
|
|
82
82
|
}
|
83
83
|
|
84
84
|
await Promise.all(promises);
|
85
|
-
progress.done
|
85
|
+
progress.done = true;
|
86
86
|
|
87
|
-
if (progress.
|
87
|
+
if (progress.canceled) {
|
88
88
|
return '';
|
89
89
|
}
|
90
90
|
return JSON.stringify({log: harLog}, null, jsonIndent);
|
@@ -106,7 +106,7 @@ export class Writer {
|
|
106
106
|
}
|
107
107
|
|
108
108
|
function contentLoaded(entry: EntryDTO, contentDataOrError: TextUtils.ContentData.ContentDataOrError): void {
|
109
|
-
progress.
|
109
|
+
++progress.worked;
|
110
110
|
const contentData = TextUtils.ContentData.ContentData.asDeferredContent(contentDataOrError);
|
111
111
|
let encoded: true|boolean = contentData.isEncoded;
|
112
112
|
if (contentData.content !== null) {
|
@@ -127,14 +127,14 @@ export class Writer {
|
|
127
127
|
stream: Common.StringOutputStream.OutputStream, compositeProgress: Common.Progress.CompositeProgress,
|
128
128
|
fileContent: string): Promise<void> {
|
129
129
|
const progress = compositeProgress.createSubProgress();
|
130
|
-
progress.
|
131
|
-
progress.
|
132
|
-
for (let i = 0; i < fileContent.length && !progress.
|
130
|
+
progress.title = i18nString(UIStrings.writingFile);
|
131
|
+
progress.totalWork = fileContent.length;
|
132
|
+
for (let i = 0; i < fileContent.length && !progress.canceled; i += chunkSize) {
|
133
133
|
const chunk = fileContent.substr(i, chunkSize);
|
134
134
|
await stream.write(chunk);
|
135
|
-
progress.
|
135
|
+
progress.worked += chunk.length;
|
136
136
|
}
|
137
|
-
progress.done
|
137
|
+
progress.done = true;
|
138
138
|
}
|
139
139
|
}
|
140
140
|
|
@@ -276,14 +276,14 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
|
|
276
276
|
if (!queriesToRun.length) {
|
277
277
|
queriesToRun.push('');
|
278
278
|
}
|
279
|
-
progress.
|
279
|
+
progress.totalWork = queriesToRun.length;
|
280
280
|
|
281
281
|
for (const query of queriesToRun) {
|
282
282
|
const files = await this.#fileSystem.searchInPath(searchConfig.isRegex() ? '' : query, progress);
|
283
283
|
files.sort(Platform.StringUtilities.naturalOrderComparator);
|
284
284
|
workingFileSet = Platform.ArrayUtilities.intersectOrdered(
|
285
285
|
workingFileSet, files, Platform.StringUtilities.naturalOrderComparator);
|
286
|
-
progress.
|
286
|
+
++progress.worked;
|
287
287
|
}
|
288
288
|
|
289
289
|
const result = new Map();
|
@@ -294,7 +294,7 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
|
|
294
294
|
}
|
295
295
|
}
|
296
296
|
|
297
|
-
progress.done
|
297
|
+
progress.done = true;
|
298
298
|
return result;
|
299
299
|
}
|
300
300
|
|
@@ -184,7 +184,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
|
|
184
184
|
let activePath = '';
|
185
185
|
for (const path of paths) {
|
186
186
|
activePath = activePath + '/' + path;
|
187
|
-
dirEntry = await this
|
187
|
+
dirEntry = await this.#createFolderIfNeeded(activePath);
|
188
188
|
if (!dirEntry) {
|
189
189
|
return null;
|
190
190
|
}
|
@@ -192,7 +192,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
|
|
192
192
|
return dirEntry;
|
193
193
|
}
|
194
194
|
|
195
|
-
|
195
|
+
#createFolderIfNeeded(path: string): Promise<DirectoryEntry|null> {
|
196
196
|
return new Promise(resolve => {
|
197
197
|
this.domFileSystem.root.getDirectory(path, {create: true}, dirEntry => resolve(dirEntry), error => {
|
198
198
|
this.domFileSystem.root.getFile(
|
@@ -517,13 +517,13 @@ export class IsolatedFileSystem extends PlatformFileSystem {
|
|
517
517
|
|
518
518
|
function innerCallback(files: Platform.DevToolsPath.RawPathString[]): void {
|
519
519
|
resolve(files.map(path => Common.ParsedURL.ParsedURL.rawPathToUrlString(path)));
|
520
|
-
progress.
|
520
|
+
++progress.worked;
|
521
521
|
}
|
522
522
|
});
|
523
523
|
}
|
524
524
|
|
525
525
|
override indexContent(progress: Common.Progress.Progress): void {
|
526
|
-
progress.
|
526
|
+
progress.totalWork = 1;
|
527
527
|
const requestId = this.manager.registerProgress(progress);
|
528
528
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.indexPath(
|
529
529
|
requestId, this.#embedderPath, JSON.stringify(this.excludedEmbedderFolders));
|
@@ -123,7 +123,7 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
123
123
|
const fileSystems = event.data;
|
124
124
|
const promises = [];
|
125
125
|
for (let i = 0; i < fileSystems.length; ++i) {
|
126
|
-
promises.push(this
|
126
|
+
promises.push(this.#addFileSystem(fileSystems[i], false));
|
127
127
|
}
|
128
128
|
void Promise.all(promises).then(onFileSystemsAdded);
|
129
129
|
}
|
@@ -154,7 +154,7 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
154
154
|
return this.fileSystemsLoadedPromise;
|
155
155
|
}
|
156
156
|
|
157
|
-
|
157
|
+
#addFileSystem(fileSystem: Host.InspectorFrontendHostAPI.DevToolsFileSystem, dispatchEvent: boolean):
|
158
158
|
Promise<IsolatedFileSystem|null> {
|
159
159
|
const embedderPath = fileSystem.fileSystemPath;
|
160
160
|
const fileSystemURL = Common.ParsedURL.ParsedURL.rawPathToUrlString(fileSystem.fileSystemPath);
|
@@ -196,7 +196,7 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
196
196
|
this.fileSystemRequestResolve.call(null, null);
|
197
197
|
this.fileSystemRequestResolve = null;
|
198
198
|
} else if (fileSystem) {
|
199
|
-
void this
|
199
|
+
void this.#addFileSystem(fileSystem, true).then(fileSystem => {
|
200
200
|
if (this.fileSystemRequestResolve) {
|
201
201
|
this.fileSystemRequestResolve.call(null, fileSystem);
|
202
202
|
this.fileSystemRequestResolve = null;
|
@@ -287,7 +287,7 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
287
287
|
if (!progress) {
|
288
288
|
return;
|
289
289
|
}
|
290
|
-
progress.
|
290
|
+
progress.totalWork = totalWork;
|
291
291
|
}
|
292
292
|
|
293
293
|
private onIndexingWorked(
|
@@ -297,8 +297,8 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
297
297
|
if (!progress) {
|
298
298
|
return;
|
299
299
|
}
|
300
|
-
progress.
|
301
|
-
if (progress.
|
300
|
+
progress.worked += worked;
|
301
|
+
if (progress.canceled) {
|
302
302
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.stopIndexing(requestId);
|
303
303
|
this.onIndexingDone(event);
|
304
304
|
}
|
@@ -311,7 +311,7 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
311
311
|
if (!progress) {
|
312
312
|
return;
|
313
313
|
}
|
314
|
-
progress.done
|
314
|
+
progress.done = true;
|
315
315
|
this.progresses.delete(requestId);
|
316
316
|
}
|
317
317
|
|
@@ -64,19 +64,19 @@ export class PersistenceImpl extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
64
64
|
}
|
65
65
|
|
66
66
|
async addBinding(binding: PersistenceBinding): Promise<void> {
|
67
|
-
await this
|
67
|
+
await this.#addBinding(binding);
|
68
68
|
}
|
69
69
|
|
70
70
|
async addBindingForTest(binding: PersistenceBinding): Promise<void> {
|
71
|
-
await this
|
71
|
+
await this.#addBinding(binding);
|
72
72
|
}
|
73
73
|
|
74
74
|
async removeBinding(binding: PersistenceBinding): Promise<void> {
|
75
|
-
await this
|
75
|
+
await this.#removeBinding(binding);
|
76
76
|
}
|
77
77
|
|
78
78
|
async removeBindingForTest(binding: PersistenceBinding): Promise<void> {
|
79
|
-
await this
|
79
|
+
await this.#removeBinding(binding);
|
80
80
|
}
|
81
81
|
|
82
82
|
#setupBindings(networkUISourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
@@ -86,7 +86,7 @@ export class PersistenceImpl extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
86
86
|
return this.#mapping.computeNetworkStatus(networkUISourceCode);
|
87
87
|
}
|
88
88
|
|
89
|
-
|
89
|
+
async #addBinding(binding: PersistenceBinding): Promise<void> {
|
90
90
|
bindings.set(binding.network, binding);
|
91
91
|
bindings.set(binding.fileSystem, binding);
|
92
92
|
|
@@ -119,7 +119,7 @@ export class PersistenceImpl extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
119
119
|
this.dispatchEventToListeners(Events.BindingCreated, binding);
|
120
120
|
}
|
121
121
|
|
122
|
-
|
122
|
+
async #removeBinding(binding: PersistenceBinding): Promise<void> {
|
123
123
|
if (bindings.get(binding.network) !== binding) {
|
124
124
|
return;
|
125
125
|
}
|
@@ -150,12 +150,12 @@ export class PersistenceImpl extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
150
150
|
private onStatusAdded(status: AutomappingStatus): Promise<void> {
|
151
151
|
const binding = new PersistenceBinding(status.network, status.fileSystem);
|
152
152
|
statusBindings.set(status, binding);
|
153
|
-
return this
|
153
|
+
return this.#addBinding(binding);
|
154
154
|
}
|
155
155
|
|
156
156
|
private async onStatusRemoved(status: AutomappingStatus): Promise<void> {
|
157
157
|
const binding = statusBindings.get(status) as PersistenceBinding;
|
158
|
-
await this
|
158
|
+
await this.#removeBinding(binding);
|
159
159
|
}
|
160
160
|
|
161
161
|
private onWorkingCopyChanged(event: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void {
|
@@ -14,12 +14,6 @@ import * as Types from './types/types.js';
|
|
14
14
|
// processors. Currently there is only one implemented, but you will see
|
15
15
|
// references to "processors" plural because it can easily be extended in the future.
|
16
16
|
|
17
|
-
export interface ParseConfig {
|
18
|
-
metadata?: Types.File.MetaData;
|
19
|
-
isFreshRecording?: boolean;
|
20
|
-
resolveSourceMap?: Types.Configuration.ParseOptions['resolveSourceMap'];
|
21
|
-
}
|
22
|
-
|
23
17
|
/**
|
24
18
|
* The Model is responsible for parsing arrays of raw trace events and storing the
|
25
19
|
* resulting data. It can store multiple traces at once, and can return the data for
|
@@ -87,10 +81,8 @@ export class Model extends EventTarget {
|
|
87
81
|
* });
|
88
82
|
* void this.traceModel.parse(events);
|
89
83
|
**/
|
90
|
-
async parse(traceEvents: readonly Types.Events.Event[], config?:
|
84
|
+
async parse(traceEvents: readonly Types.Events.Event[], config?: Types.Configuration.ParseOptions): Promise<void> {
|
91
85
|
const metadata = config?.metadata || {};
|
92
|
-
const isFreshRecording = config?.isFreshRecording || false;
|
93
|
-
const isCPUProfile = metadata?.dataOrigin === Types.File.DataOrigin.CPU_PROFILE;
|
94
86
|
// During parsing, periodically update any listeners on each processors'
|
95
87
|
// progress (if they have any updates).
|
96
88
|
const onTraceUpdate = (event: Event): void => {
|
@@ -106,13 +98,7 @@ export class Model extends EventTarget {
|
|
106
98
|
try {
|
107
99
|
// Wait for all outstanding promises before finishing the async execution,
|
108
100
|
// but perform all tasks in parallel.
|
109
|
-
|
110
|
-
isFreshRecording,
|
111
|
-
isCPUProfile,
|
112
|
-
metadata,
|
113
|
-
resolveSourceMap: config?.resolveSourceMap,
|
114
|
-
};
|
115
|
-
await this.#processor.parse(traceEvents, parseConfig);
|
101
|
+
await this.#processor.parse(traceEvents, config ?? {});
|
116
102
|
if (!this.#processor.data) {
|
117
103
|
throw new Error('processor did not parse trace');
|
118
104
|
}
|
@@ -152,6 +152,10 @@ export class TraceProcessor extends EventTarget {
|
|
152
152
|
throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);
|
153
153
|
}
|
154
154
|
|
155
|
+
if (typeof options.isCPUProfile === 'undefined' && options.metadata) {
|
156
|
+
options.isCPUProfile = options.metadata.dataOrigin === Types.File.DataOrigin.CPU_PROFILE;
|
157
|
+
}
|
158
|
+
|
155
159
|
options.logger?.start('total');
|
156
160
|
try {
|
157
161
|
this.#status = Status.PARSING;
|
@@ -424,9 +428,9 @@ export class TraceProcessor extends EventTarget {
|
|
424
428
|
insightSet.model = newModel;
|
425
429
|
}
|
426
430
|
|
427
|
-
#computeInsightSet(
|
428
|
-
|
429
|
-
|
431
|
+
#computeInsightSet(data: Handlers.Types.HandlerData, context: Insights.Types.InsightSetContext): void {
|
432
|
+
const logger = context.options.logger;
|
433
|
+
|
430
434
|
let id, urlString, navigation;
|
431
435
|
if (context.navigation) {
|
432
436
|
id = context.navigationId;
|
@@ -442,8 +446,8 @@ export class TraceProcessor extends EventTarget {
|
|
442
446
|
for (const [name, insight] of Object.entries(TraceProcessor.getInsightRunners())) {
|
443
447
|
let model: Insights.Types.InsightModel|Error;
|
444
448
|
try {
|
445
|
-
|
446
|
-
model = insight.generateInsight(data, context
|
449
|
+
logger?.start(`insights:${name}`);
|
450
|
+
model = insight.generateInsight(data, context);
|
447
451
|
model.frameId = context.frameId;
|
448
452
|
const navId = context.navigation?.args.data?.navigationId;
|
449
453
|
if (navId) {
|
@@ -456,7 +460,7 @@ export class TraceProcessor extends EventTarget {
|
|
456
460
|
} catch (err) {
|
457
461
|
model = err;
|
458
462
|
} finally {
|
459
|
-
|
463
|
+
logger?.end(`insights:${name}`);
|
460
464
|
}
|
461
465
|
Object.assign(insightSetModel, {[name]: model});
|
462
466
|
}
|
@@ -503,7 +507,7 @@ export class TraceProcessor extends EventTarget {
|
|
503
507
|
this.#insights = new Map();
|
504
508
|
}
|
505
509
|
this.#insights.set(insightSet.id, insightSet);
|
506
|
-
this.sortInsightSet(insightSet, options.metadata ?? null);
|
510
|
+
this.sortInsightSet(insightSet, context.options.metadata ?? null);
|
507
511
|
}
|
508
512
|
|
509
513
|
/**
|
@@ -543,11 +547,12 @@ export class TraceProcessor extends EventTarget {
|
|
543
547
|
data.Meta.traceBounds;
|
544
548
|
|
545
549
|
const context: Insights.Types.InsightSetContext = {
|
550
|
+
options,
|
546
551
|
bounds,
|
547
552
|
frameId: data.Meta.mainFrameId,
|
548
553
|
// No navigation or lantern context applies to this initial/no-navigation period.
|
549
554
|
};
|
550
|
-
this.#computeInsightSet(data, context
|
555
|
+
this.#computeInsightSet(data, context);
|
551
556
|
}
|
552
557
|
|
553
558
|
/**
|
@@ -593,13 +598,14 @@ export class TraceProcessor extends EventTarget {
|
|
593
598
|
}
|
594
599
|
|
595
600
|
const context: Insights.Types.InsightSetContext = {
|
601
|
+
options,
|
596
602
|
bounds,
|
597
603
|
frameId,
|
598
604
|
navigation,
|
599
605
|
navigationId,
|
600
606
|
lantern,
|
601
607
|
};
|
602
|
-
this.#computeInsightSet(data, context
|
608
|
+
this.#computeInsightSet(data, context);
|
603
609
|
}
|
604
610
|
}
|
605
611
|
|
@@ -93,9 +93,9 @@ function workletType(input: string): Types.Events.AuctionWorkletType {
|
|
93
93
|
* create everything other than the `args` field, as those are identical
|
94
94
|
* regardless of the type of event.
|
95
95
|
*/
|
96
|
-
function makeSyntheticEventBase(
|
97
|
-
|
98
|
-
Omit<Types.Events.SyntheticAuctionWorklet, 'args'> {
|
96
|
+
function makeSyntheticEventBase(
|
97
|
+
event: Types.Events.AuctionWorkletDoneWithProcess|
|
98
|
+
Types.Events.AuctionWorkletRunningInProcess): Omit<Types.Events.SyntheticAuctionWorklet, 'args'> {
|
99
99
|
return Helpers.SyntheticEvents.SyntheticEventsManager
|
100
100
|
.registerSyntheticEvent<Omit<Types.Events.SyntheticAuctionWorklet, 'args'>>({
|
101
101
|
rawSourceEvent: event,
|
@@ -178,6 +178,6 @@ export interface AuctionWorkletsData {
|
|
178
178
|
|
179
179
|
export function data(): AuctionWorkletsData {
|
180
180
|
return {
|
181
|
-
worklets:
|
181
|
+
worklets: createdSyntheticEvents,
|
182
182
|
};
|
183
183
|
}
|
@@ -95,8 +95,8 @@ export interface FramesData {
|
|
95
95
|
|
96
96
|
export function data(): FramesData {
|
97
97
|
return {
|
98
|
-
frames: model
|
99
|
-
framesById: model
|
98
|
+
frames: model?.frames() ?? [],
|
99
|
+
framesById: model?.framesById() ?? {},
|
100
100
|
};
|
101
101
|
}
|
102
102
|
|
@@ -37,15 +37,14 @@ import type {HandlerName} from './types.js';
|
|
37
37
|
// score for the given recording, and almost certainly not the
|
38
38
|
// navigation-to-unload CLS score.
|
39
39
|
|
40
|
-
interface
|
40
|
+
interface LayoutShiftsData {
|
41
41
|
clusters: readonly Types.Events.SyntheticLayoutShiftCluster[];
|
42
42
|
clustersByNavigationId: Map<Types.Events.NavigationId, Types.Events.SyntheticLayoutShiftCluster[]>;
|
43
43
|
sessionMaxScore: number;
|
44
44
|
// The session window which contains the SessionMaxScore
|
45
45
|
clsWindowID: number;
|
46
46
|
// We use these to calculate root causes for a given LayoutShift
|
47
|
-
|
48
|
-
prePaintEvents: Types.Events.PrePaint[];
|
47
|
+
prePaintEvents: readonly Types.Events.PrePaint[];
|
49
48
|
paintImageEvents: Types.Events.PaintImage[];
|
50
49
|
layoutInvalidationEvents: readonly Types.Events.LayoutInvalidationTracking[];
|
51
50
|
scheduleStyleInvalidationEvents: readonly Types.Events.ScheduleStyleInvalidationTracking[];
|
@@ -55,8 +54,7 @@ interface LayoutShifts {
|
|
55
54
|
layoutImageUnsizedEvents: readonly Types.Events.LayoutImageUnsized[];
|
56
55
|
remoteFonts: readonly RemoteFont[];
|
57
56
|
scoreRecords: readonly ScoreRecord[];
|
58
|
-
|
59
|
-
backendNodeIds: Protocol.DOM.BackendNodeId[];
|
57
|
+
backendNodeIds: Set<Protocol.DOM.BackendNodeId>;
|
60
58
|
}
|
61
59
|
|
62
60
|
interface RemoteFont {
|
@@ -524,7 +522,7 @@ async function buildLayoutShiftsClusters(): Promise<void> {
|
|
524
522
|
}
|
525
523
|
}
|
526
524
|
|
527
|
-
export function data():
|
525
|
+
export function data(): LayoutShiftsData {
|
528
526
|
return {
|
529
527
|
clusters,
|
530
528
|
sessionMaxScore,
|
@@ -532,15 +530,14 @@ export function data(): LayoutShifts {
|
|
532
530
|
prePaintEvents,
|
533
531
|
layoutInvalidationEvents,
|
534
532
|
scheduleStyleInvalidationEvents,
|
535
|
-
styleRecalcInvalidationEvents
|
533
|
+
styleRecalcInvalidationEvents,
|
536
534
|
renderFrameImplCreateChildFrameEvents,
|
537
535
|
domLoadingEvents,
|
538
536
|
layoutImageUnsizedEvents,
|
539
537
|
remoteFonts,
|
540
538
|
scoreRecords,
|
541
|
-
|
542
|
-
|
543
|
-
clustersByNavigationId: new Map(clustersByNavigationId),
|
539
|
+
backendNodeIds,
|
540
|
+
clustersByNavigationId,
|
544
541
|
paintImageEvents,
|
545
542
|
};
|
546
543
|
}
|
@@ -28,11 +28,15 @@ let devicePixelRatio: number|null = null;
|
|
28
28
|
let processNames = new Map<Types.Events.ProcessID, Types.Events.ProcessName>();
|
29
29
|
|
30
30
|
let topLevelRendererIds = new Set<Types.Events.ProcessID>();
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
|
32
|
+
function makeNewTraceBounds(): Types.Timing.TraceWindowMicro {
|
33
|
+
return {
|
34
|
+
min: Types.Timing.Micro(Number.POSITIVE_INFINITY),
|
35
|
+
max: Types.Timing.Micro(Number.NEGATIVE_INFINITY),
|
36
|
+
range: Types.Timing.Micro(Number.POSITIVE_INFINITY),
|
37
|
+
};
|
38
|
+
}
|
39
|
+
let traceBounds: Types.Timing.TraceWindowMicro = makeNewTraceBounds();
|
36
40
|
|
37
41
|
/**
|
38
42
|
* These represent the user navigating. Values such as First Contentful Paint,
|
@@ -98,9 +102,7 @@ export function reset(): void {
|
|
98
102
|
rendererProcessesByFrameId = new Map();
|
99
103
|
framesByProcessId = new Map();
|
100
104
|
|
101
|
-
traceBounds
|
102
|
-
traceBounds.max = Types.Timing.Micro(Number.NEGATIVE_INFINITY);
|
103
|
-
traceBounds.range = Types.Timing.Micro(Number.POSITIVE_INFINITY);
|
105
|
+
traceBounds = makeNewTraceBounds();
|
104
106
|
traceStartedTimeFromTracingStartedEvent = Types.Timing.Micro(-1);
|
105
107
|
|
106
108
|
traceIsGeneric = true;
|
@@ -490,7 +492,7 @@ export type FrameProcessData =
|
|
490
492
|
|
491
493
|
export function data(): MetaHandlerData {
|
492
494
|
return {
|
493
|
-
traceBounds
|
495
|
+
traceBounds,
|
494
496
|
browserProcessId,
|
495
497
|
browserThreadId,
|
496
498
|
processNames,
|
@@ -109,7 +109,7 @@ export interface Data {
|
|
109
109
|
legacySyntheticScreenshots: Types.Events.LegacySyntheticScreenshot[]|null;
|
110
110
|
screenshots: Types.Events.Screenshot[]|null;
|
111
111
|
}
|
112
|
-
|
112
|
+
|
113
113
|
export function data(): Data {
|
114
114
|
return {
|
115
115
|
legacySyntheticScreenshots: syntheticScreenshots.length ? syntheticScreenshots : null,
|
@@ -54,14 +54,14 @@ export function reset(): void {
|
|
54
54
|
}
|
55
55
|
|
56
56
|
export function handleEvent(event: Types.Events.Event): void {
|
57
|
-
const getOrMakeScript = (isolate: string, scriptIdAsNumber: number): Script => {
|
57
|
+
const getOrMakeScript = (isolate: string|number, scriptIdAsNumber: number): Script => {
|
58
58
|
const scriptId = String(scriptIdAsNumber) as Protocol.Runtime.ScriptId;
|
59
59
|
const key = `${isolate}.${scriptId}`;
|
60
60
|
return Platform.MapUtilities.getWithDefault(
|
61
61
|
scriptById, key, () => ({isolate, scriptId, frame: '', ts: 0} as Script));
|
62
62
|
};
|
63
63
|
|
64
|
-
if (Types.Events.
|
64
|
+
if (Types.Events.isRundownScriptCompiled(event) && event.args.data) {
|
65
65
|
const {isolate, scriptId, frame} = event.args.data;
|
66
66
|
const script = getOrMakeScript(isolate, scriptId);
|
67
67
|
script.frame = frame;
|
@@ -70,7 +70,7 @@ export function handleEvent(event: Types.Events.Event): void {
|
|
70
70
|
return;
|
71
71
|
}
|
72
72
|
|
73
|
-
if (Types.Events.
|
73
|
+
if (Types.Events.isRundownScript(event)) {
|
74
74
|
const {isolate, scriptId, url, sourceUrl, sourceMapUrl, sourceMapUrlElided} = event.args.data;
|
75
75
|
const script = getOrMakeScript(isolate, scriptId);
|
76
76
|
script.url = url;
|
@@ -91,14 +91,14 @@ export function handleEvent(event: Types.Events.Event): void {
|
|
91
91
|
return;
|
92
92
|
}
|
93
93
|
|
94
|
-
if (Types.Events.
|
94
|
+
if (Types.Events.isRundownScriptSource(event)) {
|
95
95
|
const {isolate, scriptId, sourceText} = event.args.data;
|
96
96
|
const script = getOrMakeScript(isolate, scriptId);
|
97
97
|
script.content = sourceText;
|
98
98
|
return;
|
99
99
|
}
|
100
100
|
|
101
|
-
if (Types.Events.
|
101
|
+
if (Types.Events.isRundownScriptSourceLarge(event)) {
|
102
102
|
const {isolate, scriptId, sourceText} = event.args.data;
|
103
103
|
const script = getOrMakeScript(isolate, scriptId);
|
104
104
|
script.content = (script.content ?? '') + sourceText;
|
@@ -9,14 +9,8 @@ import {data as metaHandlerData} from './MetaHandler.js';
|
|
9
9
|
import {ScoreClassification} from './PageLoadMetricsHandler.js';
|
10
10
|
import type {HandlerName} from './types.js';
|
11
11
|
|
12
|
-
// This handler
|
13
|
-
//
|
14
|
-
// EventTimings into Interactions, which we use to show interactions and
|
15
|
-
// highlight long interactions to the user, along with INP.
|
16
|
-
|
17
|
-
// We don't need to know which process / thread these events occurred in,
|
18
|
-
// because they are effectively global, so we just track all that we find.
|
19
|
-
let allEvents: Types.Events.EventTimingBeginOrEnd[] = [];
|
12
|
+
// This handler gathers EventTimings into Interactions, which we use to show
|
13
|
+
// interactions and highlight long interactions to the user, along with INP.
|
20
14
|
|
21
15
|
let beginCommitCompositorFrameEvents: Types.Events.BeginCommitCompositorFrame[] = [];
|
22
16
|
let parseMetaViewportEvents: Types.Events.ParseMetaViewport[] = [];
|
@@ -27,8 +21,6 @@ const INP_GOOD_TIMING = LONG_INTERACTION_THRESHOLD;
|
|
27
21
|
const INP_MEDIUM_TIMING = Helpers.Timing.milliToMicro(Types.Timing.Milli(500));
|
28
22
|
|
29
23
|
export interface UserInteractionsData {
|
30
|
-
/** All the user events we found in the trace */
|
31
|
-
allEvents: readonly Types.Events.EventTimingBeginOrEnd[];
|
32
24
|
/** All the BeginCommitCompositorFrame events we found in the trace */
|
33
25
|
beginCommitCompositorFrameEvents: readonly Types.Events.BeginCommitCompositorFrame[];
|
34
26
|
/** All the ParseMetaViewport events we found in the trace */
|
@@ -68,7 +60,6 @@ let eventTimingEndEventsById = new Map<string, Types.Events.EventTimingEnd>();
|
|
68
60
|
let eventTimingStartEventsForInteractions: Types.Events.EventTimingBegin[] = [];
|
69
61
|
|
70
62
|
export function reset(): void {
|
71
|
-
allEvents = [];
|
72
63
|
beginCommitCompositorFrameEvents = [];
|
73
64
|
parseMetaViewportEvents = [];
|
74
65
|
interactionEvents = [];
|
@@ -98,8 +89,6 @@ export function handleEvent(event: Types.Events.Event): void {
|
|
98
89
|
eventTimingEndEventsById.set(event.id, event);
|
99
90
|
}
|
100
91
|
|
101
|
-
allEvents.push(event);
|
102
|
-
|
103
92
|
// From this point on we want to find events that represent interactions.
|
104
93
|
// These events are always start events - those are the ones that contain all
|
105
94
|
// the metadata about the interaction.
|
@@ -351,7 +340,6 @@ export async function finalize(): Promise<void> {
|
|
351
340
|
|
352
341
|
export function data(): UserInteractionsData {
|
353
342
|
return {
|
354
|
-
allEvents,
|
355
343
|
beginCommitCompositorFrameEvents,
|
356
344
|
parseMetaViewportEvents,
|
357
345
|
interactionEvents,
|
@@ -226,9 +226,8 @@ export function data(): UserTimingsData {
|
|
226
226
|
performanceMeasures: syntheticEvents.filter(e => e.cat === 'blink.user_timing') as
|
227
227
|
Types.Events.SyntheticUserTimingPair[],
|
228
228
|
consoleTimings: syntheticEvents.filter(e => e.cat === 'blink.console') as Types.Events.SyntheticConsoleTimingPair[],
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
measureTraceByTraceId: new Map(measureTraceByTraceId),
|
229
|
+
performanceMarks: performanceMarkEvents,
|
230
|
+
timestampEvents,
|
231
|
+
measureTraceByTraceId,
|
233
232
|
};
|
234
233
|
}
|
@@ -471,7 +471,7 @@ function getUnsizedImageRootCauses(
|
|
471
471
|
return rootCausesByShift;
|
472
472
|
}
|
473
473
|
|
474
|
-
export function
|
474
|
+
export function isCLSCulpritsInsight(insight: InsightModel): insight is CLSCulpritsInsightModel {
|
475
475
|
return insight.insightKey === InsightKeys.CLS_CULPRITS;
|
476
476
|
}
|
477
477
|
|
@@ -81,7 +81,7 @@ const TARGET_MS = 100;
|
|
81
81
|
// Threshold for compression savings.
|
82
82
|
const IGNORE_THRESHOLD_IN_BYTES = 1400;
|
83
83
|
|
84
|
-
export function
|
84
|
+
export function isDocumentLatencyInsight(x: InsightModel): x is DocumentLatencyInsightModel {
|
85
85
|
return x.insightKey === 'DocumentLatency';
|
86
86
|
}
|
87
87
|
|
@@ -190,13 +190,12 @@ function finalize(partialModel: PartialInsightModel<DocumentLatencyInsightModel>
|
|
190
190
|
}
|
191
191
|
|
192
192
|
export function generateInsight(
|
193
|
-
data: Handlers.Types.HandlerData, context: InsightSetContext
|
194
|
-
timeFormatters?: Types.Configuration.InsightTimeFormatters): DocumentLatencyInsightModel {
|
193
|
+
data: Handlers.Types.HandlerData, context: InsightSetContext): DocumentLatencyInsightModel {
|
195
194
|
if (!context.navigation) {
|
196
195
|
return finalize({});
|
197
196
|
}
|
198
197
|
|
199
|
-
const millisToString =
|
198
|
+
const millisToString = context.options.insightTimeFormatters?.milli ?? i18n.TimeUtilities.millisToString;
|
200
199
|
|
201
200
|
const documentRequest = data.NetworkRequests.byId.get(context.navigationId);
|
202
201
|
if (!documentRequest) {
|
@@ -60,7 +60,7 @@ function finalize(partialModel: PartialInsightModel<DuplicatedJavaScriptInsightM
|
|
60
60
|
};
|
61
61
|
}
|
62
62
|
|
63
|
-
export function
|
63
|
+
export function isDuplicatedJavaScriptInsight(model: InsightModel): model is DuplicatedJavaScriptInsightModel {
|
64
64
|
return model.insightKey === InsightKeys.DUPLICATE_JAVASCRIPT;
|
65
65
|
}
|
66
66
|
|