@paulirish/trace_engine 0.0.22 → 0.0.24
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/generated/protocol.d.ts +60 -4
- package/models/trace/EntriesFilter.d.ts +14 -13
- package/models/trace/EntriesFilter.js +40 -38
- package/models/trace/EntriesFilter.js.map +1 -1
- package/models/trace/ModelImpl.d.ts +6 -4
- package/models/trace/ModelImpl.js +13 -4
- package/models/trace/ModelImpl.js.map +1 -1
- package/models/trace/Processor.js +6 -1
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/TracingManager.js.map +1 -1
- package/models/trace/extras/FetchNodes.js +1 -1
- package/models/trace/extras/FetchNodes.js.map +1 -1
- package/models/trace/extras/URLForEntry.d.ts +4 -0
- package/models/trace/extras/URLForEntry.js +35 -0
- package/models/trace/extras/URLForEntry.js.map +1 -0
- package/models/trace/extras/extras-tsconfig.json +1 -0
- package/models/trace/extras/extras.js.map +1 -1
- package/models/trace/handlers/AuctionWorkletsHandler.js +5 -2
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.js +18 -5
- package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
- package/models/trace/handlers/InitiatorsHandler.js +1 -12
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
- package/models/trace/handlers/LayoutShiftsHandler.d.ts +1 -0
- package/models/trace/handlers/LayoutShiftsHandler.js +11 -2
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.js +6 -4
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.js +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
- package/models/trace/handlers/RendererHandler.d.ts +1 -0
- package/models/trace/handlers/RendererHandler.js +2 -0
- package/models/trace/handlers/RendererHandler.js.map +1 -1
- package/models/trace/handlers/ScreenshotsHandler.js +4 -2
- package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
- package/models/trace/handlers/UserInteractionsHandler.js +4 -2
- package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
- package/models/trace/helpers/Extensions.js +4 -0
- package/models/trace/helpers/Extensions.js.map +1 -1
- package/models/trace/helpers/SyntheticEvents.d.ts +30 -0
- package/models/trace/helpers/SyntheticEvents.js +87 -0
- package/models/trace/helpers/SyntheticEvents.js.map +1 -0
- package/models/trace/helpers/Trace.d.ts +2 -0
- package/models/trace/helpers/Trace.js +23 -3
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/helpers/TreeHelpers.d.ts +20 -0
- package/models/trace/helpers/TreeHelpers.js +50 -0
- package/models/trace/helpers/TreeHelpers.js.map +1 -1
- package/models/trace/helpers/helpers-tsconfig.json +1 -0
- package/models/trace/helpers/helpers.d.ts +1 -0
- package/models/trace/helpers/helpers.js +1 -0
- package/models/trace/helpers/helpers.js.map +1 -1
- package/models/trace/insights/CumulativeLayoutShift.d.ts +7 -2
- package/models/trace/insights/CumulativeLayoutShift.js +130 -2
- package/models/trace/insights/CumulativeLayoutShift.js.map +1 -1
- package/models/trace/insights/RenderBlocking.js +14 -0
- package/models/trace/insights/RenderBlocking.js.map +1 -1
- package/models/trace/trace-tsconfig.json +0 -1
- package/models/trace/trace.d.ts +1 -2
- package/models/trace/trace.js +1 -4
- package/models/trace/trace.js.map +1 -1
- package/models/trace/types/File.d.ts +11 -6
- package/models/trace/types/File.js +0 -3
- package/models/trace/types/File.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +104 -10
- package/models/trace/types/TraceEvents.js +46 -2
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// Copyright 2024 The Chromium Authors. All rights reserved.
|
|
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
|
+
import * as Platform from '../../../core/platform/platform.js';
|
|
4
5
|
import * as Helpers from '../helpers/helpers.js';
|
|
6
|
+
import * as Types from '../types/types.js';
|
|
5
7
|
export function deps() {
|
|
6
|
-
return ['Meta', 'Animations'];
|
|
8
|
+
return ['Meta', 'Animations', 'LayoutShifts', 'NetworkRequests'];
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Each failure reason is represented by a bit flag. The bit shift operator '<<' is used to define
|
|
@@ -37,6 +39,13 @@ const ACTIONABLE_FAILURE_REASONS = [
|
|
|
37
39
|
failure: "UNSUPPORTED_TIMING_PARAMS" /* AnimationFailureReasons.UNSUPPORTED_TIMING_PARAMS */,
|
|
38
40
|
},
|
|
39
41
|
];
|
|
42
|
+
// 500ms window.
|
|
43
|
+
// Use this window to consider events and requests that may have caused a layout shift.
|
|
44
|
+
const INVALIDATION_WINDOW = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(0.5));
|
|
45
|
+
function isInInvalidationWindow(event, targetEvent) {
|
|
46
|
+
const eventEnd = event.dur ? event.ts + event.dur : event.ts;
|
|
47
|
+
return eventEnd < targetEvent.ts && eventEnd >= targetEvent.ts - INVALIDATION_WINDOW;
|
|
48
|
+
}
|
|
40
49
|
/**
|
|
41
50
|
* Returns a list of NoncompositedAnimationFailures.
|
|
42
51
|
*/
|
|
@@ -68,14 +77,133 @@ function getNonCompositedAnimations(animations) {
|
|
|
68
77
|
}
|
|
69
78
|
return failures;
|
|
70
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Given an array of layout shift and PrePaint events, returns a mapping from
|
|
82
|
+
* PrePaint events to layout shifts dispatched within it.
|
|
83
|
+
*/
|
|
84
|
+
function getShiftsByPrePaintEvents(layoutShifts, prePaintEvents) {
|
|
85
|
+
// Maps from PrePaint events to LayoutShifts that occured in each one.
|
|
86
|
+
const shiftsByPrePaint = new Map();
|
|
87
|
+
// Associate all shifts to their corresponding PrePaint.
|
|
88
|
+
for (const prePaintEvent of prePaintEvents) {
|
|
89
|
+
const firstShiftIndex = Platform.ArrayUtilities.nearestIndexFromBeginning(layoutShifts, shift => shift.ts >= prePaintEvent.ts);
|
|
90
|
+
if (firstShiftIndex === null) {
|
|
91
|
+
// No layout shifts registered after this PrePaint start. Continue.
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
for (let i = firstShiftIndex; i < layoutShifts.length; i++) {
|
|
95
|
+
const shift = layoutShifts[i];
|
|
96
|
+
if (shift.ts >= prePaintEvent.ts && shift.ts <= prePaintEvent.ts + prePaintEvent.dur) {
|
|
97
|
+
const shiftsInPrePaint = Platform.MapUtilities.getWithDefault(shiftsByPrePaint, prePaintEvent, () => []);
|
|
98
|
+
shiftsInPrePaint.push(shift);
|
|
99
|
+
}
|
|
100
|
+
if (shift.ts > prePaintEvent.ts + prePaintEvent.dur) {
|
|
101
|
+
// Reached all layoutShifts of this PrePaint. Break out to continue with the next prePaint event.
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return shiftsByPrePaint;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* This gets the first prePaint event that follows the provided event and returns it.
|
|
110
|
+
*/
|
|
111
|
+
function getNextPrePaintEvent(prePaintEvents, targetEvent) {
|
|
112
|
+
// Get the first PrePaint event that happened after the targetEvent.
|
|
113
|
+
const nextPrePaintIndex = Platform.ArrayUtilities.nearestIndexFromBeginning(prePaintEvents, prePaint => prePaint.ts > targetEvent.ts + (targetEvent.dur || 0));
|
|
114
|
+
// No PrePaint event registered after this event
|
|
115
|
+
if (nextPrePaintIndex === null) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
return prePaintEvents[nextPrePaintIndex];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* An Iframe is considered a root cause if the iframe event occurs before a prePaint event
|
|
122
|
+
* and within this prePaint event a layout shift(s) occurs.
|
|
123
|
+
*/
|
|
124
|
+
function getIframeRootCauses(iframeCreatedEvents, prePaintEvents, shiftsByPrePaint, rootCausesByShift) {
|
|
125
|
+
for (const iframeEvent of iframeCreatedEvents) {
|
|
126
|
+
const nextPrePaint = getNextPrePaintEvent(prePaintEvents, iframeEvent);
|
|
127
|
+
// If no following prePaint, this is not a root cause.
|
|
128
|
+
if (!nextPrePaint) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const shifts = shiftsByPrePaint.get(nextPrePaint);
|
|
132
|
+
// if no layout shift(s), this is not a root cause.
|
|
133
|
+
if (!shifts) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
for (const shift of shifts) {
|
|
137
|
+
const rootCausesForShift = Platform.MapUtilities.getWithDefault(rootCausesByShift, shift, () => {
|
|
138
|
+
return {
|
|
139
|
+
iframes: [],
|
|
140
|
+
fontRequests: [],
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
rootCausesForShift.iframes.push(iframeEvent);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return rootCausesByShift;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* A font request is considered a root cause if the request occurs before a prePaint event
|
|
150
|
+
* and within this prePaint event a layout shift(s) occurs. Additionally, this font request should
|
|
151
|
+
* happen within the INVALIDATION_WINDOW of the prePaint event.
|
|
152
|
+
*/
|
|
153
|
+
function getFontRootCauses(networkRequests, prePaintEvents, shiftsByPrePaint, rootCausesByShift) {
|
|
154
|
+
const fontRequests = networkRequests.filter(req => req.args.data.resourceType === 'Font' && req.args.data.mimeType.startsWith('font'));
|
|
155
|
+
for (const req of fontRequests) {
|
|
156
|
+
const nextPrePaint = getNextPrePaintEvent(prePaintEvents, req);
|
|
157
|
+
if (!nextPrePaint) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// If the req is outside the INVALIDATION_WINDOW, it could not be a root cause.
|
|
161
|
+
if (!isInInvalidationWindow(req, nextPrePaint)) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
// Get the shifts that belong to this prepaint
|
|
165
|
+
const shifts = shiftsByPrePaint.get(nextPrePaint);
|
|
166
|
+
// if no layout shift(s) in this prePaint, the request is not a root cause.
|
|
167
|
+
if (!shifts) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
// Include the root cause to the shifts in this prePaint.
|
|
171
|
+
for (const shift of shifts) {
|
|
172
|
+
const rootCausesForShift = Platform.MapUtilities.getWithDefault(rootCausesByShift, shift, () => {
|
|
173
|
+
return {
|
|
174
|
+
iframes: [],
|
|
175
|
+
fontRequests: [],
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
rootCausesForShift.fontRequests.push(req);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return rootCausesByShift;
|
|
182
|
+
}
|
|
71
183
|
export function generateInsight(traceParsedData, context) {
|
|
72
|
-
const
|
|
184
|
+
const isWithinSameNavigation = ((event) => {
|
|
73
185
|
const nav = Helpers.Trace.getNavigationForTraceEvent(event, context.frameId, traceParsedData.Meta.navigationsByFrameId);
|
|
74
186
|
return nav?.args.data?.navigationId === context.navigationId;
|
|
75
187
|
});
|
|
188
|
+
const compositeAnimationEvents = traceParsedData.Animations.animations.filter(isWithinSameNavigation);
|
|
76
189
|
const animationFailures = getNonCompositedAnimations(compositeAnimationEvents);
|
|
190
|
+
const iframeEvents = traceParsedData.LayoutShifts.renderFrameImplCreateChildFrameEvents.filter(isWithinSameNavigation);
|
|
191
|
+
const networkRequests = traceParsedData.NetworkRequests.byTime.filter(isWithinSameNavigation);
|
|
192
|
+
const layoutShifts = traceParsedData.LayoutShifts.clusters.flatMap(cluster =>
|
|
193
|
+
// Use one of the events in the cluster to determine if within the same navigation.
|
|
194
|
+
isWithinSameNavigation(cluster.events[0]) ? cluster.events : []);
|
|
195
|
+
const prePaintEvents = traceParsedData.LayoutShifts.prePaintEvents.filter(isWithinSameNavigation);
|
|
196
|
+
// Get root causes.
|
|
197
|
+
const rootCausesByShift = new Map();
|
|
198
|
+
const shiftsByPrePaint = getShiftsByPrePaintEvents(layoutShifts, prePaintEvents);
|
|
199
|
+
for (const shift of layoutShifts) {
|
|
200
|
+
rootCausesByShift.set(shift, { iframes: [], fontRequests: [] });
|
|
201
|
+
}
|
|
202
|
+
getIframeRootCauses(iframeEvents, prePaintEvents, shiftsByPrePaint, rootCausesByShift);
|
|
203
|
+
getFontRootCauses(networkRequests, prePaintEvents, shiftsByPrePaint, rootCausesByShift);
|
|
77
204
|
return {
|
|
78
205
|
animationFailures,
|
|
206
|
+
shifts: rootCausesByShift,
|
|
79
207
|
};
|
|
80
208
|
}
|
|
81
209
|
//# sourceMappingURL=CumulativeLayoutShift.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CumulativeLayoutShift.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/CumulativeLayoutShift.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AASjD,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAChC,CAAC;AA2BD;;;;;GAKG;AACH,MAAM,0BAA0B,GAAG;IACjC;QACE,IAAI,EAAE,CAAC,IAAI,EAAE;QACb,OAAO,mFAAkD;KAC1D;IACD;QACE,IAAI,EAAE,CAAC,IAAI,EAAE;QACb,OAAO,2FAAsD;KAC9D;IACD;QACE,IAAI,EAAE,CAAC,IAAI,EAAE;QACb,OAAO,+EAAgD;KACxD;IACD;QACE,IAAI,EAAE,CAAC,IAAI,CAAC;QACZ,OAAO,uFAAoD;KAC5D;IACD;QACE,IAAI,EAAE,CAAC,IAAI,CAAC;QACZ,OAAO,iFAAiD;KACzD;IACD;QACE,IAAI,EAAE,CAAC,IAAI,CAAC;QACZ,OAAO,qFAAmD;KAC3D;CACF,CAAC;AAEF;;GAEG;AACH,SAAS,0BAA0B,CAAC,UAA+D;IAEjG,MAAM,QAAQ,GAAoC,EAAE,CAAC;IACrD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;QAC9C,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;QAC1D;;;WAGG;QACH,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC;YACpD,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC;YACpE,IAAI,CAAC,WAAW,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3C,SAAS;YACX,CAAC;YACD,MAAM,cAAc,GAAG,0BAA0B,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBACzG,OAAO,MAAM,CAAC,OAAO,CAAC;YACxB,CAAC,CAAC,CAAC;YACH,MAAM,OAAO,GAAkC;gBAC7C,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW;gBACtC,cAAc;gBACd,qBAAqB;aACtB,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,eAA0C,EAAE,OAAiC;IAE3G,MAAM,wBAAwB,GAAG,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACpF,MAAM,GAAG,GACL,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAChH,OAAO,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,wBAAwB,CAAC,CAAC;IAC/E,OAAO;QACL,iBAAiB;KAClB,CAAC;AACJ,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {\n type InsightResult,\n type NavigationInsightContext,\n type RequiredData,\n} from './types.js';\n\nexport function deps(): ['Meta', 'Animations'] {\n return ['Meta', 'Animations'];\n}\n\nexport const enum AnimationFailureReasons {\n UNSUPPORTED_CSS_PROPERTY = 'UNSUPPORTED_CSS_PROPERTY',\n TRANSFROM_BOX_SIZE_DEPENDENT = 'TRANSFROM_BOX_SIZE_DEPENDENT',\n FILTER_MAY_MOVE_PIXELS = 'FILTER_MAY_MOVE_PIXELS',\n NON_REPLACE_COMPOSITE_MODE = 'NON_REPLACE_COMPOSITE_MODE',\n INCOMPATIBLE_ANIMATIONS = 'INCOMPATIBLE_ANIMATIONS',\n UNSUPPORTED_TIMING_PARAMS = 'UNSUPPORTED_TIMING_PARAMS',\n}\n\nexport interface NoncompositedAnimationFailure {\n /**\n * Animation name.\n */\n name?: string;\n /**\n * Failure reason based on mask number defined in\n * https://source.chromium.org/search?q=f:compositor_animations.h%20%22enum%20FailureReason%22.\n */\n failureReasons: AnimationFailureReasons[];\n /**\n * Unsupported properties.\n */\n unsupportedProperties?: Types.TraceEvents.TraceEventAnimation['args']['data']['unsupportedProperties'];\n}\n\n/**\n * Each failure reason is represented by a bit flag. The bit shift operator '<<' is used to define\n * which bit corresponds to each failure reason.\n * https://source.chromium.org/search?q=f:compositor_animations.h%20%22enum%20FailureReason%22\n * @type {{flag: number, failure: AnimationFailureReasons}[]}\n */\nconst ACTIONABLE_FAILURE_REASONS = [\n {\n flag: 1 << 13,\n failure: AnimationFailureReasons.UNSUPPORTED_CSS_PROPERTY,\n },\n {\n flag: 1 << 11,\n failure: AnimationFailureReasons.TRANSFROM_BOX_SIZE_DEPENDENT,\n },\n {\n flag: 1 << 12,\n failure: AnimationFailureReasons.FILTER_MAY_MOVE_PIXELS,\n },\n {\n flag: 1 << 4,\n failure: AnimationFailureReasons.NON_REPLACE_COMPOSITE_MODE,\n },\n {\n flag: 1 << 6,\n failure: AnimationFailureReasons.INCOMPATIBLE_ANIMATIONS,\n },\n {\n flag: 1 << 3,\n failure: AnimationFailureReasons.UNSUPPORTED_TIMING_PARAMS,\n },\n];\n\n/**\n * Returns a list of NoncompositedAnimationFailures.\n */\nfunction getNonCompositedAnimations(animations: readonly Types.TraceEvents.SyntheticAnimationPair[]):\n NoncompositedAnimationFailure[] {\n const failures: NoncompositedAnimationFailure[] = [];\n for (const event of animations) {\n const beginEvent = event.args.data.beginEvent;\n const instantEvents = event.args.data.instantEvents || [];\n /**\n * Animation events containing composite information are ASYNC_NESTABLE_INSTANT ('n').\n * An animation may also contain multiple 'n' events, so we look through those with useful non-composited data.\n */\n for (const event of instantEvents) {\n const failureMask = event.args.data.compositeFailed;\n const unsupportedProperties = event.args.data.unsupportedProperties;\n if (!failureMask || !unsupportedProperties) {\n continue;\n }\n const failureReasons = ACTIONABLE_FAILURE_REASONS.filter(reason => failureMask & reason.flag).map(reason => {\n return reason.failure;\n });\n const failure: NoncompositedAnimationFailure = {\n name: beginEvent.args.data.displayName,\n failureReasons,\n unsupportedProperties,\n };\n failures.push(failure);\n }\n }\n return failures;\n}\n\nexport function generateInsight(traceParsedData: RequiredData<typeof deps>, context: NavigationInsightContext):\n InsightResult<{animationFailures?: readonly NoncompositedAnimationFailure[]}> {\n const compositeAnimationEvents = traceParsedData.Animations.animations.filter(event => {\n const nav =\n Helpers.Trace.getNavigationForTraceEvent(event, context.frameId, traceParsedData.Meta.navigationsByFrameId);\n return nav?.args.data?.navigationId === context.navigationId;\n });\n const animationFailures = getNonCompositedAnimations(compositeAnimationEvents);\n return {\n animationFailures,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"CumulativeLayoutShift.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/CumulativeLayoutShift.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {\n type InsightResult,\n type NavigationInsightContext,\n type RequiredData,\n} from './types.js';\n\nexport function deps(): ['Meta', 'Animations', 'LayoutShifts', 'NetworkRequests'] {\n return ['Meta', 'Animations', 'LayoutShifts', 'NetworkRequests'];\n}\n\nexport const enum AnimationFailureReasons {\n UNSUPPORTED_CSS_PROPERTY = 'UNSUPPORTED_CSS_PROPERTY',\n TRANSFROM_BOX_SIZE_DEPENDENT = 'TRANSFROM_BOX_SIZE_DEPENDENT',\n FILTER_MAY_MOVE_PIXELS = 'FILTER_MAY_MOVE_PIXELS',\n NON_REPLACE_COMPOSITE_MODE = 'NON_REPLACE_COMPOSITE_MODE',\n INCOMPATIBLE_ANIMATIONS = 'INCOMPATIBLE_ANIMATIONS',\n UNSUPPORTED_TIMING_PARAMS = 'UNSUPPORTED_TIMING_PARAMS',\n}\n\nexport interface NoncompositedAnimationFailure {\n /**\n * Animation name.\n */\n name?: string;\n /**\n * Failure reason based on mask number defined in\n * https://source.chromium.org/search?q=f:compositor_animations.h%20%22enum%20FailureReason%22.\n */\n failureReasons: AnimationFailureReasons[];\n /**\n * Unsupported properties.\n */\n unsupportedProperties?: Types.TraceEvents.TraceEventAnimation['args']['data']['unsupportedProperties'];\n}\n\n/**\n * Each failure reason is represented by a bit flag. The bit shift operator '<<' is used to define\n * which bit corresponds to each failure reason.\n * https://source.chromium.org/search?q=f:compositor_animations.h%20%22enum%20FailureReason%22\n * @type {{flag: number, failure: AnimationFailureReasons}[]}\n */\nconst ACTIONABLE_FAILURE_REASONS = [\n {\n flag: 1 << 13,\n failure: AnimationFailureReasons.UNSUPPORTED_CSS_PROPERTY,\n },\n {\n flag: 1 << 11,\n failure: AnimationFailureReasons.TRANSFROM_BOX_SIZE_DEPENDENT,\n },\n {\n flag: 1 << 12,\n failure: AnimationFailureReasons.FILTER_MAY_MOVE_PIXELS,\n },\n {\n flag: 1 << 4,\n failure: AnimationFailureReasons.NON_REPLACE_COMPOSITE_MODE,\n },\n {\n flag: 1 << 6,\n failure: AnimationFailureReasons.INCOMPATIBLE_ANIMATIONS,\n },\n {\n flag: 1 << 3,\n failure: AnimationFailureReasons.UNSUPPORTED_TIMING_PARAMS,\n },\n];\n\n// 500ms window.\n// Use this window to consider events and requests that may have caused a layout shift.\nconst INVALIDATION_WINDOW = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(0.5));\n\nexport interface LayoutShiftRootCausesData {\n iframes: Types.TraceEvents.TraceEventRenderFrameImplCreateChildFrame[];\n fontRequests: Types.TraceEvents.SyntheticNetworkRequest[];\n}\n\nfunction isInInvalidationWindow(\n event: Types.TraceEvents.TraceEventData, targetEvent: Types.TraceEvents.TraceEventData): boolean {\n const eventEnd = event.dur ? event.ts + event.dur : event.ts;\n return eventEnd < targetEvent.ts && eventEnd >= targetEvent.ts - INVALIDATION_WINDOW;\n}\n\n/**\n * Returns a list of NoncompositedAnimationFailures.\n */\nfunction getNonCompositedAnimations(animations: readonly Types.TraceEvents.SyntheticAnimationPair[]):\n NoncompositedAnimationFailure[] {\n const failures: NoncompositedAnimationFailure[] = [];\n for (const event of animations) {\n const beginEvent = event.args.data.beginEvent;\n const instantEvents = event.args.data.instantEvents || [];\n /**\n * Animation events containing composite information are ASYNC_NESTABLE_INSTANT ('n').\n * An animation may also contain multiple 'n' events, so we look through those with useful non-composited data.\n */\n for (const event of instantEvents) {\n const failureMask = event.args.data.compositeFailed;\n const unsupportedProperties = event.args.data.unsupportedProperties;\n if (!failureMask || !unsupportedProperties) {\n continue;\n }\n const failureReasons = ACTIONABLE_FAILURE_REASONS.filter(reason => failureMask & reason.flag).map(reason => {\n return reason.failure;\n });\n const failure: NoncompositedAnimationFailure = {\n name: beginEvent.args.data.displayName,\n failureReasons,\n unsupportedProperties,\n };\n failures.push(failure);\n }\n }\n return failures;\n}\n\n/**\n * Given an array of layout shift and PrePaint events, returns a mapping from\n * PrePaint events to layout shifts dispatched within it.\n */\nfunction getShiftsByPrePaintEvents(\n layoutShifts: Types.TraceEvents.TraceEventLayoutShift[],\n prePaintEvents: Types.TraceEvents.TraceEventPrePaint[],\n ): Map<Types.TraceEvents.TraceEventPrePaint, Types.TraceEvents.TraceEventLayoutShift[]> {\n // Maps from PrePaint events to LayoutShifts that occured in each one.\n const shiftsByPrePaint = new Map<Types.TraceEvents.TraceEventPrePaint, Types.TraceEvents.TraceEventLayoutShift[]>();\n\n // Associate all shifts to their corresponding PrePaint.\n for (const prePaintEvent of prePaintEvents) {\n const firstShiftIndex =\n Platform.ArrayUtilities.nearestIndexFromBeginning(layoutShifts, shift => shift.ts >= prePaintEvent.ts);\n if (firstShiftIndex === null) {\n // No layout shifts registered after this PrePaint start. Continue.\n continue;\n }\n for (let i = firstShiftIndex; i < layoutShifts.length; i++) {\n const shift = layoutShifts[i];\n if (shift.ts >= prePaintEvent.ts && shift.ts <= prePaintEvent.ts + prePaintEvent.dur) {\n const shiftsInPrePaint = Platform.MapUtilities.getWithDefault(shiftsByPrePaint, prePaintEvent, () => []);\n shiftsInPrePaint.push(shift);\n }\n if (shift.ts > prePaintEvent.ts + prePaintEvent.dur) {\n // Reached all layoutShifts of this PrePaint. Break out to continue with the next prePaint event.\n break;\n }\n }\n }\n return shiftsByPrePaint;\n}\n\n/**\n * This gets the first prePaint event that follows the provided event and returns it.\n */\nfunction getNextPrePaintEvent(\n prePaintEvents: Types.TraceEvents.TraceEventPrePaint[],\n targetEvent: Types.TraceEvents.TraceEventData): Types.TraceEvents.TraceEventPrePaint|undefined {\n // Get the first PrePaint event that happened after the targetEvent.\n const nextPrePaintIndex = Platform.ArrayUtilities.nearestIndexFromBeginning(\n prePaintEvents, prePaint => prePaint.ts > targetEvent.ts + (targetEvent.dur || 0));\n // No PrePaint event registered after this event\n if (nextPrePaintIndex === null) {\n return undefined;\n }\n\n return prePaintEvents[nextPrePaintIndex];\n}\n\n/**\n * An Iframe is considered a root cause if the iframe event occurs before a prePaint event\n * and within this prePaint event a layout shift(s) occurs.\n */\nfunction getIframeRootCauses(\n iframeCreatedEvents: readonly Types.TraceEvents.TraceEventRenderFrameImplCreateChildFrame[],\n prePaintEvents: Types.TraceEvents.TraceEventPrePaint[],\n shiftsByPrePaint: Map<Types.TraceEvents.TraceEventPrePaint, Types.TraceEvents.TraceEventLayoutShift[]>,\n rootCausesByShift: Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData>):\n Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData> {\n for (const iframeEvent of iframeCreatedEvents) {\n const nextPrePaint = getNextPrePaintEvent(prePaintEvents, iframeEvent);\n // If no following prePaint, this is not a root cause.\n if (!nextPrePaint) {\n continue;\n }\n const shifts = shiftsByPrePaint.get(nextPrePaint);\n // if no layout shift(s), this is not a root cause.\n if (!shifts) {\n continue;\n }\n for (const shift of shifts) {\n const rootCausesForShift = Platform.MapUtilities.getWithDefault(rootCausesByShift, shift, () => {\n return {\n iframes: [],\n fontRequests: [],\n };\n });\n rootCausesForShift.iframes.push(iframeEvent);\n }\n }\n return rootCausesByShift;\n}\n\n/**\n * A font request is considered a root cause if the request occurs before a prePaint event\n * and within this prePaint event a layout shift(s) occurs. Additionally, this font request should\n * happen within the INVALIDATION_WINDOW of the prePaint event.\n */\nfunction getFontRootCauses(\n networkRequests: Types.TraceEvents.SyntheticNetworkRequest[],\n prePaintEvents: Types.TraceEvents.TraceEventPrePaint[],\n shiftsByPrePaint: Map<Types.TraceEvents.TraceEventPrePaint, Types.TraceEvents.TraceEventLayoutShift[]>,\n rootCausesByShift: Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData>):\n Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData> {\n const fontRequests =\n networkRequests.filter(req => req.args.data.resourceType === 'Font' && req.args.data.mimeType.startsWith('font'));\n\n for (const req of fontRequests) {\n const nextPrePaint = getNextPrePaintEvent(prePaintEvents, req);\n if (!nextPrePaint) {\n continue;\n }\n\n // If the req is outside the INVALIDATION_WINDOW, it could not be a root cause.\n if (!isInInvalidationWindow(req, nextPrePaint)) {\n continue;\n }\n\n // Get the shifts that belong to this prepaint\n const shifts = shiftsByPrePaint.get(nextPrePaint);\n\n // if no layout shift(s) in this prePaint, the request is not a root cause.\n if (!shifts) {\n continue;\n }\n // Include the root cause to the shifts in this prePaint.\n for (const shift of shifts) {\n const rootCausesForShift = Platform.MapUtilities.getWithDefault(rootCausesByShift, shift, () => {\n return {\n iframes: [],\n fontRequests: [],\n };\n });\n rootCausesForShift.fontRequests.push(req);\n }\n }\n return rootCausesByShift;\n}\n\nexport function generateInsight(\n traceParsedData: RequiredData<typeof deps>, context: NavigationInsightContext): InsightResult<{\n animationFailures?: readonly NoncompositedAnimationFailure[],\n shifts?: Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData>,\n}> {\n const isWithinSameNavigation = ((event: Types.TraceEvents.TraceEventData): boolean => {\n const nav =\n Helpers.Trace.getNavigationForTraceEvent(event, context.frameId, traceParsedData.Meta.navigationsByFrameId);\n return nav?.args.data?.navigationId === context.navigationId;\n });\n\n const compositeAnimationEvents = traceParsedData.Animations.animations.filter(isWithinSameNavigation);\n const animationFailures = getNonCompositedAnimations(compositeAnimationEvents);\n\n const iframeEvents =\n traceParsedData.LayoutShifts.renderFrameImplCreateChildFrameEvents.filter(isWithinSameNavigation);\n const networkRequests = traceParsedData.NetworkRequests.byTime.filter(isWithinSameNavigation);\n\n const layoutShifts = traceParsedData.LayoutShifts.clusters.flatMap(\n cluster =>\n // Use one of the events in the cluster to determine if within the same navigation.\n isWithinSameNavigation(cluster.events[0]) ? cluster.events : [],\n );\n const prePaintEvents = traceParsedData.LayoutShifts.prePaintEvents.filter(isWithinSameNavigation);\n\n // Get root causes.\n const rootCausesByShift = new Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData>();\n const shiftsByPrePaint = getShiftsByPrePaintEvents(layoutShifts, prePaintEvents);\n\n for (const shift of layoutShifts) {\n rootCausesByShift.set(shift, {iframes: [], fontRequests: []});\n }\n\n getIframeRootCauses(iframeEvents, prePaintEvents, shiftsByPrePaint, rootCausesByShift);\n getFontRootCauses(networkRequests, prePaintEvents, shiftsByPrePaint, rootCausesByShift);\n\n return {\n animationFailures,\n shifts: rootCausesByShift,\n };\n}\n"]}
|
|
@@ -29,6 +29,20 @@ export function generateInsight(traceParsedData, context) {
|
|
|
29
29
|
if (req.args.data.syntheticData.finishTime > firstPaintTs) {
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
|
+
// If a resource is marked `in_body_parser_blocking` it should only be considered render blocking if it is a
|
|
33
|
+
// high enough priority. Some resources (e.g. scripts) are not marked as high priority if they are fetched
|
|
34
|
+
// after a non-preloaded image. (See "early" definition in https://web.dev/articles/fetch-priority)
|
|
35
|
+
//
|
|
36
|
+
// There are edge cases and exceptions (e.g. priority hints) but this gives us the best approximation
|
|
37
|
+
// of render blocking resources in the document body.
|
|
38
|
+
if (req.args.data.renderBlocking === 'in_body_parser_blocking') {
|
|
39
|
+
const priority = req.args.data.priority;
|
|
40
|
+
const isScript = req.args.data.resourceType === "Script" /* Protocol.Network.ResourceType.Script */;
|
|
41
|
+
const isBlockingScript = isScript && priority === "High" /* Protocol.Network.ResourcePriority.High */;
|
|
42
|
+
if (priority !== "VeryHigh" /* Protocol.Network.ResourcePriority.VeryHigh */ && !isBlockingScript) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
32
46
|
const navigation = Helpers.Trace.getNavigationForTraceEvent(req, context.frameId, traceParsedData.Meta.navigationsByFrameId);
|
|
33
47
|
if (navigation?.args.data?.navigationId !== context.navigationId) {
|
|
34
48
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderBlocking.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/RenderBlocking.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;
|
|
1
|
+
{"version":3,"file":"RenderBlocking.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/RenderBlocking.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAG7B,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AAGjD,OAAO,EAAqB,cAAc,EAAmD,MAAM,YAAY,CAAC;AAEhH,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,eAA0C,EAAE,OAAiC;IAE3G,MAAM,YAAY,GAAG,eAAe,CAAC,eAAe,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;QACtE,EAAE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC;QAC3B,EAAE,GAAG,iEAAsD;QAC3D,EAAE,KAAK,EAAE,EAAE,CAAC;IACrC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,sBAAsB,EAAE,EAAE;YAC1B,QAAQ,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC;SACjC,CAAC;IACJ,CAAC;IAED,MAAM,sBAAsB,GAAG,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;QACzD,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YAC5C,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,KAAK,UAAU,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,KAAK,yBAAyB,EAAE,CAAC;YAC9G,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,GAAG,YAAY,EAAE,CAAC;YAC1D,SAAS;QACX,CAAC;QAED,4GAA4G;QAC5G,0GAA0G;QAC1G,mGAAmG;QACnG,EAAE;QACF,qGAAqG;QACrG,qDAAqD;QACrD,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,KAAK,yBAAyB,EAAE,CAAC;YAC/D,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;YACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,wDAAyC,CAAC;YACrF,MAAM,gBAAgB,GAAG,QAAQ,IAAI,QAAQ,wDAA2C,CAAC;YACzF,IAAI,QAAQ,gEAA+C,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACjF,SAAS;YACX,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GACZ,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC9G,IAAI,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;YACjE,SAAS;QACX,CAAC;QAED,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,OAAO;QACL,sBAAsB;KACvB,CAAC;AACJ,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Protocol from '../../../generated/protocol.js';\nimport * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {type InsightResult, InsightWarning, type NavigationInsightContext, type RequiredData} from './types.js';\n\nexport function deps(): ['NetworkRequests', 'PageLoadMetrics'] {\n return ['NetworkRequests', 'PageLoadMetrics'];\n}\n\nexport function generateInsight(traceParsedData: RequiredData<typeof deps>, context: NavigationInsightContext):\n InsightResult<{renderBlockingRequests: Types.TraceEvents.SyntheticNetworkRequest[]}> {\n const firstPaintTs = traceParsedData.PageLoadMetrics.metricScoresByFrameId.get(context.frameId)\n ?.get(context.navigationId)\n ?.get(Handlers.ModelHandlers.PageLoadMetrics.MetricName.FP)\n ?.event?.ts;\n if (!firstPaintTs) {\n return {\n renderBlockingRequests: [],\n warnings: [InsightWarning.NO_FP],\n };\n }\n\n const renderBlockingRequests = [];\n for (const req of traceParsedData.NetworkRequests.byTime) {\n if (req.args.data.frame !== context.frameId) {\n continue;\n }\n\n if (req.args.data.renderBlocking !== 'blocking' && req.args.data.renderBlocking !== 'in_body_parser_blocking') {\n continue;\n }\n\n if (req.args.data.syntheticData.finishTime > firstPaintTs) {\n continue;\n }\n\n // If a resource is marked `in_body_parser_blocking` it should only be considered render blocking if it is a\n // high enough priority. Some resources (e.g. scripts) are not marked as high priority if they are fetched\n // after a non-preloaded image. (See \"early\" definition in https://web.dev/articles/fetch-priority)\n //\n // There are edge cases and exceptions (e.g. priority hints) but this gives us the best approximation\n // of render blocking resources in the document body.\n if (req.args.data.renderBlocking === 'in_body_parser_blocking') {\n const priority = req.args.data.priority;\n const isScript = req.args.data.resourceType === Protocol.Network.ResourceType.Script;\n const isBlockingScript = isScript && priority === Protocol.Network.ResourcePriority.High;\n if (priority !== Protocol.Network.ResourcePriority.VeryHigh && !isBlockingScript) {\n continue;\n }\n }\n\n const navigation =\n Helpers.Trace.getNavigationForTraceEvent(req, context.frameId, traceParsedData.Meta.navigationsByFrameId);\n if (navigation?.args.data?.navigationId !== context.navigationId) {\n continue;\n }\n\n renderBlockingRequests.push(req);\n }\n\n return {\n renderBlockingRequests,\n };\n}\n"]}
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
32
|
"../../../../../../front_end/models/trace/EntriesFilter.ts",
|
|
33
|
-
"../../../../../../front_end/models/trace/LegacyTracingModel.ts",
|
|
34
33
|
"../../../../../../front_end/models/trace/ModelImpl.ts",
|
|
35
34
|
"../../../../../../front_end/models/trace/Processor.ts",
|
|
36
35
|
"../../../../../../front_end/models/trace/TracingManager.ts",
|
package/models/trace/trace.d.ts
CHANGED
|
@@ -3,10 +3,9 @@ import * as Extras from './extras/extras.js';
|
|
|
3
3
|
import * as Handlers from './handlers/handlers.js';
|
|
4
4
|
import * as Helpers from './helpers/helpers.js';
|
|
5
5
|
import * as Insights from './insights/insights.js';
|
|
6
|
-
import * as Legacy from './LegacyTracingModel.js';
|
|
7
6
|
import * as TraceModel from './ModelImpl.js';
|
|
8
7
|
import * as Processor from './Processor.js';
|
|
9
8
|
import * as RootCauses from './root-causes/root-causes.js';
|
|
10
9
|
import * as TracingManager from './TracingManager.js';
|
|
11
10
|
import * as Types from './types/types.js';
|
|
12
|
-
export { EntriesFilter, Extras, Handlers, Helpers, Insights,
|
|
11
|
+
export { EntriesFilter, Extras, Handlers, Helpers, Insights, Processor, RootCauses, TraceModel, TracingManager, Types, };
|
package/models/trace/trace.js
CHANGED
|
@@ -6,13 +6,10 @@ import * as Extras from './extras/extras.js';
|
|
|
6
6
|
import * as Handlers from './handlers/handlers.js';
|
|
7
7
|
import * as Helpers from './helpers/helpers.js';
|
|
8
8
|
import * as Insights from './insights/insights.js';
|
|
9
|
-
// Purposefully use a shorter name here so references to this are
|
|
10
|
-
// Legacy.TracingModel.
|
|
11
|
-
import * as Legacy from './LegacyTracingModel.js';
|
|
12
9
|
import * as TraceModel from './ModelImpl.js';
|
|
13
10
|
import * as Processor from './Processor.js';
|
|
14
11
|
import * as RootCauses from './root-causes/root-causes.js';
|
|
15
12
|
import * as TracingManager from './TracingManager.js';
|
|
16
13
|
import * as Types from './types/types.js';
|
|
17
|
-
export { EntriesFilter, Extras, Handlers, Helpers, Insights,
|
|
14
|
+
export { EntriesFilter, Extras, Handlers, Helpers, Insights, Processor, RootCauses, TraceModel, TracingManager, Types, };
|
|
18
15
|
//# sourceMappingURL=trace.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/trace.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/trace.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,UAAU,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EACL,aAAa,EACb,MAAM,EACN,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,UAAU,EACV,UAAU,EACV,cAAc,EACd,KAAK,GACN,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as EntriesFilter from './EntriesFilter.js';\nimport * as Extras from './extras/extras.js';\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as TraceModel from './ModelImpl.js';\nimport * as Processor from './Processor.js';\nimport * as RootCauses from './root-causes/root-causes.js';\nimport * as TracingManager from './TracingManager.js';\nimport * as Types from './types/types.js';\n\nexport {\n EntriesFilter,\n Extras,\n Handlers,\n Helpers,\n Insights,\n Processor,\n RootCauses,\n TraceModel,\n TracingManager,\n Types,\n};\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
|
1
2
|
import { type TraceWindowMicroSeconds } from './Timing.js';
|
|
2
|
-
import { type TraceEventData } from './TraceEvents.js';
|
|
3
|
+
import { type ProcessID, type SampleIndex, type ThreadID, type TraceEventData } from './TraceEvents.js';
|
|
3
4
|
export type TraceFile = {
|
|
4
5
|
traceEvents: readonly TraceEventData[];
|
|
5
6
|
metadata: MetaData;
|
|
@@ -12,10 +13,14 @@ export declare const enum DataOrigin {
|
|
|
12
13
|
CPUProfile = "CPUProfile",
|
|
13
14
|
TraceEvents = "TraceEvents"
|
|
14
15
|
}
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
export type RawEventKey = ['r', number];
|
|
17
|
+
export type ProfileCallKey = ['p', ProcessID, ThreadID, SampleIndex, Protocol.integer];
|
|
18
|
+
export type SyntheticEventKey = ['s', number];
|
|
19
|
+
export type TraceEventSerializableKey = RawEventKey | ProfileCallKey | SyntheticEventKey;
|
|
20
|
+
export interface Modifications {
|
|
21
|
+
entriesModifications: {
|
|
22
|
+
hiddenEntries: string[];
|
|
23
|
+
expandableEntries: string[];
|
|
19
24
|
};
|
|
20
25
|
initialBreadcrumb: Breadcrumb;
|
|
21
26
|
}
|
|
@@ -31,6 +36,6 @@ export interface MetaData {
|
|
|
31
36
|
cpuThrottling?: number;
|
|
32
37
|
hardwareConcurrency?: number;
|
|
33
38
|
dataOrigin?: DataOrigin;
|
|
34
|
-
|
|
39
|
+
modifications?: Modifications;
|
|
35
40
|
}
|
|
36
41
|
export type Contents = TraceFile | TraceEventData[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"File.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/types/File.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"File.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/types/File.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport type * as Protocol from '../../../generated/protocol.js';\n\nimport {type TraceWindowMicroSeconds} from './Timing.js';\nimport {type ProcessID, type SampleIndex, type ThreadID, type TraceEventData} from './TraceEvents.js';\n\nexport type TraceFile = {\n traceEvents: readonly TraceEventData[],\n metadata: MetaData,\n};\n\nexport interface Breadcrumb {\n window: TraceWindowMicroSeconds;\n child: Breadcrumb|null;\n}\n\nexport const enum DataOrigin {\n CPUProfile = 'CPUProfile',\n TraceEvents = 'TraceEvents',\n}\n\n// Serializable keys are created for trace events to be able to save\n// references to timeline events in a trace file. These keys enable\n// user modifications that can be saved. See go/cpq:event-data-json for\n// more details on the key format.\nexport type RawEventKey = ['r', number];\nexport type ProfileCallKey = ['p', ProcessID, ThreadID, SampleIndex, Protocol.integer];\nexport type SyntheticEventKey = ['s', number];\nexport type TraceEventSerializableKey = RawEventKey|ProfileCallKey|SyntheticEventKey;\n\nexport interface Modifications {\n entriesModifications: {\n // Entries hidden by the user\n hiddenEntries: string[],\n // Entries that parent a hiddenEntry\n expandableEntries: string[],\n };\n initialBreadcrumb: Breadcrumb;\n}\n\n/**\n * Trace metadata that we persist to the file. This will allow us to\n * store specifics for the trace, e.g., which tracks should be visible\n * on load.\n */\nexport interface MetaData {\n source?: 'DevTools';\n startTime?: string;\n networkThrottling?: string;\n cpuThrottling?: number;\n hardwareConcurrency?: number;\n dataOrigin?: DataOrigin;\n modifications?: Modifications;\n}\n\nexport type Contents = TraceFile|TraceEventData[];\n"]}
|
|
@@ -63,6 +63,7 @@ export interface TraceEventCallFrame {
|
|
|
63
63
|
lineNumber: number;
|
|
64
64
|
url: string;
|
|
65
65
|
}
|
|
66
|
+
export declare function objectIsTraceEventCallFrame(object: {}): object is TraceEventCallFrame;
|
|
66
67
|
export interface TraceFrame {
|
|
67
68
|
frame: string;
|
|
68
69
|
name: string;
|
|
@@ -78,7 +79,7 @@ export interface TraceEventSample extends TraceEventData {
|
|
|
78
79
|
* A fake trace event created to support CDP.Profiler.Profiles in the
|
|
79
80
|
* trace engine.
|
|
80
81
|
*/
|
|
81
|
-
export interface SyntheticCpuProfile extends TraceEventInstant {
|
|
82
|
+
export interface SyntheticCpuProfile extends TraceEventInstant, SyntheticBasedEvent<Phase.INSTANT> {
|
|
82
83
|
name: 'CpuProfile';
|
|
83
84
|
args: TraceEventArgs & {
|
|
84
85
|
data: TraceEventArgsData & {
|
|
@@ -119,6 +120,10 @@ export interface TraceEventComplete extends TraceEventData {
|
|
|
119
120
|
ph: Phase.COMPLETE;
|
|
120
121
|
dur: MicroSeconds;
|
|
121
122
|
}
|
|
123
|
+
export interface TraceEventRunTask extends TraceEventComplete {
|
|
124
|
+
name: KnownEventName.RunTask;
|
|
125
|
+
}
|
|
126
|
+
export declare function isTraceEventRunTask(event: TraceEventData): event is TraceEventRunTask;
|
|
122
127
|
export interface TraceEventFireIdleCallback extends TraceEventComplete {
|
|
123
128
|
name: KnownEventName.FireIdleCallback;
|
|
124
129
|
args: TraceEventArgs & {
|
|
@@ -242,7 +247,8 @@ interface SyntheticArgsData {
|
|
|
242
247
|
totalTime: MicroSeconds;
|
|
243
248
|
waiting: MicroSeconds;
|
|
244
249
|
}
|
|
245
|
-
export interface SyntheticNetworkRequest extends TraceEventComplete {
|
|
250
|
+
export interface SyntheticNetworkRequest extends TraceEventComplete, SyntheticBasedEvent<Phase.COMPLETE> {
|
|
251
|
+
rawSourceEvent: TraceEventData;
|
|
246
252
|
args: TraceEventArgs & {
|
|
247
253
|
data: TraceEventArgsData & {
|
|
248
254
|
syntheticData: SyntheticArgsData;
|
|
@@ -300,7 +306,8 @@ export declare const enum AuctionWorkletType {
|
|
|
300
306
|
SELLER = "seller",
|
|
301
307
|
UNKNOWN = "unknown"
|
|
302
308
|
}
|
|
303
|
-
export interface SyntheticAuctionWorkletEvent extends TraceEventInstant {
|
|
309
|
+
export interface SyntheticAuctionWorkletEvent extends TraceEventInstant, SyntheticBasedEvent<Phase.INSTANT> {
|
|
310
|
+
rawSourceEvent: TraceEventData;
|
|
304
311
|
name: 'SyntheticAuctionWorkletEvent';
|
|
305
312
|
pid: ProcessID;
|
|
306
313
|
host: string;
|
|
@@ -363,7 +370,8 @@ export interface TraceEventScreenshot extends TraceEventData {
|
|
|
363
370
|
ph: Phase.OBJECT_SNAPSHOT;
|
|
364
371
|
}
|
|
365
372
|
export declare function isTraceEventScreenshot(event: TraceEventData): event is TraceEventScreenshot;
|
|
366
|
-
export interface SyntheticScreenshot extends TraceEventData {
|
|
373
|
+
export interface SyntheticScreenshot extends TraceEventData, SyntheticBasedEvent {
|
|
374
|
+
rawSourceEvent: TraceEventScreenshot;
|
|
367
375
|
/** This is the correct presentation timestamp. */
|
|
368
376
|
ts: MicroSeconds;
|
|
369
377
|
args: TraceEventArgs & {
|
|
@@ -620,7 +628,9 @@ export interface LayoutShiftParsedData {
|
|
|
620
628
|
cumulativeWeightedScoreInWindow: number;
|
|
621
629
|
sessionWindowData: LayoutShiftSessionWindowData;
|
|
622
630
|
}
|
|
623
|
-
export interface SyntheticLayoutShift extends TraceEventLayoutShift {
|
|
631
|
+
export interface SyntheticLayoutShift extends TraceEventLayoutShift, SyntheticBasedEvent<Phase.INSTANT> {
|
|
632
|
+
name: 'LayoutShift';
|
|
633
|
+
rawSourceEvent: TraceEventLayoutShift;
|
|
624
634
|
args: TraceEventArgs & {
|
|
625
635
|
frame: string;
|
|
626
636
|
data?: LayoutShiftData & {
|
|
@@ -651,6 +661,7 @@ export interface TraceEventResourceSendRequest extends TraceEventInstant {
|
|
|
651
661
|
requestMethod?: string;
|
|
652
662
|
renderBlocking?: RenderBlocking;
|
|
653
663
|
initiator?: Initiator;
|
|
664
|
+
isLinkPreload?: boolean;
|
|
654
665
|
};
|
|
655
666
|
};
|
|
656
667
|
}
|
|
@@ -733,7 +744,6 @@ export interface TraceEventResourceReceiveResponse extends TraceEventInstant {
|
|
|
733
744
|
responseTime: MilliSeconds;
|
|
734
745
|
statusCode: number;
|
|
735
746
|
timing: TraceEventResourceReceiveResponseTimingData;
|
|
736
|
-
isLinkPreload?: boolean;
|
|
737
747
|
connectionId: number;
|
|
738
748
|
connectionReused: boolean;
|
|
739
749
|
headers?: Array<{
|
|
@@ -842,6 +852,14 @@ export interface TraceEventScheduleStyleRecalculation extends TraceEventInstant
|
|
|
842
852
|
};
|
|
843
853
|
}
|
|
844
854
|
export declare function isTraceEventScheduleStyleRecalculation(event: TraceEventData): event is TraceEventScheduleStyleRecalculation;
|
|
855
|
+
export interface TraceEventRenderFrameImplCreateChildFrame extends TraceEventData {
|
|
856
|
+
name: KnownEventName.RenderFrameImplCreateChildFrame;
|
|
857
|
+
args: TraceEventArgs & {
|
|
858
|
+
child_frame_token: string;
|
|
859
|
+
frame_token: string;
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
export declare function isTraceEventRenderFrameImplCreateChildFrame(event: TraceEventData): event is TraceEventRenderFrameImplCreateChildFrame;
|
|
845
863
|
export interface TraceEventPrePaint extends TraceEventComplete {
|
|
846
864
|
name: 'PrePaint';
|
|
847
865
|
}
|
|
@@ -994,7 +1012,16 @@ export interface TraceEventPipelineReporter extends TraceEventData {
|
|
|
994
1012
|
};
|
|
995
1013
|
}
|
|
996
1014
|
export declare function isTraceEventPipelineReporter(event: TraceEventData): event is TraceEventPipelineReporter;
|
|
997
|
-
export interface
|
|
1015
|
+
export interface SyntheticBasedEvent<Ph extends Phase = Phase> extends SyntheticEntry {
|
|
1016
|
+
ph: Ph;
|
|
1017
|
+
rawSourceEvent: TraceEventData;
|
|
1018
|
+
}
|
|
1019
|
+
export type SyntheticEntry = TraceEventData & {
|
|
1020
|
+
_tag: 'SyntheticEntryTag';
|
|
1021
|
+
};
|
|
1022
|
+
export declare function isSyntheticBasedEvent(event: TraceEventData): event is SyntheticBasedEvent;
|
|
1023
|
+
export interface SyntheticEventPair<T extends TraceEventPairableAsync = TraceEventPairableAsync> extends SyntheticBasedEvent {
|
|
1024
|
+
rawSourceEvent: TraceEventData;
|
|
998
1025
|
name: T['name'];
|
|
999
1026
|
cat: T['cat'];
|
|
1000
1027
|
id?: string;
|
|
@@ -1050,6 +1077,7 @@ export interface SyntheticProfileCall extends SyntheticTraceEntry {
|
|
|
1050
1077
|
nodeId: Protocol.integer;
|
|
1051
1078
|
sampleIndex: number;
|
|
1052
1079
|
profileId: ProfileID;
|
|
1080
|
+
selfTime: MicroSeconds;
|
|
1053
1081
|
}
|
|
1054
1082
|
/**
|
|
1055
1083
|
* A JS Sample reflects a single sample from the V8 CPU Profile
|
|
@@ -1237,7 +1265,7 @@ export interface TraceEventLayout extends TraceEventComplete {
|
|
|
1237
1265
|
partialLayout: boolean;
|
|
1238
1266
|
totalObjects: number;
|
|
1239
1267
|
};
|
|
1240
|
-
endData
|
|
1268
|
+
endData?: {
|
|
1241
1269
|
layoutRoots: Array<{
|
|
1242
1270
|
depth: number;
|
|
1243
1271
|
nodeId: Protocol.DOM.BackendNodeId;
|
|
@@ -1267,6 +1295,11 @@ declare class CallFrameIdTag {
|
|
|
1267
1295
|
}
|
|
1268
1296
|
export type CallFrameID = number & CallFrameIdTag;
|
|
1269
1297
|
export declare function CallFrameID(value: number): CallFrameID;
|
|
1298
|
+
declare class SampleIndexTag {
|
|
1299
|
+
#private;
|
|
1300
|
+
}
|
|
1301
|
+
export type SampleIndex = number & SampleIndexTag;
|
|
1302
|
+
export declare function SampleIndex(value: number): SampleIndex;
|
|
1270
1303
|
declare class ProcessIdTag {
|
|
1271
1304
|
#private;
|
|
1272
1305
|
}
|
|
@@ -1526,12 +1559,64 @@ export interface TraceEventWebSocketCreate extends TraceEventInstant {
|
|
|
1526
1559
|
identifier: number;
|
|
1527
1560
|
url: string;
|
|
1528
1561
|
frame?: string;
|
|
1562
|
+
workerId?: string;
|
|
1529
1563
|
websocketProtocol?: string;
|
|
1530
1564
|
stackTrace?: TraceEventCallFrame;
|
|
1531
1565
|
};
|
|
1532
1566
|
};
|
|
1533
1567
|
}
|
|
1534
1568
|
export declare function isTraceEventWebSocketCreate(event: TraceEventData): event is TraceEventWebSocketCreate;
|
|
1569
|
+
export interface TraceEventWebSocketInfo extends TraceEventInstant {
|
|
1570
|
+
name: KnownEventName.WebSocketDestroy | KnownEventName.WebSocketReceiveHandshake | KnownEventName.WebSocketReceiveHandshakeResponse;
|
|
1571
|
+
args: TraceEventArgs & {
|
|
1572
|
+
data: TraceEventArgsData & {
|
|
1573
|
+
identifier: number;
|
|
1574
|
+
url: string;
|
|
1575
|
+
frame?: string;
|
|
1576
|
+
workerId?: string;
|
|
1577
|
+
};
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
export interface TraceEventWebSocketTransfer extends TraceEventInstant {
|
|
1581
|
+
name: KnownEventName.WebSocketSend | KnownEventName.WebSocketReceive;
|
|
1582
|
+
args: TraceEventArgs & {
|
|
1583
|
+
data: TraceEventArgsData & {
|
|
1584
|
+
identifier: number;
|
|
1585
|
+
url: string;
|
|
1586
|
+
frame?: string;
|
|
1587
|
+
workerId?: string;
|
|
1588
|
+
dataLength: number;
|
|
1589
|
+
};
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
export declare function isTraceEventWebSocketInfo(traceEventData: TraceEventData): traceEventData is TraceEventWebSocketInfo;
|
|
1593
|
+
export declare function isTraceEventWebSocketTransfer(traceEventData: TraceEventData): traceEventData is TraceEventWebSocketTransfer;
|
|
1594
|
+
export interface TraceEventWebSocketSend extends TraceEventInstant {
|
|
1595
|
+
name: KnownEventName.WebSocketSend;
|
|
1596
|
+
args: TraceEventArgs & {
|
|
1597
|
+
data: TraceEventArgsData & {
|
|
1598
|
+
identifier: number;
|
|
1599
|
+
url: string;
|
|
1600
|
+
frame?: string;
|
|
1601
|
+
workerId?: string;
|
|
1602
|
+
dataLength: number;
|
|
1603
|
+
};
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
export declare function isTraceEventWebSocketSend(event: TraceEventData): event is TraceEventWebSocketSend;
|
|
1607
|
+
export interface TraceEventWebSocketReceive extends TraceEventInstant {
|
|
1608
|
+
name: KnownEventName.WebSocketReceive;
|
|
1609
|
+
args: TraceEventArgs & {
|
|
1610
|
+
data: TraceEventArgsData & {
|
|
1611
|
+
identifier: number;
|
|
1612
|
+
url: string;
|
|
1613
|
+
frame?: string;
|
|
1614
|
+
workerId?: string;
|
|
1615
|
+
dataLength: number;
|
|
1616
|
+
};
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
export declare function isTraceEventWebSocketReceive(event: TraceEventData): event is TraceEventWebSocketReceive;
|
|
1535
1620
|
export interface TraceEventWebSocketSendHandshakeRequest extends TraceEventInstant {
|
|
1536
1621
|
name: KnownEventName.WebSocketSendHandshakeRequest;
|
|
1537
1622
|
args: TraceEventArgs & {
|
|
@@ -1562,7 +1647,8 @@ export interface TraceEventWebSocketDestroy extends TraceEventInstant {
|
|
|
1562
1647
|
};
|
|
1563
1648
|
}
|
|
1564
1649
|
export declare function isTraceEventWebSocketDestroy(event: TraceEventData): event is TraceEventWebSocketDestroy;
|
|
1565
|
-
export declare function isWebSocketTraceEvent(event: TraceEventData): event is TraceEventWebSocketCreate |
|
|
1650
|
+
export declare function isWebSocketTraceEvent(event: TraceEventData): event is TraceEventWebSocketCreate | TraceEventWebSocketInfo | TraceEventWebSocketTransfer;
|
|
1651
|
+
export type WebSocketEvent = TraceEventWebSocketCreate | TraceEventWebSocketInfo | TraceEventWebSocketTransfer;
|
|
1566
1652
|
export interface TraceEventV8Compile extends TraceEventComplete {
|
|
1567
1653
|
name: KnownEventName.Compile;
|
|
1568
1654
|
args: TraceEventArgs & {
|
|
@@ -1646,6 +1732,8 @@ export declare const enum KnownEventName {
|
|
|
1646
1732
|
WebSocketSendHandshake = "WebSocketSendHandshakeRequest",
|
|
1647
1733
|
WebSocketReceiveHandshake = "WebSocketReceiveHandshakeResponse",
|
|
1648
1734
|
WebSocketDestroy = "WebSocketDestroy",
|
|
1735
|
+
WebSocketSend = "WebSocketSend",
|
|
1736
|
+
WebSocketReceive = "WebSocketReceive",
|
|
1649
1737
|
CryptoDoEncrypt = "DoEncrypt",
|
|
1650
1738
|
CryptoDoEncryptReply = "DoEncryptReply",
|
|
1651
1739
|
CryptoDoDecrypt = "DoDecrypt",
|
|
@@ -1755,6 +1843,12 @@ export declare const enum KnownEventName {
|
|
|
1755
1843
|
InputLatencyMouseWheel = "InputLatency::MouseWheel",
|
|
1756
1844
|
ImplSideFling = "InputHandlerProxy::HandleGestureFling::started",
|
|
1757
1845
|
SchedulePostMessage = "SchedulePostMessage",
|
|
1758
|
-
HandlePostMessage = "HandlePostMessage"
|
|
1846
|
+
HandlePostMessage = "HandlePostMessage",
|
|
1847
|
+
RenderFrameImplCreateChildFrame = "RenderFrameImpl::createChildFrame"
|
|
1759
1848
|
}
|
|
1849
|
+
export declare const Categories: {
|
|
1850
|
+
readonly Console: "blink.console";
|
|
1851
|
+
readonly UserTiming: "blink.user_timing";
|
|
1852
|
+
readonly Loading: "loading";
|
|
1853
|
+
};
|
|
1760
1854
|
export {};
|