chrome-devtools-mcp-for-extension 0.19.2 → 0.20.0
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/build/node_modules/chrome-devtools-frontend/front_end/core/common/Color.js +13 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ColorConverter.js +9 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Console.js +1 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Debouncer.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Gzip.js +9 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/MapWithDefault.js +5 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ParsedURL.js +10 -20
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ResourceType.js +0 -11
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ReturnToPanel.js +6 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Revealer.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/SegmentedRange.js +1 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Settings.js +110 -99
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/StringOutputStream.js +1 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Throttler.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/common.js +1 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/AidaClient.js +21 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/DispatchHttpRequestClient.js +66 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/GdpClient.js +102 -86
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHost.js +32 -450
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHostAPI.js +32 -29
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHostStub.js +430 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/Platform.js +5 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/ResourceLoader.js +10 -22
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/UserMetrics.js +26 -15
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/host.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/ArrayUtilities.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/HostRuntime.js +19 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/StringUtilities.js +34 -32
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/api/HostRuntime.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/api/api.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/browser/HostRuntime.js +63 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/browser/browser.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/node/HostRuntime.js +72 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/node/node.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/platform.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/CDPConnection.js +17 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/ConnectionTransport.js +12 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/DevToolsCDPConnection.js +138 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/InspectorBackend.js +49 -312
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/protocol_client.js +4 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/root/DevToolsContext.js +54 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/root/root.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/AnimationModel.js +2 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CPUThrottlingManager.js +0 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMatchedStyles.js +51 -17
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMetadata.js +21 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSModel.js +11 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSProperty.js +4 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSPropertyParser.js +11 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSPropertyParserMatchers.js +34 -24
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSRule.js +52 -10
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSStartingStyle.js +21 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSStyleDeclaration.js +4 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ChildTargetManager.js +39 -35
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Connections.js +10 -47
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ConsoleModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Cookie.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DOMModel.js +29 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DebuggerModel.js +5 -20
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/EnhancedTracesParser.js +17 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/EventBreakpointsModel.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/HttpReasonPhraseStrings.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/IOModel.js +1 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkManager.js +428 -121
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkRequest.js +8 -22
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PageResourceLoader.js +44 -34
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PreloadingModel.js +64 -19
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RehydratingConnection.js +139 -12
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RemoteObject.js +5 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ResourceTreeModel.js +3 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ScopeTreeCache.js +36 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ScreenCaptureModel.js +20 -18
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Script.js +26 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ServerSentEventsProtocol.js +3 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMap.js +54 -14
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapCache.js +16 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapManager.js +19 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapScopesInfo.js +240 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Target.js +12 -17
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/TargetManager.js +38 -29
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/TraceObject.js +11 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/sdk-meta.js +80 -31
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/sdk.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/ARIAProperties.js +1301 -174
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/Deprecation.js +67 -22
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js +62 -91
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/SupportedCSSProperties.js +188 -100
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.js +30 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.js +50 -34
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.js +152 -101
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AICallTree.js +11 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIContext.js +25 -26
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIQueries.js +46 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CSSWorkspaceBinding.js +10 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CompilerScriptMapping.js +82 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DebuggerWorkspaceBinding.js +33 -15
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceMapping.js +105 -14
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceScriptMapping.js +38 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/SASSSourceMapping.js +5 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/cpu_profile/CPUProfileDataModel.js +9 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/models/cpu_profile/ProfileTreeModel.js +6 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/models/crux-manager/CrUXManager.js +6 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/FormatterWorkerPool.js +16 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/network_time_calculator/RequestTimeRanges.js +6 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/FunctionCodeResolver.js +192 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/NamesResolver.js +12 -16
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/source_map_scopes.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTraceModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/Trie.js +8 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/LanternComputationData.js +1 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/ModelImpl.js +6 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/Processor.js +4 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/Styles.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/TraceTree.js +11 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/FramesHandler.js +7 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/LayoutShiftsHandler.js +8 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/MetaHandler.js +4 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/NetworkRequestsHandler.js +29 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/SamplesHandler.js +59 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/ScriptsHandler.js +26 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/UserTimingsHandler.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/helpers.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Timing.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Trace.js +18 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/CLSCulprits.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/Cache.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DOMSize.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DocumentLatency.js +12 -11
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DuplicatedJavaScript.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/FontDisplay.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ForcedReflow.js +3 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/INPBreakdown.js +14 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ImageDelivery.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPBreakdown.js +13 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPDiscovery.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LegacyJavaScript.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ModernHTTP.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/NetworkDependencyTree.js +4 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/RenderBlocking.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/SlowCSSSelector.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ThirdParties.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/Viewport.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/types/TraceEvents.js +9 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace_source_maps_resolver/SourceMapsResolver.js +25 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/IgnoreListManager.js +41 -48
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/UISourceCode.js +38 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/WorkspaceImpl.js +5 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/workspace-meta.js +34 -0
- package/build/src/McpContext.js +8 -1
- package/build/src/tools/bookmarks.js +0 -1
- package/build/src/tools/gemini-web.js +17 -25
- package/build/src/tools/snapshot.js +9 -2
- package/package.json +3 -3
|
@@ -98,6 +98,9 @@ export function handleEvent(event) {
|
|
|
98
98
|
storeTraceEventWithRequestId(event.args.data.requestId, 'resourceMarkAsCached', event);
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
|
+
if (Types.Events.isPreloadRenderBlockingStatusChangeEvent(event)) {
|
|
102
|
+
storeTraceEventWithRequestId(event.args.data.requestId, 'preloadRenderBlockingStatusChange', [event]);
|
|
103
|
+
}
|
|
101
104
|
if (Types.Events.isWebSocketCreate(event) || Types.Events.isWebSocketInfo(event) ||
|
|
102
105
|
Types.Events.isWebSocketTransfer(event)) {
|
|
103
106
|
const identifier = event.args.data.identifier;
|
|
@@ -221,6 +224,7 @@ export async function finalize() {
|
|
|
221
224
|
*
|
|
222
225
|
* See `_updateTimingsForLightrider` in Lighthouse for more detail.
|
|
223
226
|
*/
|
|
227
|
+
let lrServerResponseTime;
|
|
224
228
|
if (isLightrider && request.receiveResponse?.args.data.headers) {
|
|
225
229
|
timing = {
|
|
226
230
|
requestTime: Helpers.Timing.microToSeconds(request.sendRequests.at(0)?.ts ?? 0),
|
|
@@ -254,6 +258,13 @@ export async function finalize() {
|
|
|
254
258
|
timing.connectEnd = TCPMs;
|
|
255
259
|
timing.sslEnd = TCPMs;
|
|
256
260
|
}
|
|
261
|
+
// Lightrider does not have any equivalent for `sendEnd` timing values. The
|
|
262
|
+
// closest we can get to the server response time is from a header that
|
|
263
|
+
// Lightrider sets.
|
|
264
|
+
const ResponseMsHeader = request.receiveResponse.args.data.headers.find(h => h.name === 'X-ResponseMs');
|
|
265
|
+
if (ResponseMsHeader) {
|
|
266
|
+
lrServerResponseTime = Math.max(0, parseInt(ResponseMsHeader.value, 10));
|
|
267
|
+
}
|
|
257
268
|
}
|
|
258
269
|
// TODO: consider allowing chrome / about.
|
|
259
270
|
const allowedProtocols = [
|
|
@@ -346,6 +357,13 @@ export async function finalize() {
|
|
|
346
357
|
const waiting = timing ?
|
|
347
358
|
Types.Timing.Micro((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS) :
|
|
348
359
|
Types.Timing.Micro(0);
|
|
360
|
+
// Server Response Time
|
|
361
|
+
// =======================
|
|
362
|
+
// Time from when the send finished going to when the first byte of headers were received.
|
|
363
|
+
const serverResponseTime = timing ?
|
|
364
|
+
Types.Timing.Micro(((timing.receiveHeadersStart ?? timing.receiveHeadersEnd) - timing.sendEnd) *
|
|
365
|
+
MILLISECONDS_TO_MICROSECONDS) :
|
|
366
|
+
Types.Timing.Micro(0);
|
|
349
367
|
// Download
|
|
350
368
|
// =======================
|
|
351
369
|
// Time from receipt of headers to the finish time.
|
|
@@ -372,11 +390,18 @@ export async function finalize() {
|
|
|
372
390
|
Types.Timing.Micro((timing.connectEnd - timing.connectStart) * MILLISECONDS_TO_MICROSECONDS) :
|
|
373
391
|
Types.Timing.Micro(0);
|
|
374
392
|
// Finally get some of the general data from the trace events.
|
|
375
|
-
const { frame, url, renderBlocking } = finalSendRequest.args.data;
|
|
393
|
+
const { frame, url, renderBlocking: sendRequestIsRenderBlocking } = finalSendRequest.args.data;
|
|
376
394
|
const { encodedDataLength, decodedBodyLength } = request.resourceFinish ? request.resourceFinish.args.data : { encodedDataLength: 0, decodedBodyLength: 0 };
|
|
377
395
|
const parsedUrl = new URL(url);
|
|
378
396
|
const isHttps = parsedUrl.protocol === 'https:';
|
|
379
397
|
const requestingFrameUrl = Helpers.Trace.activeURLForFrameAtTime(frame, finalSendRequest.ts, rendererProcessesByFrame) || '';
|
|
398
|
+
// A resource that is preloaded (and not marked as render blocking) can
|
|
399
|
+
// become render blocked later via a PreloadRenderBlockingStatusChange. In
|
|
400
|
+
// this case, we take the render blocking value of the last
|
|
401
|
+
// PreloadRenderBlockingStatusChange for this request.
|
|
402
|
+
const preloadRenderBlockingStatusChange = request.preloadRenderBlockingStatusChange?.at(-1)?.args.data.renderBlocking;
|
|
403
|
+
// In the event the property isn't set, assume non-blocking.
|
|
404
|
+
const isRenderBlocking = preloadRenderBlockingStatusChange ?? sendRequestIsRenderBlocking ?? 'non_blocking';
|
|
380
405
|
// Construct a synthetic trace event for this network request.
|
|
381
406
|
const networkEvent = Helpers.SyntheticEvents.SyntheticEventsManager.registerSyntheticEvent({
|
|
382
407
|
rawSourceEvent: finalSendRequest,
|
|
@@ -404,6 +429,7 @@ export async function finalize() {
|
|
|
404
429
|
stalled,
|
|
405
430
|
totalTime,
|
|
406
431
|
waiting,
|
|
432
|
+
serverResponseTime,
|
|
407
433
|
},
|
|
408
434
|
// All fields below are from TraceEventsForNetworkRequest.
|
|
409
435
|
decodedBodyLength,
|
|
@@ -416,8 +442,7 @@ export async function finalize() {
|
|
|
416
442
|
initialPriority,
|
|
417
443
|
protocol: request.receiveResponse?.args.data.protocol ?? 'unknown',
|
|
418
444
|
redirects,
|
|
419
|
-
|
|
420
|
-
renderBlocking: renderBlocking ?? 'non_blocking',
|
|
445
|
+
renderBlocking: isRenderBlocking,
|
|
421
446
|
requestId,
|
|
422
447
|
requestingFrameUrl,
|
|
423
448
|
requestMethod: finalSendRequest.args.data.requestMethod,
|
|
@@ -428,6 +453,7 @@ export async function finalize() {
|
|
|
428
453
|
initiator: finalSendRequest.args.data.initiator,
|
|
429
454
|
stackTrace: finalSendRequest.args.data.stackTrace,
|
|
430
455
|
timing,
|
|
456
|
+
lrServerResponseTime,
|
|
431
457
|
url,
|
|
432
458
|
failed: request.resourceFinish?.args.data.didFail ?? false,
|
|
433
459
|
finished: Boolean(request.resourceFinish),
|
|
@@ -17,23 +17,66 @@ let entryToNode = new Map();
|
|
|
17
17
|
// are matched by profile id, which we then finish processing to export
|
|
18
18
|
// events matched by thread id.
|
|
19
19
|
let preprocessedData = new Map();
|
|
20
|
+
/**
|
|
21
|
+
* Profile source selection priority when multiple profiles exist for the same thread.
|
|
22
|
+
*
|
|
23
|
+
* Profile sources and their typical scenarios:
|
|
24
|
+
* - 'Internal': Browser-initiated profiling performance panel traces.
|
|
25
|
+
* This is the profiling mechanism when users click "Record" in the Devtools UI.
|
|
26
|
+
* - 'Inspector': User-initiated via console.profile()/profileEnd() calls.
|
|
27
|
+
* Represents explicit developer intent to profile specific code.
|
|
28
|
+
* - 'SelfProfiling': Page-initiated via JS Self-Profiling API.
|
|
29
|
+
* Lower signal vs the two above; treated as fallback.
|
|
30
|
+
*
|
|
31
|
+
* Selection strategy:
|
|
32
|
+
* - CPU Profile mode: Prefer 'Inspector' (explicit user request).
|
|
33
|
+
* - Performance trace: Prefer 'Internal' (integrated timeline context), then 'Inspector'.
|
|
34
|
+
* - Sources not in the priority list (including 'SelfProfiling') act as fallbacks.
|
|
35
|
+
* When no priority source matches, the first candidate profile is selected.
|
|
36
|
+
*/
|
|
37
|
+
const PROFILE_SOURCES_BY_PRIORITY = {
|
|
38
|
+
cpuProfile: ['Inspector'],
|
|
39
|
+
performanceTrace: ['Internal', 'Inspector'],
|
|
40
|
+
};
|
|
20
41
|
function parseCPUProfileData(parseOptions) {
|
|
42
|
+
const priorityList = parseOptions.isCPUProfile ? PROFILE_SOURCES_BY_PRIORITY.cpuProfile : PROFILE_SOURCES_BY_PRIORITY.performanceTrace;
|
|
21
43
|
for (const [processId, profiles] of preprocessedData) {
|
|
44
|
+
const profilesByThread = new Map();
|
|
22
45
|
for (const [profileId, preProcessedData] of profiles) {
|
|
23
46
|
const threadId = preProcessedData.threadId;
|
|
24
|
-
if (
|
|
47
|
+
if (threadId === undefined) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const listForThread = Platform.MapUtilities.getWithDefault(profilesByThread, threadId, () => []);
|
|
51
|
+
listForThread.push({ id: profileId, data: preProcessedData });
|
|
52
|
+
}
|
|
53
|
+
for (const [threadId, candidates] of profilesByThread) {
|
|
54
|
+
if (!candidates.length) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
let chosen = candidates[0];
|
|
58
|
+
for (const source of priorityList) {
|
|
59
|
+
const match = candidates.find(p => p.data.source === source);
|
|
60
|
+
if (match) {
|
|
61
|
+
chosen = match;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const chosenData = chosen.data;
|
|
66
|
+
if (!chosenData.rawProfile.nodes.length) {
|
|
25
67
|
continue;
|
|
26
68
|
}
|
|
27
69
|
const indexStack = [];
|
|
28
|
-
const profileModel = new CPUProfile.CPUProfileDataModel.CPUProfileDataModel(
|
|
70
|
+
const profileModel = new CPUProfile.CPUProfileDataModel.CPUProfileDataModel(chosenData.rawProfile);
|
|
29
71
|
const profileTree = Helpers.TreeHelpers.makeEmptyTraceEntryTree();
|
|
30
72
|
profileTree.maxDepth = profileModel.maxDepth;
|
|
73
|
+
const selectedProfileId = chosen.id;
|
|
31
74
|
const finalizedData = {
|
|
32
|
-
rawProfile:
|
|
75
|
+
rawProfile: chosenData.rawProfile,
|
|
33
76
|
parsedProfile: profileModel,
|
|
34
77
|
profileCalls: [],
|
|
35
78
|
profileTree,
|
|
36
|
-
profileId,
|
|
79
|
+
profileId: selectedProfileId,
|
|
37
80
|
};
|
|
38
81
|
const dataByThread = Platform.MapUtilities.getWithDefault(profilesInProcess, processId, () => new Map());
|
|
39
82
|
dataByThread.set(threadId, finalizedData);
|
|
@@ -49,7 +92,7 @@ function parseCPUProfileData(parseOptions) {
|
|
|
49
92
|
}
|
|
50
93
|
const ts = Helpers.Timing.milliToMicro(Types.Timing.Milli(timeStampMilliseconds));
|
|
51
94
|
const nodeId = node.id;
|
|
52
|
-
const profileCall = Helpers.Trace.makeProfileCall(node,
|
|
95
|
+
const profileCall = Helpers.Trace.makeProfileCall(node, selectedProfileId, sampleIndex, ts, processId, threadId);
|
|
53
96
|
finalizedData.profileCalls.push(profileCall);
|
|
54
97
|
indexStack.push(finalizedData.profileCalls.length - 1);
|
|
55
98
|
const traceEntryNode = Helpers.TreeHelpers.makeEmptyTraceEntryNode(profileCall, nodeId);
|
|
@@ -68,7 +111,7 @@ function parseCPUProfileData(parseOptions) {
|
|
|
68
111
|
}
|
|
69
112
|
const { callFrame, ts, pid, tid } = profileCall;
|
|
70
113
|
const traceEntryNode = entryToNode.get(profileCall);
|
|
71
|
-
if (callFrame === undefined || ts === undefined || pid === undefined ||
|
|
114
|
+
if (callFrame === undefined || ts === undefined || pid === undefined || selectedProfileId === undefined ||
|
|
72
115
|
tid === undefined || traceEntryNode === undefined) {
|
|
73
116
|
return;
|
|
74
117
|
}
|
|
@@ -119,6 +162,7 @@ export function handleEvent(event) {
|
|
|
119
162
|
const profileData = getOrCreatePreProcessedData(event.pid, event.id);
|
|
120
163
|
profileData.rawProfile.startTime = event.ts;
|
|
121
164
|
profileData.threadId = event.tid;
|
|
165
|
+
assignProfileSourceIfKnown(profileData, event.args?.data?.source);
|
|
122
166
|
return;
|
|
123
167
|
}
|
|
124
168
|
if (Types.Events.isProfileChunk(event)) {
|
|
@@ -146,9 +190,11 @@ export function handleEvent(event) {
|
|
|
146
190
|
}
|
|
147
191
|
const timeDeltas = event.args.data?.timeDeltas || [];
|
|
148
192
|
const lines = event.args.data?.lines || Array(samples.length).fill(0);
|
|
193
|
+
const columns = event.args.data?.columns || Array(samples.length).fill(0);
|
|
149
194
|
cdpProfile.samples?.push(...samples);
|
|
150
195
|
cdpProfile.timeDeltas?.push(...timeDeltas);
|
|
151
196
|
cdpProfile.lines?.push(...lines);
|
|
197
|
+
cdpProfile.columns?.push(...columns);
|
|
152
198
|
if (traceIds) {
|
|
153
199
|
cdpProfile.traceIds ??= {};
|
|
154
200
|
for (const key in traceIds) {
|
|
@@ -163,12 +209,18 @@ export function handleEvent(event) {
|
|
|
163
209
|
const timeDeltas = cdpProfile.timeDeltas;
|
|
164
210
|
cdpProfile.endTime = timeDeltas.reduce((x, y) => x + y, cdpProfile.startTime);
|
|
165
211
|
}
|
|
212
|
+
assignProfileSourceIfKnown(profileData, event.args?.data?.source);
|
|
166
213
|
return;
|
|
167
214
|
}
|
|
168
215
|
}
|
|
169
216
|
export async function finalize(parseOptions = {}) {
|
|
170
217
|
parseCPUProfileData(parseOptions);
|
|
171
218
|
}
|
|
219
|
+
function assignProfileSourceIfKnown(profileData, source) {
|
|
220
|
+
if (Types.Events.VALID_PROFILE_SOURCES.includes(source)) {
|
|
221
|
+
profileData.source = source;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
172
224
|
export function data() {
|
|
173
225
|
return {
|
|
174
226
|
profilesInProcess,
|
|
@@ -185,6 +237,7 @@ function getOrCreatePreProcessedData(processId, profileId) {
|
|
|
185
237
|
samples: [],
|
|
186
238
|
timeDeltas: [],
|
|
187
239
|
lines: [],
|
|
240
|
+
columns: [],
|
|
188
241
|
},
|
|
189
242
|
profileId,
|
|
190
243
|
}));
|
|
@@ -7,17 +7,19 @@ import * as Types from '../types/types.js';
|
|
|
7
7
|
import { data as metaHandlerData } from './MetaHandler.js';
|
|
8
8
|
import { data as networkRequestsHandlerData } from './NetworkRequestsHandler.js';
|
|
9
9
|
let scriptById = new Map();
|
|
10
|
+
let frameIdByIsolate = new Map();
|
|
10
11
|
export function deps() {
|
|
11
12
|
return ['Meta', 'NetworkRequests'];
|
|
12
13
|
}
|
|
13
14
|
export function reset() {
|
|
14
15
|
scriptById = new Map();
|
|
16
|
+
frameIdByIsolate = new Map();
|
|
15
17
|
}
|
|
16
18
|
export function handleEvent(event) {
|
|
17
19
|
const getOrMakeScript = (isolate, scriptIdAsNumber) => {
|
|
18
20
|
const scriptId = String(scriptIdAsNumber);
|
|
19
21
|
const key = `${isolate}.${scriptId}`;
|
|
20
|
-
return Platform.MapUtilities.getWithDefault(scriptById, key, () => ({ isolate, scriptId, frame: '', ts:
|
|
22
|
+
return Platform.MapUtilities.getWithDefault(scriptById, key, () => ({ isolate, scriptId, frame: '', ts: event.ts }));
|
|
21
23
|
};
|
|
22
24
|
if (Types.Events.isRundownScriptCompiled(event) && event.args.data) {
|
|
23
25
|
const { isolate, scriptId, frame } = event.args.data;
|
|
@@ -29,7 +31,11 @@ export function handleEvent(event) {
|
|
|
29
31
|
if (Types.Events.isRundownScript(event)) {
|
|
30
32
|
const { isolate, scriptId, url, sourceUrl, sourceMapUrl, sourceMapUrlElided } = event.args.data;
|
|
31
33
|
const script = getOrMakeScript(isolate, scriptId);
|
|
34
|
+
if (!script.frame) {
|
|
35
|
+
script.frame = frameIdByIsolate.get(String(isolate)) ?? '';
|
|
36
|
+
}
|
|
32
37
|
script.url = url;
|
|
38
|
+
script.ts = event.ts;
|
|
33
39
|
if (sourceUrl) {
|
|
34
40
|
script.sourceUrl = sourceUrl;
|
|
35
41
|
}
|
|
@@ -58,6 +64,25 @@ export function handleEvent(event) {
|
|
|
58
64
|
script.content = (script.content ?? '') + sourceText;
|
|
59
65
|
return;
|
|
60
66
|
}
|
|
67
|
+
// Setup frameIdByIsolate, which is used only in the case that we are missing
|
|
68
|
+
// rundown events for a script. We won't get a frame association from the rundown
|
|
69
|
+
// events if the recording started only after the script was first compiled. In
|
|
70
|
+
// that scenario, derive the frame via the isolate / FunctionCall events.
|
|
71
|
+
// TODO: ideally, we put the frame on ScriptCatchup event. So much easier. This approach has some
|
|
72
|
+
// issues.
|
|
73
|
+
if (Types.Events.isFunctionCall(event) && event.args.data?.isolate && event.args.data.frame) {
|
|
74
|
+
const { isolate, frame } = event.args.data;
|
|
75
|
+
const existingValue = frameIdByIsolate.get(isolate);
|
|
76
|
+
if (existingValue !== frame) {
|
|
77
|
+
frameIdByIsolate.set(isolate, frame);
|
|
78
|
+
// Update the scripts we discovered but without knowing their frame.
|
|
79
|
+
for (const script of scriptById.values()) {
|
|
80
|
+
if (!script.frame && script.isolate === isolate) {
|
|
81
|
+
script.frame = frame;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
61
86
|
}
|
|
62
87
|
function findFrame(meta, frameId) {
|
|
63
88
|
for (const frames of meta.frameByProcessId?.values()) {
|
|
@@ -108,7 +108,7 @@ function getEventTrack(event) {
|
|
|
108
108
|
return undefined;
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
111
|
-
* Similar to the default {@
|
|
111
|
+
* Similar to the default {@link Helpers.Trace.eventTimeComparator}
|
|
112
112
|
* but with a twist:
|
|
113
113
|
* In case of equal start and end times, put the second event (within a
|
|
114
114
|
* track) first.
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/helpers.js
CHANGED
|
@@ -142,7 +142,7 @@ export function addEventToEntityMapping(event, entityMappings) {
|
|
|
142
142
|
}
|
|
143
143
|
entityMappings.entityByEvent.set(event, entity);
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
/** A slight upgrade of addEventToEntityMapping to handle the sub-events of a network request. **/
|
|
146
146
|
export function addNetworkRequestToEntityMapping(networkRequest, entityMappings, requestTraceEvents) {
|
|
147
147
|
const entity = getEntityForEvent(networkRequest, entityMappings);
|
|
148
148
|
if (!entity) {
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Timing.js
CHANGED
|
@@ -25,8 +25,10 @@ export function timeStampForEventAdjustedByClosestNavigation(event, traceBounds,
|
|
|
25
25
|
}
|
|
26
26
|
return Types.Timing.Micro(eventTimeStamp);
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Expands the trace window by a provided percentage or, if it the expanded window is smaller than 1 millisecond, expands it to 1 millisecond.
|
|
30
|
+
* If the expanded window is outside of the max trace window, cut the overflowing bound to the max trace window bound.
|
|
31
|
+
**/
|
|
30
32
|
export function expandWindowByPercentOrToOneMillisecond(annotationWindow, maxTraceWindow, percentage) {
|
|
31
33
|
// Expand min and max of the window by half of the provided percentage. That way, in total, the window will be expanded by the provided percentage.
|
|
32
34
|
let newMin = annotationWindow.min - annotationWindow.range * (percentage / 100) / 2;
|
|
@@ -70,8 +70,10 @@ export function extractOriginFromTrace(firstNavigationURL) {
|
|
|
70
70
|
}
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Each thread contains events. Events indicate the thread and process IDs, which are
|
|
75
|
+
* used to store the event in the correct process thread entry below.
|
|
76
|
+
**/
|
|
75
77
|
export function addEventToProcessThread(event, eventsInProcessThread) {
|
|
76
78
|
const { tid, pid } = event;
|
|
77
79
|
let eventsInThread = eventsInProcessThread.get(pid);
|
|
@@ -500,6 +502,16 @@ export function getStackTraceTopCallFrameInEventPayload(event) {
|
|
|
500
502
|
}
|
|
501
503
|
}
|
|
502
504
|
}
|
|
505
|
+
export function rawCallFrameForEntry(entry) {
|
|
506
|
+
if (Types.Events.isProfileCall(entry)) {
|
|
507
|
+
return entry.callFrame;
|
|
508
|
+
}
|
|
509
|
+
const topCallFrame = getStackTraceTopCallFrameInEventPayload(entry);
|
|
510
|
+
if (topCallFrame) {
|
|
511
|
+
return topCallFrame;
|
|
512
|
+
}
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
503
515
|
/**
|
|
504
516
|
* Given a 1-based call frame creates a 0-based one.
|
|
505
517
|
*/
|
|
@@ -704,8 +716,10 @@ export function extractSampleTraceId(event) {
|
|
|
704
716
|
}
|
|
705
717
|
return event.args?.sampleTraceId ?? event.args?.data?.sampleTraceId ?? null;
|
|
706
718
|
}
|
|
707
|
-
|
|
708
|
-
|
|
719
|
+
/**
|
|
720
|
+
* This exactly matches Trace.Styles.visibleTypes. See the runtime verification in maybeInitStylesMap.
|
|
721
|
+
* TODO(crbug.com/410884528)
|
|
722
|
+
**/
|
|
709
723
|
export const VISIBLE_TRACE_EVENT_TYPES = new Set([
|
|
710
724
|
"AbortPostTaskCallback" /* Types.Events.Name.ABORT_POST_TASK_CALLBACK */,
|
|
711
725
|
"Animation" /* Types.Events.Name.ANIMATION */,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/CLSCulprits.js
CHANGED
|
@@ -14,7 +14,7 @@ export const UIStrings = {
|
|
|
14
14
|
* @description Description of a DevTools insight that identifies the reasons that elements shift on the page.
|
|
15
15
|
* This is displayed after a user expands the section to see more. No character length limits.
|
|
16
16
|
*/
|
|
17
|
-
description: 'Layout shifts occur when elements move absent any user interaction. [Investigate the causes of layout shifts](https://
|
|
17
|
+
description: 'Layout shifts occur when elements move absent any user interaction. [Investigate the causes of layout shifts](https://developer.chrome.com/docs/performance/insights/cls-culprit), such as elements being added, removed, or their fonts changing as the page loads.',
|
|
18
18
|
/**
|
|
19
19
|
* @description Text indicating the worst layout shift cluster.
|
|
20
20
|
*/
|
|
@@ -417,6 +417,7 @@ function finalize(partialModel) {
|
|
|
417
417
|
strings: UIStrings,
|
|
418
418
|
title: i18nString(UIStrings.title),
|
|
419
419
|
description: i18nString(UIStrings.description),
|
|
420
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/cls-culprit',
|
|
420
421
|
category: InsightCategory.CLS,
|
|
421
422
|
state,
|
|
422
423
|
...partialModel,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/Cache.js
CHANGED
|
@@ -14,7 +14,7 @@ export const UIStrings = {
|
|
|
14
14
|
/**
|
|
15
15
|
* @description Text to tell the user about how caching can help improve performance.
|
|
16
16
|
*/
|
|
17
|
-
description: 'A long cache lifetime can speed up repeat visits to your page. [Learn more](https://
|
|
17
|
+
description: 'A long cache lifetime can speed up repeat visits to your page. [Learn more about caching](https://developer.chrome.com/docs/performance/insights/cache).',
|
|
18
18
|
/**
|
|
19
19
|
* @description Column for a font loaded by the page to render text.
|
|
20
20
|
*/
|
|
@@ -43,6 +43,7 @@ function finalize(partialModel) {
|
|
|
43
43
|
strings: UIStrings,
|
|
44
44
|
title: i18nString(UIStrings.title),
|
|
45
45
|
description: i18nString(UIStrings.description),
|
|
46
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/cache',
|
|
46
47
|
category: InsightCategory.ALL,
|
|
47
48
|
state: partialModel.requests.length > 0 ? 'fail' : 'pass',
|
|
48
49
|
...partialModel,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DOMSize.js
CHANGED
|
@@ -14,7 +14,7 @@ export const UIStrings = {
|
|
|
14
14
|
/**
|
|
15
15
|
* @description Description of an insight that recommends reducing the size of the DOM tree as a means to improve page responsiveness. "DOM" is an acronym and should not be translated. "layout reflows" are when the browser will recompute the layout of content on the page.
|
|
16
16
|
*/
|
|
17
|
-
description: 'A large DOM can increase the duration of style calculations and layout reflows, impacting page responsiveness. A large DOM will also increase memory usage. [Learn how to avoid an excessive DOM size](https://developer.chrome.com/docs/
|
|
17
|
+
description: 'A large DOM can increase the duration of style calculations and layout reflows, impacting page responsiveness. A large DOM will also increase memory usage. [Learn how to avoid an excessive DOM size](https://developer.chrome.com/docs/performance/insights/dom-size).',
|
|
18
18
|
/**
|
|
19
19
|
* @description Header for a column containing the names of statistics as opposed to the actual statistic values.
|
|
20
20
|
*/
|
|
@@ -73,6 +73,7 @@ function finalize(partialModel) {
|
|
|
73
73
|
strings: UIStrings,
|
|
74
74
|
title: i18nString(UIStrings.title),
|
|
75
75
|
description: i18nString(UIStrings.description),
|
|
76
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/dom-size',
|
|
76
77
|
category: InsightCategory.INP,
|
|
77
78
|
state: relatedEvents.length > 0 ? 'informative' : 'pass',
|
|
78
79
|
...partialModel,
|
|
@@ -14,7 +14,7 @@ export const UIStrings = {
|
|
|
14
14
|
/**
|
|
15
15
|
* @description Description of an insight that provides a breakdown for how long it took to download the main document.
|
|
16
16
|
*/
|
|
17
|
-
description: 'Your first network request is the most important.
|
|
17
|
+
description: 'Your first network request is the most important. [Reduce its latency](https://developer.chrome.com/docs/performance/insights/document-latency) by avoiding redirects, ensuring a fast server response, and enabling text compression.',
|
|
18
18
|
/**
|
|
19
19
|
* @description Text to tell the user that the document request does not have redirects.
|
|
20
20
|
*/
|
|
@@ -67,20 +67,20 @@ const IGNORE_THRESHOLD_IN_BYTES = 1400;
|
|
|
67
67
|
export function isDocumentLatencyInsight(x) {
|
|
68
68
|
return x.insightKey === 'DocumentLatency';
|
|
69
69
|
}
|
|
70
|
-
function getServerResponseTime(request
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
return
|
|
70
|
+
function getServerResponseTime(request) {
|
|
71
|
+
// For technical reasons, Lightrider does not have `sendEnd` timing values. The
|
|
72
|
+
// closest we can get to the server response time is from a header that Lightrider
|
|
73
|
+
// sets.
|
|
74
|
+
// @ts-expect-error
|
|
75
|
+
const isLightrider = globalThis.isLightrider;
|
|
76
|
+
if (isLightrider) {
|
|
77
|
+
return request.args.data.lrServerResponseTime ?? null;
|
|
78
78
|
}
|
|
79
79
|
const timing = request.args.data.timing;
|
|
80
80
|
if (!timing) {
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
83
|
-
const ms = Helpers.Timing.microToMilli(request.args.data.syntheticData.
|
|
83
|
+
const ms = Helpers.Timing.microToMilli(request.args.data.syntheticData.serverResponseTime);
|
|
84
84
|
return Math.round(ms);
|
|
85
85
|
}
|
|
86
86
|
function getCompressionSavings(request) {
|
|
@@ -148,6 +148,7 @@ function finalize(partialModel) {
|
|
|
148
148
|
strings: UIStrings,
|
|
149
149
|
title: i18nString(UIStrings.title),
|
|
150
150
|
description: i18nString(UIStrings.description),
|
|
151
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/document-latency',
|
|
151
152
|
category: InsightCategory.ALL,
|
|
152
153
|
state: hasFailure ? 'fail' : 'pass',
|
|
153
154
|
...partialModel,
|
|
@@ -162,7 +163,7 @@ export function generateInsight(data, context) {
|
|
|
162
163
|
if (!documentRequest) {
|
|
163
164
|
return finalize({ warnings: [InsightWarning.NO_DOCUMENT_REQUEST] });
|
|
164
165
|
}
|
|
165
|
-
const serverResponseTime = getServerResponseTime(documentRequest
|
|
166
|
+
const serverResponseTime = getServerResponseTime(documentRequest);
|
|
166
167
|
if (serverResponseTime === null) {
|
|
167
168
|
throw new Error('missing document request timing');
|
|
168
169
|
}
|
|
@@ -14,7 +14,7 @@ export const UIStrings = {
|
|
|
14
14
|
/**
|
|
15
15
|
* @description Description of an insight that identifies multiple copies of the same JavaScript sources, and recommends removing the duplication.
|
|
16
16
|
*/
|
|
17
|
-
description: 'Remove large, duplicate JavaScript modules from bundles to reduce unnecessary bytes consumed by network activity.',
|
|
17
|
+
description: 'Remove large, [duplicate JavaScript modules](https://developer.chrome.com/docs/performance/insights/duplicated-javascript) from bundles to reduce unnecessary bytes consumed by network activity.',
|
|
18
18
|
/** Label for a column in a data table; entries will be the locations of JavaScript or CSS code, e.g. the name of a Javascript package or module. */
|
|
19
19
|
columnSource: 'Source',
|
|
20
20
|
/** Label for a column in a data table; entries will be the number of wasted bytes due to duplication of a web resource. */
|
|
@@ -29,6 +29,7 @@ function finalize(partialModel) {
|
|
|
29
29
|
strings: UIStrings,
|
|
30
30
|
title: i18nString(UIStrings.title),
|
|
31
31
|
description: i18nString(UIStrings.description),
|
|
32
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/duplicated-javascript',
|
|
32
33
|
category: InsightCategory.LCP,
|
|
33
34
|
state: Boolean(partialModel.duplication.values().next().value) ? 'fail' : 'pass',
|
|
34
35
|
relatedEvents: [...new Set(requests)],
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/FontDisplay.js
CHANGED
|
@@ -12,7 +12,7 @@ export const UIStrings = {
|
|
|
12
12
|
/**
|
|
13
13
|
* @description Text to tell the user about the font-display CSS feature to help improve a the UX of a page.
|
|
14
14
|
*/
|
|
15
|
-
description: 'Consider setting [`font-display`](https://developer.chrome.com/
|
|
15
|
+
description: 'Consider setting [`font-display`](https://developer.chrome.com/docs/performance/insights/font-display) to `swap` or `optional` to ensure text is consistently visible. `swap` can be further optimized to mitigate layout shifts with [font metric overrides](https://developer.chrome.com/blog/font-fallbacks).',
|
|
16
16
|
/** Column for a font loaded by the page to render text. */
|
|
17
17
|
fontColumn: 'Font',
|
|
18
18
|
/** Column for the amount of time wasted. */
|
|
@@ -26,6 +26,7 @@ function finalize(partialModel) {
|
|
|
26
26
|
strings: UIStrings,
|
|
27
27
|
title: i18nString(UIStrings.title),
|
|
28
28
|
description: i18nString(UIStrings.description),
|
|
29
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/font-display',
|
|
29
30
|
category: InsightCategory.INP,
|
|
30
31
|
state: partialModel.fonts.find(font => font.wastedTime > 0) ? 'fail' : 'pass',
|
|
31
32
|
...partialModel,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ForcedReflow.js
CHANGED
|
@@ -15,11 +15,11 @@ export const UIStrings = {
|
|
|
15
15
|
/**
|
|
16
16
|
* @description Text to describe the forced reflow.
|
|
17
17
|
*/
|
|
18
|
-
description: 'A forced reflow occurs when JavaScript queries geometric properties (such as `offsetWidth`) after styles have been invalidated by a change to the DOM state. This can result in poor performance. Learn more about [forced reflows](https://
|
|
18
|
+
description: 'A forced reflow occurs when JavaScript queries geometric properties (such as `offsetWidth`) after styles have been invalidated by a change to the DOM state. This can result in poor performance. Learn more about [forced reflows](https://developer.chrome.com/docs/performance/insights/forced-reflow) and possible mitigations.',
|
|
19
19
|
/**
|
|
20
20
|
* @description Title of a list to provide related stack trace data
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
reflowCallFrames: 'Call frames that trigger reflow',
|
|
23
23
|
/**
|
|
24
24
|
* @description Text to describe the top time-consuming function call
|
|
25
25
|
*/
|
|
@@ -100,6 +100,7 @@ function finalize(partialModel) {
|
|
|
100
100
|
strings: UIStrings,
|
|
101
101
|
title: i18nString(UIStrings.title),
|
|
102
102
|
description: i18nString(UIStrings.description),
|
|
103
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/forced-reflow',
|
|
103
104
|
category: InsightCategory.ALL,
|
|
104
105
|
state: partialModel.aggregatedBottomUpData.length !== 0 ? 'fail' : 'pass',
|
|
105
106
|
...partialModel,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/INPBreakdown.js
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
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
|
import * as i18n from '../../../core/i18n/i18n.js';
|
|
5
|
+
import * as Handlers from '../handlers/handlers.js';
|
|
5
6
|
import * as Helpers from '../helpers/helpers.js';
|
|
6
7
|
import { InsightCategory, } from './types.js';
|
|
7
8
|
export const UIStrings = {
|
|
8
9
|
/**
|
|
9
10
|
* @description Text to tell the user about the longest user interaction.
|
|
10
11
|
*/
|
|
11
|
-
description: 'Start investigating
|
|
12
|
+
description: 'Start investigating [how to improve INP](https://developer.chrome.com/docs/performance/insights/inp-breakdown) by looking at the longest subpart.',
|
|
12
13
|
/**
|
|
13
14
|
* @description Title for the performance insight "INP breakdown", which shows a breakdown of INP by subparts / sections.
|
|
14
15
|
*/
|
|
@@ -45,13 +46,24 @@ export function isINPBreakdownInsight(insight) {
|
|
|
45
46
|
return insight.insightKey === "INPBreakdown" /* InsightKeys.INP_BREAKDOWN */;
|
|
46
47
|
}
|
|
47
48
|
function finalize(partialModel) {
|
|
49
|
+
let state = 'pass';
|
|
50
|
+
if (partialModel.longestInteractionEvent) {
|
|
51
|
+
const classification = Handlers.ModelHandlers.UserInteractions.scoreClassificationForInteractionToNextPaint(partialModel.longestInteractionEvent.dur);
|
|
52
|
+
if (classification === "good" /* Handlers.ModelHandlers.PageLoadMetrics.ScoreClassification.GOOD */) {
|
|
53
|
+
state = 'informative';
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
state = 'fail';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
48
59
|
return {
|
|
49
60
|
insightKey: "INPBreakdown" /* InsightKeys.INP_BREAKDOWN */,
|
|
50
61
|
strings: UIStrings,
|
|
51
62
|
title: i18nString(UIStrings.title),
|
|
52
63
|
description: i18nString(UIStrings.description),
|
|
64
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/inp-breakdown',
|
|
53
65
|
category: InsightCategory.INP,
|
|
54
|
-
state
|
|
66
|
+
state,
|
|
55
67
|
...partialModel,
|
|
56
68
|
};
|
|
57
69
|
}
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ImageDelivery.js
CHANGED
|
@@ -13,7 +13,7 @@ export const UIStrings = {
|
|
|
13
13
|
/**
|
|
14
14
|
* @description Description of an insight that recommends ways to reduce the size of images downloaded and used on the page.
|
|
15
15
|
*/
|
|
16
|
-
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/
|
|
16
|
+
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/performance/insights/image-delivery)',
|
|
17
17
|
/**
|
|
18
18
|
* @description Message displayed in a chip explaining that an image file size is large for the # of pixels it has and recommends possible adjustments to improve the image size.
|
|
19
19
|
*/
|
|
@@ -114,6 +114,7 @@ function finalize(partialModel) {
|
|
|
114
114
|
strings: UIStrings,
|
|
115
115
|
title: i18nString(UIStrings.title),
|
|
116
116
|
description: i18nString(UIStrings.description),
|
|
117
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/image-delivery',
|
|
117
118
|
category: InsightCategory.LCP,
|
|
118
119
|
state: partialModel.optimizableImages.length > 0 ? 'fail' : 'pass',
|
|
119
120
|
...partialModel,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPBreakdown.js
CHANGED
|
@@ -16,7 +16,7 @@ export const UIStrings = {
|
|
|
16
16
|
* @description Description of a DevTools insight that presents a breakdown for the LCP metric by subparts.
|
|
17
17
|
* This is displayed after a user expands the section to see more. No character length limits.
|
|
18
18
|
*/
|
|
19
|
-
description: 'Each [subpart has specific improvement strategies](https://
|
|
19
|
+
description: 'Each [subpart has specific improvement strategies](https://developer.chrome.com/docs/performance/insights/lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.',
|
|
20
20
|
/**
|
|
21
21
|
* @description Time to first byte title for the Largest Contentful Paint's subparts timespan breakdown.
|
|
22
22
|
*/
|
|
@@ -124,13 +124,24 @@ function finalize(partialModel) {
|
|
|
124
124
|
if (partialModel.lcpRequest) {
|
|
125
125
|
relatedEvents.push(partialModel.lcpRequest);
|
|
126
126
|
}
|
|
127
|
+
let state = 'pass';
|
|
128
|
+
if (partialModel.lcpMs !== undefined) {
|
|
129
|
+
const classification = Handlers.ModelHandlers.PageLoadMetrics.scoreClassificationForLargestContentfulPaint(Helpers.Timing.milliToMicro(partialModel.lcpMs));
|
|
130
|
+
if (classification === "good" /* Handlers.ModelHandlers.PageLoadMetrics.ScoreClassification.GOOD */) {
|
|
131
|
+
state = 'informative';
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
state = 'fail';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
127
137
|
return {
|
|
128
138
|
insightKey: "LCPBreakdown" /* InsightKeys.LCP_BREAKDOWN */,
|
|
129
139
|
strings: UIStrings,
|
|
130
140
|
title: i18nString(UIStrings.title),
|
|
131
141
|
description: i18nString(UIStrings.description),
|
|
142
|
+
docs: 'https://developer.chrome.com/docs/performance/insights/lcp-breakdown',
|
|
132
143
|
category: InsightCategory.LCP,
|
|
133
|
-
state
|
|
144
|
+
state,
|
|
134
145
|
...partialModel,
|
|
135
146
|
relatedEvents,
|
|
136
147
|
};
|