chrome-devtools-frontend 1.0.1514545 → 1.0.1515796
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/AUTHORS +1 -0
- package/docs/committers_policy.md +1 -1
- package/docs/contributing/infrastructure.md +101 -5
- package/front_end/Images/gdp-logo-dark.png +0 -0
- package/front_end/Images/gdp-logo-light.png +0 -0
- package/front_end/core/common/Settings.ts +11 -32
- package/front_end/entrypoints/main/main-meta.ts +2 -2
- package/front_end/generated/InspectorBackendCommands.js +4 -4
- package/front_end/generated/SupportedCSSProperties.js +12 -0
- package/front_end/generated/protocol.ts +10 -1
- package/front_end/global_typings/global_defs.d.ts +15 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +22 -23
- package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +6 -7
- package/front_end/models/ai_assistance/ai_assistance.ts +3 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +141 -2
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +96 -10
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +123 -55
- package/front_end/models/cpu_profile/ProfileTreeModel.ts +1 -1
- package/front_end/models/extensions/ExtensionPanel.ts +4 -0
- package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +5 -1
- package/front_end/models/javascript_metadata/NativeFunctions.js +7 -7
- package/front_end/models/text_utils/TextUtils.ts +26 -0
- package/front_end/models/trace/Processor.ts +1 -1
- package/front_end/models/trace/helpers/Trace.ts +1 -1
- package/front_end/models/trace/insights/DocumentLatency.ts +9 -7
- package/front_end/models/trace/types/Configuration.ts +12 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +6 -7
- package/front_end/panels/ai_assistance/components/ChatView.ts +1 -2
- package/front_end/panels/application/components/BackForwardCacheStrings.ts +8 -2
- package/front_end/panels/common/BadgeNotification.ts +10 -8
- package/front_end/panels/common/GdpSignUpDialog.ts +25 -16
- package/front_end/panels/common/gdpSignUpDialog.css +10 -14
- package/front_end/panels/console/ConsoleView.ts +4 -0
- package/front_end/panels/elements/ElementsPanel.ts +4 -0
- package/front_end/panels/elements/StylePropertiesSection.ts +4 -4
- package/front_end/panels/network/NetworkConfigView.ts +1 -1
- package/front_end/panels/network/NetworkLogView.ts +2 -2
- package/front_end/panels/network/components/HeaderSectionRow.ts +2 -3
- package/front_end/panels/profiler/HeapProfileView.ts +1 -3
- package/front_end/panels/profiler/HeapSnapshotView.ts +5 -1
- package/front_end/panels/profiler/ProfileDataGrid.ts +4 -0
- package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +7 -29
- package/front_end/panels/profiler/ProfileView.ts +4 -0
- package/front_end/panels/recorder/components/CreateRecordingView.ts +2 -2
- package/front_end/panels/search/SearchView.ts +322 -248
- package/front_end/panels/settings/KeybindsSettingsTab.ts +1 -1
- package/front_end/panels/settings/SettingsScreen.ts +1 -1
- package/front_end/panels/settings/components/SyncSection.ts +59 -14
- package/front_end/panels/settings/components/syncSection.css +17 -4
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +4 -7
- package/front_end/panels/sources/SourcesView.ts +4 -0
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +2 -2
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +6 -3
- package/front_end/panels/timeline/CountersGraph.ts +5 -5
- package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +4 -3
- package/front_end/panels/timeline/TimelineFlameChartView.ts +9 -4
- package/front_end/panels/timeline/TimelineHistoryManager.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +4 -3
- package/front_end/panels/timeline/TimelineTreeView.ts +6 -2
- package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +2 -2
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +6 -6
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +2 -2
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -3
- package/front_end/panels/timeline/utils/utils.ts +0 -8
- package/front_end/panels/webauthn/WebauthnPane.ts +1 -1
- package/front_end/{panels/timeline/utils → services/tracing}/FreshRecording.ts +1 -1
- package/front_end/services/tracing/tracing.ts +2 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/README.md +6 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +11 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +30 -8
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +1 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js +5 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +12 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +22 -8
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +11 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +30 -8
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +1 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js +5 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +12 -2
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +13 -2
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +50 -8
- package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +0 -1
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +8 -1
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +21 -5
- package/front_end/third_party/puppeteer/package/src/generated/version.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +12 -0
- package/front_end/ui/components/text_editor/config.ts +66 -16
- package/front_end/ui/legacy/Dialog.ts +38 -13
- package/front_end/ui/legacy/InspectorView.ts +7 -9
- package/front_end/ui/legacy/ProgressIndicator.ts +4 -5
- package/front_end/ui/legacy/SearchableView.ts +73 -55
- package/front_end/ui/legacy/SettingsUI.ts +5 -5
- package/front_end/ui/legacy/components/color_picker/Spectrum.ts +1 -4
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +5 -5
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +4 -2
- package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +1 -4
- package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +3 -3
- package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/JSONView.ts +10 -10
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -0
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +4 -0
- package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -4
- package/front_end/ui/legacy/searchableView.css +0 -4
- package/front_end/ui/visual_logging/Debugging.ts +24 -12
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +3 -3
- package/front_end/Images/src/gdp-logo-standalone.svg +0 -9
- /package/front_end/{panels/timeline/utils → models/ai_assistance/performance}/AICallTree.ts +0 -0
- /package/front_end/{panels/timeline/utils → models/ai_assistance/performance}/AIContext.ts +0 -0
- /package/front_end/{panels/timeline/utils/InsightAIContext.ts → models/ai_assistance/performance/AIQueries.ts} +0 -0
@@ -9,7 +9,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
|
|
9
9
|
import * as Platform from '../../../core/platform/platform.js';
|
10
10
|
import * as Root from '../../../core/root/root.js';
|
11
11
|
import * as SDK from '../../../core/sdk/sdk.js';
|
12
|
-
import * as
|
12
|
+
import * as Tracing from '../../../services/tracing/tracing.js';
|
13
13
|
import * as Trace from '../../trace/trace.js';
|
14
14
|
import type {ConversationType} from '../AiHistoryStorage.js';
|
15
15
|
import {
|
@@ -18,6 +18,8 @@ import {
|
|
18
18
|
} from '../data_formatters/PerformanceInsightFormatter.js';
|
19
19
|
import {PerformanceTraceFormatter} from '../data_formatters/PerformanceTraceFormatter.js';
|
20
20
|
import {debugLog} from '../debug.js';
|
21
|
+
import {AICallTree} from '../performance/AICallTree.js';
|
22
|
+
import {AgentFocus} from '../performance/AIContext.js';
|
21
23
|
|
22
24
|
import {
|
23
25
|
type AgentOptions,
|
@@ -156,23 +158,23 @@ enum ScorePriority {
|
|
156
158
|
DEFAULT = 1,
|
157
159
|
}
|
158
160
|
|
159
|
-
export class PerformanceTraceContext extends ConversationContext<
|
161
|
+
export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
160
162
|
static full(parsedTrace: Trace.TraceModel.ParsedTrace): PerformanceTraceContext {
|
161
|
-
return new PerformanceTraceContext(
|
163
|
+
return new PerformanceTraceContext(AgentFocus.full(parsedTrace));
|
162
164
|
}
|
163
165
|
|
164
166
|
static fromInsight(parsedTrace: Trace.TraceModel.ParsedTrace, insight: Trace.Insights.Types.InsightModel):
|
165
167
|
PerformanceTraceContext {
|
166
|
-
return new PerformanceTraceContext(
|
168
|
+
return new PerformanceTraceContext(AgentFocus.fromInsight(parsedTrace, insight));
|
167
169
|
}
|
168
170
|
|
169
|
-
static fromCallTree(callTree:
|
170
|
-
return new PerformanceTraceContext(
|
171
|
+
static fromCallTree(callTree: AICallTree): PerformanceTraceContext {
|
172
|
+
return new PerformanceTraceContext(AgentFocus.fromCallTree(callTree));
|
171
173
|
}
|
172
174
|
|
173
|
-
#focus:
|
175
|
+
#focus: AgentFocus;
|
174
176
|
|
175
|
-
constructor(focus:
|
177
|
+
constructor(focus: AgentFocus) {
|
176
178
|
super();
|
177
179
|
this.#focus = focus;
|
178
180
|
}
|
@@ -182,7 +184,7 @@ export class PerformanceTraceContext extends ConversationContext<TimelineUtils.A
|
|
182
184
|
return `trace-${min}-${max}`;
|
183
185
|
}
|
184
186
|
|
185
|
-
override getItem():
|
187
|
+
override getItem(): AgentFocus {
|
186
188
|
return this.#focus;
|
187
189
|
}
|
188
190
|
|
@@ -226,13 +228,13 @@ type PerformanceConversationType =
|
|
226
228
|
* One agent instance handles one conversation. Create a new agent
|
227
229
|
* instance for a new conversation.
|
228
230
|
*/
|
229
|
-
export class PerformanceAgent extends AiAgent<
|
231
|
+
export class PerformanceAgent extends AiAgent<AgentFocus> {
|
230
232
|
// TODO: would make more sense on AgentOptions
|
231
233
|
#conversationType: PerformanceConversationType;
|
232
234
|
#formatter: PerformanceTraceFormatter|null = null;
|
233
235
|
#lastInsightForEnhancedQuery: Trace.Insights.Types.InsightModel|undefined;
|
234
236
|
#eventsSerializer = new Trace.EventsSerializer.EventsSerializer();
|
235
|
-
#lastFocusHandledForContextDetails:
|
237
|
+
#lastFocusHandledForContextDetails: AgentFocus|null = null;
|
236
238
|
|
237
239
|
constructor(opts: AgentOptions, conversationType: PerformanceConversationType) {
|
238
240
|
super(opts);
|
@@ -250,8 +252,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
250
252
|
*
|
251
253
|
* The record key is the result of a function's displayInfoFromArgs.
|
252
254
|
*/
|
253
|
-
#functionCallCacheForFocus =
|
254
|
-
new Map<TimelineUtils.AIContext.AgentFocus, Record<string, Host.AidaClient.RequestFact>>();
|
255
|
+
#functionCallCacheForFocus = new Map<AgentFocus, Record<string, Host.AidaClient.RequestFact>>();
|
255
256
|
|
256
257
|
#networkDataDescriptionFact: Host.AidaClient.RequestFact = {
|
257
258
|
text: TraceEventFormatter.networkDataFormatDescription,
|
@@ -305,8 +306,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
305
306
|
}
|
306
307
|
|
307
308
|
async *
|
308
|
-
handleContextDetails(context: ConversationContext<
|
309
|
-
AsyncGenerator<ContextResponse, void, void> {
|
309
|
+
handleContextDetails(context: ConversationContext<AgentFocus>|null): AsyncGenerator<ContextResponse, void, void> {
|
310
310
|
if (!context) {
|
311
311
|
return;
|
312
312
|
}
|
@@ -368,8 +368,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
368
368
|
return super.parseTextResponse(response);
|
369
369
|
}
|
370
370
|
|
371
|
-
override async enhanceQuery(query: string, context: ConversationContext<
|
372
|
-
Promise<string> {
|
371
|
+
override async enhanceQuery(query: string, context: ConversationContext<AgentFocus>|null): Promise<string> {
|
373
372
|
if (!context) {
|
374
373
|
this.clearDeclaredFunctions();
|
375
374
|
return query;
|
@@ -426,7 +425,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
426
425
|
}
|
427
426
|
|
428
427
|
override async * run(initialQuery: string, options: {
|
429
|
-
selected: ConversationContext<
|
428
|
+
selected: ConversationContext<AgentFocus>|null,
|
430
429
|
signal?: AbortSignal,
|
431
430
|
}): AsyncGenerator<ResponseData, void, void> {
|
432
431
|
const focus = options.selected?.getItem();
|
@@ -518,7 +517,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
518
517
|
});
|
519
518
|
}
|
520
519
|
|
521
|
-
#addFacts(focus:
|
520
|
+
#addFacts(focus: AgentFocus): void {
|
522
521
|
this.addFact(this.#callFrameDataDescriptionFact);
|
523
522
|
this.addFact(this.#networkDataDescriptionFact);
|
524
523
|
|
@@ -543,7 +542,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
543
542
|
}
|
544
543
|
}
|
545
544
|
|
546
|
-
#cacheFunctionResult(focus:
|
545
|
+
#cacheFunctionResult(focus: AgentFocus, key: string, result: string): void {
|
547
546
|
const fact: Host.AidaClient.RequestFact = {
|
548
547
|
text: `This is the result of calling ${key}:\n${result}`,
|
549
548
|
metadata: {source: key, score: ScorePriority.DEFAULT},
|
@@ -553,7 +552,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
553
552
|
this.#functionCallCacheForFocus.set(focus, cache);
|
554
553
|
}
|
555
554
|
|
556
|
-
#declareFunctions(context: ConversationContext<
|
555
|
+
#declareFunctions(context: ConversationContext<AgentFocus>): void {
|
557
556
|
const focus = context.getItem();
|
558
557
|
const {parsedTrace, insightSet} = focus.data;
|
559
558
|
|
@@ -786,7 +785,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
786
785
|
return {error: 'Invalid eventKey'};
|
787
786
|
}
|
788
787
|
|
789
|
-
const tree =
|
788
|
+
const tree = AICallTree.fromEvent(event, parsedTrace);
|
790
789
|
const callTree = tree ? this.#formatter.formatCallTree(tree) : 'No call tree found';
|
791
790
|
|
792
791
|
const key = `getDetailedCallTree(${args.eventKey})`;
|
@@ -796,7 +795,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
|
|
796
795
|
|
797
796
|
});
|
798
797
|
|
799
|
-
const isFresh =
|
798
|
+
const isFresh = Tracing.FreshRecording.Tracker.instance().recordingIsFresh(parsedTrace);
|
800
799
|
const hasScriptContents =
|
801
800
|
parsedTrace.metadata.enhancedTraceVersion && parsedTrace.data.Scripts.scripts.some(s => s.content);
|
802
801
|
|
@@ -5,7 +5,8 @@
|
|
5
5
|
import * as Host from '../../../core/host/host.js';
|
6
6
|
import * as i18n from '../../../core/i18n/i18n.js';
|
7
7
|
import * as Root from '../../../core/root/root.js';
|
8
|
-
import type
|
8
|
+
import type {AICallTree} from '../performance/AICallTree.js';
|
9
|
+
import type {AgentFocus} from '../performance/AIContext.js';
|
9
10
|
|
10
11
|
import {AiAgent, type ContextResponse, type ConversationContext, type RequestOptions, ResponseType} from './AiAgent.js';
|
11
12
|
import {PerformanceTraceContext} from './PerformanceAgent.js';
|
@@ -87,7 +88,7 @@ The 'calculatePosition' function, taking 80ms, is a potential bottleneck.
|
|
87
88
|
Consider optimizing the position calculation logic or reducing the frequency of calls to improve animation performance.
|
88
89
|
`;
|
89
90
|
|
90
|
-
export class PerformanceAnnotationsAgent extends AiAgent<
|
91
|
+
export class PerformanceAnnotationsAgent extends AiAgent<AgentFocus> {
|
91
92
|
override preamble = callTreePreamble;
|
92
93
|
|
93
94
|
get clientFeature(): Host.AidaClient.ClientFeature {
|
@@ -109,8 +110,7 @@ export class PerformanceAnnotationsAgent extends AiAgent<TimelineUtils.AIContext
|
|
109
110
|
}
|
110
111
|
|
111
112
|
async *
|
112
|
-
handleContextDetails(context: ConversationContext<
|
113
|
-
AsyncGenerator<ContextResponse, void, void> {
|
113
|
+
handleContextDetails(context: ConversationContext<AgentFocus>|null): AsyncGenerator<ContextResponse, void, void> {
|
114
114
|
if (!context) {
|
115
115
|
return;
|
116
116
|
}
|
@@ -134,8 +134,7 @@ export class PerformanceAnnotationsAgent extends AiAgent<TimelineUtils.AIContext
|
|
134
134
|
};
|
135
135
|
}
|
136
136
|
|
137
|
-
override async enhanceQuery(query: string, context: ConversationContext<
|
138
|
-
Promise<string> {
|
137
|
+
override async enhanceQuery(query: string, context: ConversationContext<AgentFocus>|null): Promise<string> {
|
139
138
|
if (!context) {
|
140
139
|
return query;
|
141
140
|
}
|
@@ -153,7 +152,7 @@ export class PerformanceAnnotationsAgent extends AiAgent<TimelineUtils.AIContext
|
|
153
152
|
/**
|
154
153
|
* Used in the Performance panel to automatically generate a label for a selected entry.
|
155
154
|
*/
|
156
|
-
async generateAIEntryLabel(callTree:
|
155
|
+
async generateAIEntryLabel(callTree: AICallTree): Promise<string> {
|
157
156
|
const context = PerformanceTraceContext.fromCallTree(callTree);
|
158
157
|
const response = await Array.fromAsync(this.run(AI_LABEL_GENERATION_PROMPT, {selected: context}));
|
159
158
|
const lastResponse = response.at(-1);
|
@@ -23,3 +23,6 @@ export * from './data_formatters/PerformanceTraceFormatter.js';
|
|
23
23
|
export * from './data_formatters/UnitFormatters.js';
|
24
24
|
export * from './ConversationHandler.js';
|
25
25
|
export * from './injected.js';
|
26
|
+
export * from './performance/AICallTree.js';
|
27
|
+
export * from './performance/AIContext.js';
|
28
|
+
export * from './performance/AIQueries.js';
|
package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt
CHANGED
@@ -830,11 +830,13 @@ URL: https://web.dev/cls/
|
|
830
830
|
Bounds: {min: 1020034823047, max: 1020036087961}
|
831
831
|
CPU throttling: none
|
832
832
|
Network throttling: none
|
833
|
-
Metrics:
|
833
|
+
Metrics (lab / observed):
|
834
834
|
- LCP: 118 ms, event: (eventKey: r-1802, ts: 1020034953358)
|
835
|
+
- LCP breakdown:
|
835
836
|
- TTFB: 31.3 ms, bounds: {min: 1020034834921, max: 1020034866264}
|
836
837
|
- Render delay: 87.1 ms, bounds: {min: 1020034866264, max: 1020034953358}
|
837
838
|
- CLS: 0.00
|
839
|
+
Metrics (field / real users): n/a – no data for this page in CrUX
|
838
840
|
Available insights:
|
839
841
|
- insight name: LCPBreakdown
|
840
842
|
description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
|
@@ -861,13 +863,15 @@ URL: https://news.yahoo.com/
|
|
861
863
|
Bounds: {min: 157423484442, max: 157427277166}
|
862
864
|
CPU throttling: none
|
863
865
|
Network throttling: none
|
864
|
-
Metrics:
|
866
|
+
Metrics (lab / observed):
|
865
867
|
- LCP: 464 ms, event: (eventKey: r-33210, ts: 157423953162)
|
868
|
+
- LCP breakdown:
|
866
869
|
- TTFB: 215.7 ms, bounds: {min: 157423488682, max: 157423704371}
|
867
870
|
- Load delay: 90.3 ms, bounds: {min: 157423704371, max: 157423794709}
|
868
871
|
- Load duration: 64 ms, bounds: {min: 157423794709, max: 157423858674}
|
869
872
|
- Render delay: 94.5 ms, bounds: {min: 157423858674, max: 157423953162}
|
870
873
|
- CLS: 0.04, event: (eventKey: s--1, ts: 157425604232)
|
874
|
+
Metrics (field / real users): n/a – no data for this page in CrUX
|
871
875
|
Available insights:
|
872
876
|
- insight name: LCPBreakdown
|
873
877
|
description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
|
@@ -914,3 +918,138 @@ Available insights:
|
|
914
918
|
example question: Is my site polyfilling modern JavaScript features?
|
915
919
|
example question: How can I reduce the amount of legacy JavaScript on my page?
|
916
920
|
=== end content
|
921
|
+
|
922
|
+
Title: PerformanceTraceFormatter formatTraceSummary deals with CrUX manager errors
|
923
|
+
Content:
|
924
|
+
URL: http://localhost/image-delivery-cases.html
|
925
|
+
Bounds: {min: 59728641874, max: 59734400108}
|
926
|
+
CPU throttling: 1x
|
927
|
+
Network throttling: No throttling
|
928
|
+
Metrics (lab / observed):
|
929
|
+
- LCP: 663 ms, event: (eventKey: r-14753, ts: 59729312744)
|
930
|
+
- LCP breakdown:
|
931
|
+
- TTFB: 7 ms, bounds: {min: 59728649746, max: 59728656735}
|
932
|
+
- Load delay: 45.6 ms, bounds: {min: 59728656735, max: 59728702313}
|
933
|
+
- Load duration: 506.3 ms, bounds: {min: 59728702313, max: 59729208600}
|
934
|
+
- Render delay: 104.1 ms, bounds: {min: 59729208600, max: 59729312744}
|
935
|
+
- CLS: 0.31, event: (eventKey: s--1, ts: 59729100192)
|
936
|
+
Metrics (field / real users): n/a – no data for this page in CrUX
|
937
|
+
Available insights:
|
938
|
+
- insight name: Cache
|
939
|
+
description: A long cache lifetime can speed up repeat visits to your page. [Learn more](https://web.dev/uses-long-cache-ttl/).
|
940
|
+
relevant trace bounds: {min: 59728702014, max: 59728867430}
|
941
|
+
estimated metric savings: FCP 0 ms, LCP 150 ms
|
942
|
+
estimated wasted bytes: 971.5 kB
|
943
|
+
example question: What caching strategies can I apply to improve my page performance?
|
944
|
+
- insight name: ImageDelivery
|
945
|
+
description: Reducing the download time of images can improve the perceived load time of the page and LCP. [Learn more about optimizing image size](https://developer.chrome.com/docs/lighthouse/performance/uses-optimized-images/)
|
946
|
+
relevant trace bounds: {min: 59728701403, max: 59729395208}
|
947
|
+
estimated metric savings: FCP 0 ms, LCP 100 ms
|
948
|
+
estimated wasted bytes: 2 MB
|
949
|
+
example question: What should I do to improve and optimize the time taken to fetch and display images on the page?
|
950
|
+
example question: Are all images on my site optimized?
|
951
|
+
- insight name: LCPBreakdown
|
952
|
+
description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
|
953
|
+
relevant trace bounds: {min: 59728649746, max: 59729312744}
|
954
|
+
example question: Help me optimize my LCP score
|
955
|
+
example question: Which LCP phase was most problematic?
|
956
|
+
example question: What can I do to reduce the LCP time for this page load?
|
957
|
+
- insight name: LCPDiscovery
|
958
|
+
description: Optimize LCP by making the LCP image [discoverable](https://web.dev/articles/optimize-lcp#1_eliminate_resource_load_delay) from the HTML immediately, and [avoiding lazy-loading](https://web.dev/articles/lcp-lazy-loading)
|
959
|
+
relevant trace bounds: {min: 59728656735, max: 59729209036}
|
960
|
+
example question: Suggest fixes to reduce my LCP
|
961
|
+
example question: What can I do to reduce my LCP discovery time?
|
962
|
+
example question: Why is LCP discovery time important?
|
963
|
+
- insight name: CLSCulprits
|
964
|
+
description: Layout shifts occur when elements move absent any user interaction. [Investigate the causes of layout shifts](https://web.dev/articles/optimize-cls), such as elements being added, removed, or their fonts changing as the page loads.
|
965
|
+
relevant trace bounds: {min: 59729100192, max: 59730317334}
|
966
|
+
example question: Help me optimize my CLS score
|
967
|
+
example question: How can I prevent layout shifts on this page?
|
968
|
+
- insight name: DocumentLatency
|
969
|
+
description: Your first network request is the most important. Reduce its latency by avoiding redirects, ensuring a fast server response, and enabling text compression.
|
970
|
+
relevant trace bounds: {min: 59728651057, max: 59728790724}
|
971
|
+
estimated metric savings: FCP 0 ms, LCP 0 ms
|
972
|
+
estimated wasted bytes: 1.6 kB
|
973
|
+
example question: How do I decrease the initial loading time of my page?
|
974
|
+
example question: Did anything slow down the request for this document?
|
975
|
+
- insight name: Viewport
|
976
|
+
description: Tap interactions may be [delayed by up to 300 ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.
|
977
|
+
relevant trace bounds: {min: 59728649746, max: 59734400108}
|
978
|
+
estimated metric savings: INP 0 ms
|
979
|
+
example question: How do I make sure my page is optimized for mobile viewing?
|
980
|
+
- insight name: ThirdParties
|
981
|
+
description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page's content.
|
982
|
+
relevant trace bounds: {min: 59728701403, max: 59729465969}
|
983
|
+
example question: Which third parties are having the largest impact on my page performance?
|
984
|
+
=== end content
|
985
|
+
|
986
|
+
Title: PerformanceTraceFormatter formatTraceSummary image-delivery.json.gz
|
987
|
+
Content:
|
988
|
+
URL: http://localhost/image-delivery-cases.html
|
989
|
+
Bounds: {min: 59728641874, max: 59734400108}
|
990
|
+
CPU throttling: 1x
|
991
|
+
Network throttling: No throttling
|
992
|
+
Metrics (lab / observed):
|
993
|
+
- LCP: 663 ms, event: (eventKey: r-14753, ts: 59729312744)
|
994
|
+
- LCP breakdown:
|
995
|
+
- TTFB: 7 ms, bounds: {min: 59728649746, max: 59728656735}
|
996
|
+
- Load delay: 45.6 ms, bounds: {min: 59728656735, max: 59728702313}
|
997
|
+
- Load duration: 506.3 ms, bounds: {min: 59728702313, max: 59729208600}
|
998
|
+
- Render delay: 104.1 ms, bounds: {min: 59729208600, max: 59729312744}
|
999
|
+
- CLS: 0.31, event: (eventKey: s--1, ts: 59729100192)
|
1000
|
+
Metrics (field / real users):
|
1001
|
+
- LCP: 1740 ms (scope: url)
|
1002
|
+
- INP: 185 ms (scope: url)
|
1003
|
+
- CLS: 0.08 (scope: url)
|
1004
|
+
- The above data is from CrUX–Chrome User Experience Report. It's how the page performs for real users.
|
1005
|
+
- The values shown above are the p75 measure of all real Chrome users
|
1006
|
+
- The scope indicates if the data came from the entire origin, or a specific url
|
1007
|
+
- Lab metrics describe how this specific page load performed, while field metrics are an aggregation of results from real-world users. Best practice is to prioritize metrics that are bad in field data. Lab metrics may be better or worse than fields metrics depending on the developer's machine, network, or the actions performed while tracing.
|
1008
|
+
Available insights:
|
1009
|
+
- insight name: Cache
|
1010
|
+
description: A long cache lifetime can speed up repeat visits to your page. [Learn more](https://web.dev/uses-long-cache-ttl/).
|
1011
|
+
relevant trace bounds: {min: 59728702014, max: 59728867430}
|
1012
|
+
estimated metric savings: FCP 0 ms, LCP 150 ms
|
1013
|
+
estimated wasted bytes: 971.5 kB
|
1014
|
+
example question: What caching strategies can I apply to improve my page performance?
|
1015
|
+
- insight name: ImageDelivery
|
1016
|
+
description: Reducing the download time of images can improve the perceived load time of the page and LCP. [Learn more about optimizing image size](https://developer.chrome.com/docs/lighthouse/performance/uses-optimized-images/)
|
1017
|
+
relevant trace bounds: {min: 59728701403, max: 59729395208}
|
1018
|
+
estimated metric savings: FCP 0 ms, LCP 100 ms
|
1019
|
+
estimated wasted bytes: 2 MB
|
1020
|
+
example question: What should I do to improve and optimize the time taken to fetch and display images on the page?
|
1021
|
+
example question: Are all images on my site optimized?
|
1022
|
+
- insight name: LCPBreakdown
|
1023
|
+
description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
|
1024
|
+
relevant trace bounds: {min: 59728649746, max: 59729312744}
|
1025
|
+
example question: Help me optimize my LCP score
|
1026
|
+
example question: Which LCP phase was most problematic?
|
1027
|
+
example question: What can I do to reduce the LCP time for this page load?
|
1028
|
+
- insight name: LCPDiscovery
|
1029
|
+
description: Optimize LCP by making the LCP image [discoverable](https://web.dev/articles/optimize-lcp#1_eliminate_resource_load_delay) from the HTML immediately, and [avoiding lazy-loading](https://web.dev/articles/lcp-lazy-loading)
|
1030
|
+
relevant trace bounds: {min: 59728656735, max: 59729209036}
|
1031
|
+
example question: Suggest fixes to reduce my LCP
|
1032
|
+
example question: What can I do to reduce my LCP discovery time?
|
1033
|
+
example question: Why is LCP discovery time important?
|
1034
|
+
- insight name: CLSCulprits
|
1035
|
+
description: Layout shifts occur when elements move absent any user interaction. [Investigate the causes of layout shifts](https://web.dev/articles/optimize-cls), such as elements being added, removed, or their fonts changing as the page loads.
|
1036
|
+
relevant trace bounds: {min: 59729100192, max: 59730317334}
|
1037
|
+
example question: Help me optimize my CLS score
|
1038
|
+
example question: How can I prevent layout shifts on this page?
|
1039
|
+
- insight name: DocumentLatency
|
1040
|
+
description: Your first network request is the most important. Reduce its latency by avoiding redirects, ensuring a fast server response, and enabling text compression.
|
1041
|
+
relevant trace bounds: {min: 59728651057, max: 59728790724}
|
1042
|
+
estimated metric savings: FCP 0 ms, LCP 0 ms
|
1043
|
+
estimated wasted bytes: 1.6 kB
|
1044
|
+
example question: How do I decrease the initial loading time of my page?
|
1045
|
+
example question: Did anything slow down the request for this document?
|
1046
|
+
- insight name: Viewport
|
1047
|
+
description: Tap interactions may be [delayed by up to 300 ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.
|
1048
|
+
relevant trace bounds: {min: 59728649746, max: 59734400108}
|
1049
|
+
estimated metric savings: INP 0 ms
|
1050
|
+
example question: How do I make sure my page is optimized for mobile viewing?
|
1051
|
+
- insight name: ThirdParties
|
1052
|
+
description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page's content.
|
1053
|
+
relevant trace bounds: {min: 59728701403, max: 59729465969}
|
1054
|
+
example question: Which third parties are having the largest impact on my page performance?
|
1055
|
+
=== end content
|
@@ -2,8 +2,11 @@
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
3
3
|
// found in the LICENSE file.
|
4
4
|
|
5
|
-
import * as
|
5
|
+
import * as CrUXManager from '../../crux-manager/crux-manager.js';
|
6
6
|
import * as Trace from '../../trace/trace.js';
|
7
|
+
import type {AICallTree} from '../performance/AICallTree.js';
|
8
|
+
import type {AgentFocus} from '../performance/AIContext.js';
|
9
|
+
import {AIQueries} from '../performance/AIQueries.js';
|
7
10
|
|
8
11
|
import {PerformanceInsightFormatter, TraceEventFormatter} from './PerformanceInsightFormatter.js';
|
9
12
|
import {bytes, micros, millis} from './UnitFormatters.js';
|
@@ -13,7 +16,7 @@ export class PerformanceTraceFormatter {
|
|
13
16
|
#insightSet: Trace.Insights.Types.InsightSet|null;
|
14
17
|
#eventsSerializer: Trace.EventsSerializer.EventsSerializer;
|
15
18
|
|
16
|
-
constructor(focus:
|
19
|
+
constructor(focus: AgentFocus, eventsSerializer: Trace.EventsSerializer.EventsSerializer) {
|
17
20
|
this.#parsedTrace = focus.data.parsedTrace;
|
18
21
|
this.#insightSet = focus.data.insightSet;
|
19
22
|
this.#eventsSerializer = eventsSerializer;
|
@@ -28,6 +31,81 @@ export class PerformanceTraceFormatter {
|
|
28
31
|
return `{min: ${bounds.min}, max: ${bounds.max}}`;
|
29
32
|
}
|
30
33
|
|
34
|
+
/**
|
35
|
+
* Fetching the Crux summary can error outside of DevTools, hence the
|
36
|
+
* try-catch around it here.
|
37
|
+
*/
|
38
|
+
#getCruxTraceSummary(insightSet: Trace.Insights.Types.InsightSet|null): string[] {
|
39
|
+
if (insightSet === null) {
|
40
|
+
return [];
|
41
|
+
}
|
42
|
+
try {
|
43
|
+
const cruxScope = CrUXManager.CrUXManager.instance().getSelectedScope();
|
44
|
+
const parts: string[] = [];
|
45
|
+
const fieldMetrics =
|
46
|
+
Trace.Insights.Common.getFieldMetricsForInsightSet(insightSet, this.#parsedTrace.metadata, cruxScope);
|
47
|
+
const fieldLcp = fieldMetrics?.lcp;
|
48
|
+
const fieldInp = fieldMetrics?.inp;
|
49
|
+
const fieldCls = fieldMetrics?.cls;
|
50
|
+
|
51
|
+
if (fieldLcp || fieldInp || fieldCls) {
|
52
|
+
parts.push('Metrics (field / real users):');
|
53
|
+
|
54
|
+
const serializeFieldMetricTimingResult =
|
55
|
+
(fieldMetric: Trace.Insights.Common.CrUXFieldMetricTimingResult): string => {
|
56
|
+
return `${Math.round(fieldMetric.value / 1000)} ms (scope: ${fieldMetric.pageScope})`;
|
57
|
+
};
|
58
|
+
|
59
|
+
const serializeFieldMetricNumberResult =
|
60
|
+
(fieldMetric: Trace.Insights.Common.CrUXFieldMetricNumberResult): string => {
|
61
|
+
return `${fieldMetric.value.toFixed(2)} (scope: ${fieldMetric.pageScope})`;
|
62
|
+
};
|
63
|
+
|
64
|
+
if (fieldLcp) {
|
65
|
+
parts.push(` - LCP: ${serializeFieldMetricTimingResult(fieldLcp)}`);
|
66
|
+
|
67
|
+
const fieldLcpBreakdown = fieldMetrics?.lcpBreakdown;
|
68
|
+
if (fieldLcpBreakdown &&
|
69
|
+
(fieldLcpBreakdown.ttfb || fieldLcpBreakdown.loadDelay || fieldLcpBreakdown.loadDuration ||
|
70
|
+
fieldLcpBreakdown.renderDelay)) {
|
71
|
+
parts.push(' - LCP breakdown:');
|
72
|
+
if (fieldLcpBreakdown.ttfb) {
|
73
|
+
parts.push(` - TTFB: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.ttfb)}`);
|
74
|
+
}
|
75
|
+
if (fieldLcpBreakdown.loadDelay) {
|
76
|
+
parts.push(` - Load delay: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.loadDelay)}`);
|
77
|
+
}
|
78
|
+
if (fieldLcpBreakdown.loadDuration) {
|
79
|
+
parts.push(` - Load duration: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.loadDuration)}`);
|
80
|
+
}
|
81
|
+
if (fieldLcpBreakdown.renderDelay) {
|
82
|
+
parts.push(` - Render delay: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.renderDelay)}`);
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
if (fieldInp) {
|
87
|
+
parts.push(` - INP: ${serializeFieldMetricTimingResult(fieldInp)}`);
|
88
|
+
}
|
89
|
+
if (fieldCls) {
|
90
|
+
parts.push(` - CLS: ${serializeFieldMetricNumberResult(fieldCls)}`);
|
91
|
+
}
|
92
|
+
|
93
|
+
parts.push(
|
94
|
+
' - The above data is from CrUX–Chrome User Experience Report. It\'s how the page performs for real users.');
|
95
|
+
parts.push(' - The values shown above are the p75 measure of all real Chrome users');
|
96
|
+
parts.push(' - The scope indicates if the data came from the entire origin, or a specific url');
|
97
|
+
parts.push(
|
98
|
+
' - Lab metrics describe how this specific page load performed, while field metrics are an aggregation ' +
|
99
|
+
'of results from real-world users. Best practice is to prioritize metrics that are bad in field data. ' +
|
100
|
+
'Lab metrics may be better or worse than fields metrics depending on the developer\'s machine, network, or the ' +
|
101
|
+
'actions performed while tracing.');
|
102
|
+
}
|
103
|
+
return parts;
|
104
|
+
} catch {
|
105
|
+
return [];
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
31
109
|
formatTraceSummary(): string {
|
32
110
|
const parsedTrace = this.#parsedTrace;
|
33
111
|
const insightSet = this.#insightSet;
|
@@ -45,7 +123,7 @@ export class PerformanceTraceFormatter {
|
|
45
123
|
parts.push('CPU throttling: ' + (traceMetadata.cpuThrottling ? `${traceMetadata.cpuThrottling}x` : 'none'));
|
46
124
|
parts.push(`Network throttling: ${traceMetadata.networkThrottling ?? 'none'}`);
|
47
125
|
if (lcp || cls || inp) {
|
48
|
-
parts.push('Metrics:');
|
126
|
+
parts.push('Metrics (lab / observed):');
|
49
127
|
if (lcp) {
|
50
128
|
parts.push(` - LCP: ${Math.round(lcp.value / 1000)} ms, event: ${this.serializeEvent(lcp.event)}`);
|
51
129
|
const subparts = insightSet?.model.LCPBreakdown.subparts;
|
@@ -53,6 +131,7 @@ export class PerformanceTraceFormatter {
|
|
53
131
|
const serializeSubpart = (subpart: Trace.Insights.Models.LCPBreakdown.Subpart): string => {
|
54
132
|
return `${micros(subpart.range)}, bounds: ${this.serializeBounds(subpart)}`;
|
55
133
|
};
|
134
|
+
parts.push(' - LCP breakdown:');
|
56
135
|
parts.push(` - TTFB: ${serializeSubpart(subparts.ttfb)}`);
|
57
136
|
if (subparts.loadDelay !== undefined) {
|
58
137
|
parts.push(` - Load delay: ${serializeSubpart(subparts.loadDelay)}`);
|
@@ -71,7 +150,14 @@ export class PerformanceTraceFormatter {
|
|
71
150
|
parts.push(` - CLS: ${cls.value.toFixed(2)}${eventText}`);
|
72
151
|
}
|
73
152
|
} else {
|
74
|
-
parts.push('Metrics: n/a');
|
153
|
+
parts.push('Metrics (lab / observed): n/a');
|
154
|
+
}
|
155
|
+
|
156
|
+
const cruxParts = insightSet && this.#getCruxTraceSummary(insightSet);
|
157
|
+
if (cruxParts?.length) {
|
158
|
+
parts.push(...cruxParts);
|
159
|
+
} else {
|
160
|
+
parts.push('Metrics (field / real users): n/a – no data for this page in CrUX');
|
75
161
|
}
|
76
162
|
|
77
163
|
if (insightSet) {
|
@@ -176,7 +262,7 @@ export class PerformanceTraceFormatter {
|
|
176
262
|
const insightSet = this.#insightSet;
|
177
263
|
|
178
264
|
const bounds = parsedTrace.data.Meta.traceBounds;
|
179
|
-
const rootNode =
|
265
|
+
const rootNode = AIQueries.mainThreadActivityBottomUp(
|
180
266
|
insightSet?.navigation?.args.data?.navigationId,
|
181
267
|
bounds,
|
182
268
|
parsedTrace,
|
@@ -229,8 +315,8 @@ export class PerformanceTraceFormatter {
|
|
229
315
|
const insightSet = this.#insightSet;
|
230
316
|
|
231
317
|
const bounds = parsedTrace.data.Meta.traceBounds;
|
232
|
-
const longestTaskTrees =
|
233
|
-
insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
|
318
|
+
const longestTaskTrees =
|
319
|
+
AIQueries.longestTasks(insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
|
234
320
|
if (!longestTaskTrees || longestTaskTrees.length === 0) {
|
235
321
|
return 'Longest tasks: none';
|
236
322
|
}
|
@@ -288,7 +374,7 @@ export class PerformanceTraceFormatter {
|
|
288
374
|
formatMainThreadTrackSummary(bounds: Trace.Types.Timing.TraceWindowMicro): string {
|
289
375
|
const results = [];
|
290
376
|
|
291
|
-
const topDownTree =
|
377
|
+
const topDownTree = AIQueries.mainThreadActivityTopDown(
|
292
378
|
this.#insightSet?.navigation?.args.data?.navigationId,
|
293
379
|
bounds,
|
294
380
|
this.#parsedTrace,
|
@@ -298,7 +384,7 @@ export class PerformanceTraceFormatter {
|
|
298
384
|
results.push(this.formatCallTree(topDownTree, 2 /* headerLevel */));
|
299
385
|
}
|
300
386
|
|
301
|
-
const bottomUpRootNode =
|
387
|
+
const bottomUpRootNode = AIQueries.mainThreadActivityBottomUp(
|
302
388
|
this.#insightSet?.navigation?.args.data?.navigationId,
|
303
389
|
bounds,
|
304
390
|
this.#parsedTrace,
|
@@ -349,7 +435,7 @@ export class PerformanceTraceFormatter {
|
|
349
435
|
return results.join('\n\n');
|
350
436
|
}
|
351
437
|
|
352
|
-
formatCallTree(tree:
|
438
|
+
formatCallTree(tree: AICallTree, headerLevel = 1): string {
|
353
439
|
const results = [tree.serialize(headerLevel), ''];
|
354
440
|
|
355
441
|
// TODO(b/425270067): add eventKey to tree.serialize, but need to wait for other
|