@paulirish/trace_engine 0.0.23 → 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 +48 -2
- 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/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 +4 -2
- package/models/trace/handlers/AuctionWorkletsHandler.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 +10 -2
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.js +4 -3
- package/models/trace/handlers/NetworkRequestsHandler.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 +3 -2
- package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
- package/models/trace/handlers/UserInteractionsHandler.js +3 -2
- package/models/trace/handlers/UserInteractionsHandler.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.js +4 -2
- package/models/trace/helpers/Trace.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/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 +85 -12
- package/models/trace/types/TraceEvents.js +27 -3
- 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"]}
|
|
@@ -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"]}
|
|
@@ -79,7 +79,7 @@ export interface TraceEventSample extends TraceEventData {
|
|
|
79
79
|
* A fake trace event created to support CDP.Profiler.Profiles in the
|
|
80
80
|
* trace engine.
|
|
81
81
|
*/
|
|
82
|
-
export interface SyntheticCpuProfile extends TraceEventInstant,
|
|
82
|
+
export interface SyntheticCpuProfile extends TraceEventInstant, SyntheticBasedEvent<Phase.INSTANT> {
|
|
83
83
|
name: 'CpuProfile';
|
|
84
84
|
args: TraceEventArgs & {
|
|
85
85
|
data: TraceEventArgsData & {
|
|
@@ -247,7 +247,7 @@ interface SyntheticArgsData {
|
|
|
247
247
|
totalTime: MicroSeconds;
|
|
248
248
|
waiting: MicroSeconds;
|
|
249
249
|
}
|
|
250
|
-
export interface SyntheticNetworkRequest extends TraceEventComplete,
|
|
250
|
+
export interface SyntheticNetworkRequest extends TraceEventComplete, SyntheticBasedEvent<Phase.COMPLETE> {
|
|
251
251
|
rawSourceEvent: TraceEventData;
|
|
252
252
|
args: TraceEventArgs & {
|
|
253
253
|
data: TraceEventArgsData & {
|
|
@@ -306,7 +306,7 @@ export declare const enum AuctionWorkletType {
|
|
|
306
306
|
SELLER = "seller",
|
|
307
307
|
UNKNOWN = "unknown"
|
|
308
308
|
}
|
|
309
|
-
export interface SyntheticAuctionWorkletEvent extends TraceEventInstant,
|
|
309
|
+
export interface SyntheticAuctionWorkletEvent extends TraceEventInstant, SyntheticBasedEvent<Phase.INSTANT> {
|
|
310
310
|
rawSourceEvent: TraceEventData;
|
|
311
311
|
name: 'SyntheticAuctionWorkletEvent';
|
|
312
312
|
pid: ProcessID;
|
|
@@ -370,7 +370,7 @@ export interface TraceEventScreenshot extends TraceEventData {
|
|
|
370
370
|
ph: Phase.OBJECT_SNAPSHOT;
|
|
371
371
|
}
|
|
372
372
|
export declare function isTraceEventScreenshot(event: TraceEventData): event is TraceEventScreenshot;
|
|
373
|
-
export interface SyntheticScreenshot extends TraceEventData,
|
|
373
|
+
export interface SyntheticScreenshot extends TraceEventData, SyntheticBasedEvent {
|
|
374
374
|
rawSourceEvent: TraceEventScreenshot;
|
|
375
375
|
/** This is the correct presentation timestamp. */
|
|
376
376
|
ts: MicroSeconds;
|
|
@@ -628,7 +628,7 @@ export interface LayoutShiftParsedData {
|
|
|
628
628
|
cumulativeWeightedScoreInWindow: number;
|
|
629
629
|
sessionWindowData: LayoutShiftSessionWindowData;
|
|
630
630
|
}
|
|
631
|
-
export interface SyntheticLayoutShift extends TraceEventLayoutShift,
|
|
631
|
+
export interface SyntheticLayoutShift extends TraceEventLayoutShift, SyntheticBasedEvent<Phase.INSTANT> {
|
|
632
632
|
name: 'LayoutShift';
|
|
633
633
|
rawSourceEvent: TraceEventLayoutShift;
|
|
634
634
|
args: TraceEventArgs & {
|
|
@@ -661,6 +661,7 @@ export interface TraceEventResourceSendRequest extends TraceEventInstant {
|
|
|
661
661
|
requestMethod?: string;
|
|
662
662
|
renderBlocking?: RenderBlocking;
|
|
663
663
|
initiator?: Initiator;
|
|
664
|
+
isLinkPreload?: boolean;
|
|
664
665
|
};
|
|
665
666
|
};
|
|
666
667
|
}
|
|
@@ -743,7 +744,6 @@ export interface TraceEventResourceReceiveResponse extends TraceEventInstant {
|
|
|
743
744
|
responseTime: MilliSeconds;
|
|
744
745
|
statusCode: number;
|
|
745
746
|
timing: TraceEventResourceReceiveResponseTimingData;
|
|
746
|
-
isLinkPreload?: boolean;
|
|
747
747
|
connectionId: number;
|
|
748
748
|
connectionReused: boolean;
|
|
749
749
|
headers?: Array<{
|
|
@@ -852,6 +852,14 @@ export interface TraceEventScheduleStyleRecalculation extends TraceEventInstant
|
|
|
852
852
|
};
|
|
853
853
|
}
|
|
854
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;
|
|
855
863
|
export interface TraceEventPrePaint extends TraceEventComplete {
|
|
856
864
|
name: 'PrePaint';
|
|
857
865
|
}
|
|
@@ -1004,12 +1012,15 @@ export interface TraceEventPipelineReporter extends TraceEventData {
|
|
|
1004
1012
|
};
|
|
1005
1013
|
}
|
|
1006
1014
|
export declare function isTraceEventPipelineReporter(event: TraceEventData): event is TraceEventPipelineReporter;
|
|
1007
|
-
interface
|
|
1015
|
+
export interface SyntheticBasedEvent<Ph extends Phase = Phase> extends SyntheticEntry {
|
|
1008
1016
|
ph: Ph;
|
|
1009
1017
|
rawSourceEvent: TraceEventData;
|
|
1010
1018
|
}
|
|
1011
|
-
export
|
|
1012
|
-
|
|
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 {
|
|
1013
1024
|
rawSourceEvent: TraceEventData;
|
|
1014
1025
|
name: T['name'];
|
|
1015
1026
|
cat: T['cat'];
|
|
@@ -1066,6 +1077,7 @@ export interface SyntheticProfileCall extends SyntheticTraceEntry {
|
|
|
1066
1077
|
nodeId: Protocol.integer;
|
|
1067
1078
|
sampleIndex: number;
|
|
1068
1079
|
profileId: ProfileID;
|
|
1080
|
+
selfTime: MicroSeconds;
|
|
1069
1081
|
}
|
|
1070
1082
|
/**
|
|
1071
1083
|
* A JS Sample reflects a single sample from the V8 CPU Profile
|
|
@@ -1253,7 +1265,7 @@ export interface TraceEventLayout extends TraceEventComplete {
|
|
|
1253
1265
|
partialLayout: boolean;
|
|
1254
1266
|
totalObjects: number;
|
|
1255
1267
|
};
|
|
1256
|
-
endData
|
|
1268
|
+
endData?: {
|
|
1257
1269
|
layoutRoots: Array<{
|
|
1258
1270
|
depth: number;
|
|
1259
1271
|
nodeId: Protocol.DOM.BackendNodeId;
|
|
@@ -1283,6 +1295,11 @@ declare class CallFrameIdTag {
|
|
|
1283
1295
|
}
|
|
1284
1296
|
export type CallFrameID = number & CallFrameIdTag;
|
|
1285
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;
|
|
1286
1303
|
declare class ProcessIdTag {
|
|
1287
1304
|
#private;
|
|
1288
1305
|
}
|
|
@@ -1542,12 +1559,64 @@ export interface TraceEventWebSocketCreate extends TraceEventInstant {
|
|
|
1542
1559
|
identifier: number;
|
|
1543
1560
|
url: string;
|
|
1544
1561
|
frame?: string;
|
|
1562
|
+
workerId?: string;
|
|
1545
1563
|
websocketProtocol?: string;
|
|
1546
1564
|
stackTrace?: TraceEventCallFrame;
|
|
1547
1565
|
};
|
|
1548
1566
|
};
|
|
1549
1567
|
}
|
|
1550
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;
|
|
1551
1620
|
export interface TraceEventWebSocketSendHandshakeRequest extends TraceEventInstant {
|
|
1552
1621
|
name: KnownEventName.WebSocketSendHandshakeRequest;
|
|
1553
1622
|
args: TraceEventArgs & {
|
|
@@ -1578,7 +1647,8 @@ export interface TraceEventWebSocketDestroy extends TraceEventInstant {
|
|
|
1578
1647
|
};
|
|
1579
1648
|
}
|
|
1580
1649
|
export declare function isTraceEventWebSocketDestroy(event: TraceEventData): event is TraceEventWebSocketDestroy;
|
|
1581
|
-
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;
|
|
1582
1652
|
export interface TraceEventV8Compile extends TraceEventComplete {
|
|
1583
1653
|
name: KnownEventName.Compile;
|
|
1584
1654
|
args: TraceEventArgs & {
|
|
@@ -1662,6 +1732,8 @@ export declare const enum KnownEventName {
|
|
|
1662
1732
|
WebSocketSendHandshake = "WebSocketSendHandshakeRequest",
|
|
1663
1733
|
WebSocketReceiveHandshake = "WebSocketReceiveHandshakeResponse",
|
|
1664
1734
|
WebSocketDestroy = "WebSocketDestroy",
|
|
1735
|
+
WebSocketSend = "WebSocketSend",
|
|
1736
|
+
WebSocketReceive = "WebSocketReceive",
|
|
1665
1737
|
CryptoDoEncrypt = "DoEncrypt",
|
|
1666
1738
|
CryptoDoEncryptReply = "DoEncryptReply",
|
|
1667
1739
|
CryptoDoDecrypt = "DoDecrypt",
|
|
@@ -1771,7 +1843,8 @@ export declare const enum KnownEventName {
|
|
|
1771
1843
|
InputLatencyMouseWheel = "InputLatency::MouseWheel",
|
|
1772
1844
|
ImplSideFling = "InputHandlerProxy::HandleGestureFling::started",
|
|
1773
1845
|
SchedulePostMessage = "SchedulePostMessage",
|
|
1774
|
-
HandlePostMessage = "HandlePostMessage"
|
|
1846
|
+
HandlePostMessage = "HandlePostMessage",
|
|
1847
|
+
RenderFrameImplCreateChildFrame = "RenderFrameImpl::createChildFrame"
|
|
1775
1848
|
}
|
|
1776
1849
|
export declare const Categories: {
|
|
1777
1850
|
readonly Console: "blink.console";
|
|
@@ -68,10 +68,13 @@ export function isTraceEventBeginCommitCompositorFrame(event) {
|
|
|
68
68
|
export function isTraceEventScheduleStyleRecalculation(event) {
|
|
69
69
|
return event.name === "ScheduleStyleRecalculation" /* KnownEventName.ScheduleStyleRecalculation */;
|
|
70
70
|
}
|
|
71
|
+
export function isTraceEventRenderFrameImplCreateChildFrame(event) {
|
|
72
|
+
return event.name === "RenderFrameImpl::createChildFrame" /* KnownEventName.RenderFrameImplCreateChildFrame */;
|
|
73
|
+
}
|
|
71
74
|
export function isTraceEventPipelineReporter(event) {
|
|
72
75
|
return event.name === "PipelineReporter" /* KnownEventName.PipelineReporter */;
|
|
73
76
|
}
|
|
74
|
-
export function
|
|
77
|
+
export function isSyntheticBasedEvent(event) {
|
|
75
78
|
return 'rawSourceEvent' in event;
|
|
76
79
|
}
|
|
77
80
|
export function isSyntheticInteractionEvent(event) {
|
|
@@ -155,6 +158,13 @@ class CallFrameIdTag {
|
|
|
155
158
|
export function CallFrameID(value) {
|
|
156
159
|
return value;
|
|
157
160
|
}
|
|
161
|
+
class SampleIndexTag {
|
|
162
|
+
#sampleIndexTag;
|
|
163
|
+
}
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
165
|
+
export function SampleIndex(value) {
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
158
168
|
class ProcessIdTag {
|
|
159
169
|
#processIdTag;
|
|
160
170
|
}
|
|
@@ -408,6 +418,21 @@ export function isTraceEventRequestIdleCallback(event) {
|
|
|
408
418
|
export function isTraceEventWebSocketCreate(event) {
|
|
409
419
|
return event.name === "WebSocketCreate" /* KnownEventName.WebSocketCreate */;
|
|
410
420
|
}
|
|
421
|
+
export function isTraceEventWebSocketInfo(traceEventData) {
|
|
422
|
+
return traceEventData.name === "WebSocketSendHandshakeRequest" /* KnownEventName.WebSocketSendHandshakeRequest */ ||
|
|
423
|
+
traceEventData.name === "WebSocketReceiveHandshakeResponse" /* KnownEventName.WebSocketReceiveHandshakeResponse */ ||
|
|
424
|
+
traceEventData.name === "WebSocketDestroy" /* KnownEventName.WebSocketDestroy */;
|
|
425
|
+
}
|
|
426
|
+
export function isTraceEventWebSocketTransfer(traceEventData) {
|
|
427
|
+
return traceEventData.name === "WebSocketSend" /* KnownEventName.WebSocketSend */ ||
|
|
428
|
+
traceEventData.name === "WebSocketReceive" /* KnownEventName.WebSocketReceive */;
|
|
429
|
+
}
|
|
430
|
+
export function isTraceEventWebSocketSend(event) {
|
|
431
|
+
return event.name === "WebSocketSend" /* KnownEventName.WebSocketSend */;
|
|
432
|
+
}
|
|
433
|
+
export function isTraceEventWebSocketReceive(event) {
|
|
434
|
+
return event.name === "WebSocketReceive" /* KnownEventName.WebSocketReceive */;
|
|
435
|
+
}
|
|
411
436
|
export function isTraceEventWebSocketSendHandshakeRequest(event) {
|
|
412
437
|
return event.name === "WebSocketSendHandshakeRequest" /* KnownEventName.WebSocketSendHandshakeRequest */;
|
|
413
438
|
}
|
|
@@ -418,8 +443,7 @@ export function isTraceEventWebSocketDestroy(event) {
|
|
|
418
443
|
return event.name === "WebSocketDestroy" /* KnownEventName.WebSocketDestroy */;
|
|
419
444
|
}
|
|
420
445
|
export function isWebSocketTraceEvent(event) {
|
|
421
|
-
return isTraceEventWebSocketCreate(event) ||
|
|
422
|
-
isTraceEventWebSocketReceiveHandshakeResponse(event) || isTraceEventWebSocketSendHandshakeRequest(event);
|
|
446
|
+
return isTraceEventWebSocketCreate(event) || isTraceEventWebSocketInfo(event) || isTraceEventWebSocketTransfer(event);
|
|
423
447
|
}
|
|
424
448
|
export function isTraceEventV8Compile(event) {
|
|
425
449
|
return event.name === "v8.compile" /* KnownEventName.Compile */;
|