@paulirish/trace_engine 0.0.10 → 0.0.11
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/analyze-trace.mjs +1 -1
- package/core/platform/DevToolsPath.d.ts +4 -13
- package/core/platform/DevToolsPath.js +7 -4
- package/core/platform/DevToolsPath.js.map +1 -7
- package/core/platform/MimeType.d.ts +27 -0
- package/core/platform/MimeType.js +119 -86
- package/core/platform/MimeType.js.map +1 -7
- package/core/platform/Timing.d.ts +7 -0
- package/core/platform/Timing.js +7 -4
- package/core/platform/Timing.js.map +1 -7
- package/core/platform/UIString.d.ts +2 -5
- package/core/platform/UIString.js +5 -2
- package/core/platform/UIString.js.map +1 -7
- package/core/platform/UserVisibleError.js +19 -10
- package/core/platform/UserVisibleError.js.map +1 -7
- package/core/platform/array-utilities.d.ts +48 -10
- package/core/platform/array-utilities.js +160 -124
- package/core/platform/array-utilities.js.map +1 -7
- package/core/platform/brand.d.ts +14 -0
- package/core/platform/brand.js +5 -1
- package/core/platform/brand.js.map +1 -7
- package/core/platform/date-utilities.js +10 -6
- package/core/platform/date-utilities.js.map +1 -7
- package/core/platform/dom-utilities.d.ts +3 -1
- package/core/platform/dom-utilities.js +94 -83
- package/core/platform/dom-utilities.js.map +1 -7
- package/core/platform/keyboard-utilities.d.ts +2 -0
- package/core/platform/keyboard-utilities.js +15 -24
- package/core/platform/keyboard-utilities.js.map +1 -7
- package/core/platform/map-utilities.d.ts +4 -0
- package/core/platform/map-utilities.js +66 -60
- package/core/platform/map-utilities.js.map +1 -7
- package/core/platform/number-utilities.js +66 -55
- package/core/platform/number-utilities.js.map +1 -7
- package/core/platform/platform.d.ts +5 -1
- package/core/platform/platform.js +54 -37
- package/core/platform/platform.js.map +1 -7
- package/core/platform/promise-utilities.d.ts +10 -0
- package/core/platform/promise-utilities.js +16 -8
- package/core/platform/promise-utilities.js.map +1 -7
- package/core/platform/set-utilities.js +20 -17
- package/core/platform/set-utilities.js.map +1 -7
- package/core/platform/string-utilities.d.ts +32 -1
- package/core/platform/string-utilities.js +453 -379
- package/core/platform/string-utilities.js.map +1 -7
- package/core/platform/typescript-utilities.d.ts +5 -5
- package/core/platform/typescript-utilities.js +19 -7
- package/core/platform/typescript-utilities.js.map +1 -7
- package/generated/protocol.d.ts +2081 -347
- package/generated/protocol.js +5 -2230
- package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
- package/models/cpu_profile/CPUProfileDataModel.js +492 -359
- package/models/cpu_profile/CPUProfileDataModel.js.map +1 -7
- package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
- package/models/cpu_profile/ProfileTreeModel.js +87 -82
- package/models/cpu_profile/ProfileTreeModel.js.map +1 -7
- package/models/cpu_profile/cpu_profile.d.ts +3 -0
- package/models/cpu_profile/cpu_profile.js +7 -7
- package/models/cpu_profile/cpu_profile.js.map +1 -7
- package/models/trace/EntriesFilter.d.ts +55 -0
- package/models/trace/EntriesFilter.js +227 -166
- package/models/trace/EntriesFilter.js.map +1 -7
- package/models/trace/LegacyTracingModel.js.map +1 -7
- package/models/trace/ModelImpl.d.ts +110 -0
- package/models/trace/ModelImpl.js +161 -102
- package/models/trace/ModelImpl.js.map +1 -7
- package/models/trace/Processor.d.ts +36 -0
- package/models/trace/Processor.js +197 -163
- package/models/trace/Processor.js.map +1 -7
- package/models/trace/TracingManager.js.map +1 -7
- package/models/trace/extras/FetchNodes.d.ts +46 -0
- package/models/trace/extras/FetchNodes.js +132 -91
- package/models/trace/extras/FetchNodes.js.map +1 -7
- package/models/trace/extras/FilmStrip.d.ts +19 -0
- package/models/trace/extras/FilmStrip.js +38 -31
- package/models/trace/extras/FilmStrip.js.map +1 -7
- package/models/trace/extras/MainThreadActivity.d.ts +2 -0
- package/models/trace/extras/MainThreadActivity.js +72 -56
- package/models/trace/extras/MainThreadActivity.js.map +1 -7
- package/models/trace/extras/Metadata.d.ts +2 -0
- package/models/trace/extras/Metadata.js +42 -26
- package/models/trace/extras/Metadata.js.map +1 -7
- package/models/trace/extras/extras.js.map +1 -7
- package/models/trace/handlers/AnimationHandler.d.ts +8 -0
- package/models/trace/handlers/AnimationHandler.js +22 -20
- package/models/trace/handlers/AnimationHandler.js.map +1 -7
- package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
- package/models/trace/handlers/AuctionWorkletsHandler.js +143 -89
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -7
- package/models/trace/handlers/FramesHandler.d.ts +76 -0
- package/models/trace/handlers/FramesHandler.js +424 -355
- package/models/trace/handlers/FramesHandler.js.map +1 -7
- package/models/trace/handlers/GPUHandler.d.ts +11 -0
- package/models/trace/handlers/GPUHandler.js +41 -37
- package/models/trace/handlers/GPUHandler.js.map +1 -7
- package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
- package/models/trace/handlers/InitiatorsHandler.js +164 -113
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -7
- package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
- package/models/trace/handlers/InvalidationsHandler.js +101 -79
- package/models/trace/handlers/InvalidationsHandler.js.map +1 -7
- package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
- package/models/trace/handlers/LargestImagePaintHandler.js +32 -12
- package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -7
- package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
- package/models/trace/handlers/LargestTextPaintHandler.js +20 -12
- package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -7
- package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
- package/models/trace/handlers/LayerTreeHandler.js +96 -70
- package/models/trace/handlers/LayerTreeHandler.js.map +1 -7
- package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
- package/models/trace/handlers/LayoutShiftsHandler.js +304 -227
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -7
- package/models/trace/handlers/MemoryHandler.d.ts +7 -0
- package/models/trace/handlers/MemoryHandler.js +14 -11
- package/models/trace/handlers/MemoryHandler.js.map +1 -7
- package/models/trace/handlers/MetaHandler.d.ts +37 -0
- package/models/trace/handlers/MetaHandler.js +314 -226
- package/models/trace/handlers/MetaHandler.js.map +1 -7
- package/models/trace/handlers/ModelHandlers.d.ts +21 -0
- package/models/trace/handlers/ModelHandlers.js +25 -22
- package/models/trace/handlers/ModelHandlers.js.map +1 -7
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +342 -218
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -7
- package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
- package/models/trace/handlers/PageLoadMetricsHandler.js +357 -284
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -7
- package/models/trace/handlers/RendererHandler.d.ts +101 -0
- package/models/trace/handlers/RendererHandler.js +295 -191
- package/models/trace/handlers/RendererHandler.js.map +1 -7
- package/models/trace/handlers/SamplesHandler.d.ts +46 -0
- package/models/trace/handlers/SamplesHandler.js +195 -158
- package/models/trace/handlers/SamplesHandler.js.map +1 -7
- package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
- package/models/trace/handlers/ScreenshotsHandler.js +63 -41
- package/models/trace/handlers/ScreenshotsHandler.js.map +1 -7
- package/models/trace/handlers/Threads.d.ts +33 -0
- package/models/trace/handlers/Threads.js +85 -67
- package/models/trace/handlers/Threads.js.map +1 -7
- package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
- package/models/trace/handlers/UserInteractionsHandler.js +240 -141
- package/models/trace/handlers/UserInteractionsHandler.js.map +1 -7
- package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
- package/models/trace/handlers/UserTimingsHandler.js +91 -80
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -7
- package/models/trace/handlers/WarningsHandler.d.ts +14 -0
- package/models/trace/handlers/WarningsHandler.js +100 -62
- package/models/trace/handlers/WarningsHandler.js.map +1 -7
- package/models/trace/handlers/WorkersHandler.d.ts +11 -0
- package/models/trace/handlers/WorkersHandler.js +40 -38
- package/models/trace/handlers/WorkersHandler.js.map +1 -7
- package/models/trace/handlers/handlers.d.ts +3 -0
- package/models/trace/handlers/handlers.js +7 -4
- package/models/trace/handlers/handlers.js.map +1 -7
- package/models/trace/handlers/types.d.ts +45 -0
- package/models/trace/handlers/types.js +15 -15
- package/models/trace/handlers/types.js.map +1 -7
- package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
- package/models/trace/helpers/SamplesIntegrator.js +381 -204
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -7
- package/models/trace/helpers/Timing.d.ts +26 -0
- package/models/trace/helpers/Timing.js +131 -110
- package/models/trace/helpers/Timing.js.map +1 -7
- package/models/trace/helpers/Trace.d.ts +37 -0
- package/models/trace/helpers/Trace.js +200 -166
- package/models/trace/helpers/Trace.js.map +1 -7
- package/models/trace/helpers/TreeHelpers.d.ts +90 -0
- package/models/trace/helpers/TreeHelpers.js +203 -100
- package/models/trace/helpers/TreeHelpers.js.map +1 -7
- package/models/trace/helpers/helpers.d.ts +4 -0
- package/models/trace/helpers/helpers.js +8 -5
- package/models/trace/helpers/helpers.js.map +1 -7
- package/models/trace/root-causes/LayoutShift.d.ts +119 -0
- package/models/trace/root-causes/LayoutShift.js +470 -323
- package/models/trace/root-causes/LayoutShift.js.map +1 -7
- package/models/trace/root-causes/RootCauses.d.ts +14 -0
- package/models/trace/root-causes/RootCauses.js +9 -6
- package/models/trace/root-causes/RootCauses.js.map +1 -7
- package/models/trace/root-causes/root-causes.d.ts +1 -0
- package/models/trace/root-causes/root-causes.js +5 -2
- package/models/trace/root-causes/root-causes.js.map +1 -7
- package/models/trace/trace.d.ts +11 -0
- package/models/trace/trace.js +17 -23
- package/models/trace/trace.js.map +1 -7
- package/models/trace/types/Configuration.d.ts +33 -0
- package/models/trace/types/Configuration.js +25 -14
- package/models/trace/types/Configuration.js.map +1 -7
- package/models/trace/types/File.d.ts +23 -0
- package/models/trace/types/File.js +5 -6
- package/models/trace/types/File.js.map +1 -7
- package/models/trace/types/Timing.d.ts +25 -0
- package/models/trace/types/Timing.js +10 -11
- package/models/trace/types/Timing.js.map +1 -7
- package/models/trace/types/TraceEvents.d.ts +1571 -0
- package/models/trace/types/TraceEvents.js +174 -381
- package/models/trace/types/TraceEvents.js.map +1 -7
- package/models/trace/types/types.d.ts +4 -0
- package/models/trace/types/types.js +8 -5
- package/models/trace/types/types.js.map +1 -7
- package/package.json +1 -1
- package/TracingManager.js +0 -0
- package/extras/extras.js +0 -0
- package/trace.mjs +0 -6980
- package/trace.mjs.map +0 -8
|
@@ -1,90 +1,116 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
1
|
+
// Copyright 2023 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
import * as Helpers from '../helpers/helpers.js';
|
|
5
|
+
import * as Types from '../types/types.js';
|
|
6
|
+
import { data as metaHandlerData } from './MetaHandler.js';
|
|
7
|
+
let handlerState = 1 /* HandlerState.UNINITIALIZED */;
|
|
6
8
|
const paintEvents = [];
|
|
7
9
|
const snapshotEvents = [];
|
|
8
|
-
const paintToSnapshotMap =
|
|
10
|
+
const paintToSnapshotMap = new Map();
|
|
9
11
|
let lastPaintForLayerId = {};
|
|
10
12
|
let currentMainFrameLayerTreeId = null;
|
|
11
13
|
const updateLayerEvents = [];
|
|
12
14
|
const relevantEvents = [];
|
|
13
15
|
export function reset() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
handlerState = 1 /* HandlerState.UNINITIALIZED */;
|
|
17
|
+
paintEvents.length = 0;
|
|
18
|
+
snapshotEvents.length = 0;
|
|
19
|
+
paintToSnapshotMap.clear();
|
|
20
|
+
lastPaintForLayerId = {};
|
|
21
|
+
currentMainFrameLayerTreeId = null;
|
|
22
|
+
updateLayerEvents.length = 0;
|
|
23
|
+
relevantEvents.length = 0;
|
|
22
24
|
}
|
|
23
25
|
export function initialize() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
if (handlerState !== 1 /* HandlerState.UNINITIALIZED */) {
|
|
27
|
+
throw new Error('LayerTree Handler was not reset before being initialized');
|
|
28
|
+
}
|
|
29
|
+
handlerState = 2 /* HandlerState.INITIALIZED */;
|
|
28
30
|
}
|
|
29
31
|
export function handleEvent(event) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
// We gather up the events here but do all the processing in finalize(). This
|
|
33
|
+
// is because we need to have all the events before we process them, and we
|
|
34
|
+
// need the Meta handler to be finalized() so we can use its data as we need
|
|
35
|
+
// the mainFrameId to know which Layer(s) to care about.
|
|
36
|
+
if (Types.TraceEvents.isTraceEventPaint(event) || Types.TraceEvents.isTraceEventDisplayListItemListSnapshot(event) ||
|
|
37
|
+
Types.TraceEvents.isTraceEventUpdateLayer(event) || Types.TraceEvents.isTraceEventSetLayerId(event)) {
|
|
38
|
+
relevantEvents.push(event);
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
export async function finalize() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
42
|
+
if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
|
|
43
|
+
throw new Error('LayerTree Handler is not initialized');
|
|
44
|
+
}
|
|
45
|
+
const metaData = metaHandlerData();
|
|
46
|
+
Helpers.Trace.sortTraceEventsInPlace(relevantEvents);
|
|
47
|
+
for (const event of relevantEvents) {
|
|
48
|
+
if (Types.TraceEvents.isTraceEventSetLayerId(event)) {
|
|
49
|
+
if (metaData.mainFrameId !== event.args.data.frame) {
|
|
50
|
+
// We only care about LayerId changes that affect the main frame.
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
currentMainFrameLayerTreeId = event.args.data.layerTreeId;
|
|
54
|
+
}
|
|
55
|
+
else if (Types.TraceEvents.isTraceEventUpdateLayer(event)) {
|
|
56
|
+
// We don't do anything with this event, but we need to store it because
|
|
57
|
+
// the information in it determines if we need to care about future
|
|
58
|
+
// snapshot events - we need to know what the active layer is when we see a
|
|
59
|
+
// snapshot.
|
|
60
|
+
updateLayerEvents.push(event);
|
|
61
|
+
}
|
|
62
|
+
else if (Types.TraceEvents.isTraceEventPaint(event)) {
|
|
63
|
+
if (!event.args.data.layerId) {
|
|
64
|
+
// Note that this check purposefully includes excluding an event with a layerId of 0.
|
|
65
|
+
// 0 indicates that this paint was for a subframe - we do not want these
|
|
66
|
+
// as we only care about paints for top level frames.
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
paintEvents.push(event);
|
|
70
|
+
lastPaintForLayerId[event.args.data.layerId] = event;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
else if (Types.TraceEvents.isTraceEventDisplayListItemListSnapshot(event)) {
|
|
74
|
+
// First we figure out which layer is active for this event's thread. To
|
|
75
|
+
// do this we work backwards through the list of UpdateLayerEvents,
|
|
76
|
+
// finding the first one (i.e. the most recent one) with the same pid and
|
|
77
|
+
// tid.
|
|
78
|
+
let lastUpdateLayerEventForThread = null;
|
|
79
|
+
for (let i = updateLayerEvents.length - 1; i > -1; i--) {
|
|
80
|
+
const updateEvent = updateLayerEvents[i];
|
|
81
|
+
if (updateEvent.pid === event.pid && updateEvent.tid === event.tid) {
|
|
82
|
+
lastUpdateLayerEventForThread = updateEvent;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!lastUpdateLayerEventForThread) {
|
|
87
|
+
// No active layer, so this snapshot is not relevant.
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (lastUpdateLayerEventForThread.args.layerTreeId !== currentMainFrameLayerTreeId) {
|
|
91
|
+
// Snapshot applies to a layer that is not the main frame, so discard.
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const paintEvent = lastPaintForLayerId[lastUpdateLayerEventForThread.args.layerId];
|
|
95
|
+
if (!paintEvent) {
|
|
96
|
+
// No paint event for this layer, so discard.
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
snapshotEvents.push(event);
|
|
100
|
+
// Store the relationship between the paint and the snapshot.
|
|
101
|
+
paintToSnapshotMap.set(paintEvent, event);
|
|
62
102
|
}
|
|
63
|
-
}
|
|
64
|
-
if (!lastUpdateLayerEventForThread) {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (lastUpdateLayerEventForThread.args.layerTreeId !== currentMainFrameLayerTreeId) {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
const paintEvent = lastPaintForLayerId[lastUpdateLayerEventForThread.args.layerId];
|
|
71
|
-
if (!paintEvent) {
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
snapshotEvents.push(event);
|
|
75
|
-
paintToSnapshotMap.set(paintEvent, event);
|
|
76
103
|
}
|
|
77
|
-
|
|
78
|
-
handlerState = HandlerState.FINALIZED;
|
|
104
|
+
handlerState = 3 /* HandlerState.FINALIZED */;
|
|
79
105
|
}
|
|
80
106
|
export function data() {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
107
|
+
return {
|
|
108
|
+
paints: Array.from(paintEvents),
|
|
109
|
+
snapshots: Array.from(snapshotEvents),
|
|
110
|
+
paintsToSnapshots: new Map(paintToSnapshotMap),
|
|
111
|
+
};
|
|
86
112
|
}
|
|
87
113
|
export function deps() {
|
|
88
|
-
|
|
114
|
+
return ['Meta'];
|
|
89
115
|
}
|
|
90
|
-
//# sourceMappingURL=LayerTreeHandler.js.map
|
|
116
|
+
//# sourceMappingURL=LayerTreeHandler.js.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../../../front_end/models/trace/handlers/LayerTreeHandler.ts"],
|
|
4
|
-
"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.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport {HandlerState, type TraceEventHandlerName} from './types.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst paintEvents: Types.TraceEvents.TraceEventPaint[] = [];\nconst snapshotEvents: Types.TraceEvents.TraceEventDisplayItemListSnapshot[] = [];\nconst paintToSnapshotMap =\n new Map<Types.TraceEvents.TraceEventPaint, Types.TraceEvents.TraceEventDisplayItemListSnapshot>();\n\nlet lastPaintForLayerId: Record<number, Types.TraceEvents.TraceEventPaint> = {};\n\nlet currentMainFrameLayerTreeId: number|null = null;\nconst updateLayerEvents: Types.TraceEvents.TraceEventUpdateLayer[] = [];\n\ntype RelevantLayerTreeEvent = Types.TraceEvents.TraceEventPaint|\n Types.TraceEvents.TraceEventDisplayItemListSnapshot|\n Types.TraceEvents.TraceEventUpdateLayer|Types.TraceEvents.TraceEventSetLayerTreeId;\n\nconst relevantEvents: RelevantLayerTreeEvent[] = [];\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n paintEvents.length = 0;\n snapshotEvents.length = 0;\n paintToSnapshotMap.clear();\n\n lastPaintForLayerId = {};\n currentMainFrameLayerTreeId = null;\n updateLayerEvents.length = 0;\n relevantEvents.length = 0;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('LayerTree Handler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n // We gather up the events here but do all the processing in finalize(). This\n // is because we need to have all the events before we process them, and we\n // need the Meta handler to be finalized() so we can use its data as we need\n // the mainFrameId to know which Layer(s) to care about.\n if (Types.TraceEvents.isTraceEventPaint(event) || Types.TraceEvents.isTraceEventDisplayListItemListSnapshot(event) ||\n Types.TraceEvents.isTraceEventUpdateLayer(event) || Types.TraceEvents.isTraceEventSetLayerId(event)) {\n relevantEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('LayerTree Handler is not initialized');\n }\n\n const metaData = metaHandlerData();\n Helpers.Trace.sortTraceEventsInPlace(relevantEvents);\n\n for (const event of relevantEvents) {\n if (Types.TraceEvents.isTraceEventSetLayerId(event)) {\n if (metaData.mainFrameId !== event.args.data.frame) {\n // We only care about LayerId changes that affect the main frame.\n continue;\n }\n currentMainFrameLayerTreeId = event.args.data.layerTreeId;\n } else if (Types.TraceEvents.isTraceEventUpdateLayer(event)) {\n // We don't do anything with this event, but we need to store it because\n // the information in it determines if we need to care about future\n // snapshot events - we need to know what the active layer is when we see a\n // snapshot.\n updateLayerEvents.push(event);\n } else if (Types.TraceEvents.isTraceEventPaint(event)) {\n if (!event.args.data.layerId) {\n // Note that this check purposefully includes excluding an event with a layerId of 0.\n // 0 indicates that this paint was for a subframe - we do not want these\n // as we only care about paints for top level frames.\n continue;\n }\n paintEvents.push(event);\n lastPaintForLayerId[event.args.data.layerId] = event;\n continue;\n } else if (Types.TraceEvents.isTraceEventDisplayListItemListSnapshot(event)) {\n // First we figure out which layer is active for this event's thread. To\n // do this we work backwards through the list of UpdateLayerEvents,\n // finding the first one (i.e. the most recent one) with the same pid and\n // tid.\n let lastUpdateLayerEventForThread: Types.TraceEvents.TraceEventUpdateLayer|null = null;\n for (let i = updateLayerEvents.length - 1; i > -1; i--) {\n const updateEvent = updateLayerEvents[i];\n if (updateEvent.pid === event.pid && updateEvent.tid === event.tid) {\n lastUpdateLayerEventForThread = updateEvent;\n break;\n }\n }\n if (!lastUpdateLayerEventForThread) {\n // No active layer, so this snapshot is not relevant.\n continue;\n }\n if (lastUpdateLayerEventForThread.args.layerTreeId !== currentMainFrameLayerTreeId) {\n // Snapshot applies to a layer that is not the main frame, so discard.\n continue;\n }\n const paintEvent = lastPaintForLayerId[lastUpdateLayerEventForThread.args.layerId];\n if (!paintEvent) {\n // No paint event for this layer, so discard.\n continue;\n }\n snapshotEvents.push(event);\n\n // Store the relationship between the paint and the snapshot.\n paintToSnapshotMap.set(paintEvent, event);\n }\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport interface LayerTreeData {\n paints: Types.TraceEvents.TraceEventPaint[];\n snapshots: Types.TraceEvents.TraceEventDisplayItemListSnapshot[];\n paintsToSnapshots: Map<Types.TraceEvents.TraceEventPaint, Types.TraceEvents.TraceEventDisplayItemListSnapshot>;\n}\n\nexport function data(): LayerTreeData {\n return {\n paints: Array.from(paintEvents),\n snapshots: Array.from(snapshotEvents),\n paintsToSnapshots: new Map(paintToSnapshotMap),\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"],
|
|
5
|
-
"mappings": "AAIA;AACA;AAEA;AACA;AAEA,IAAI,eAAe,aAAa;AAEhC,MAAM,cAAmD;AACzD,MAAM,iBAAwE;AAC9E,MAAM,qBACF,oBAAI;AAER,IAAI,sBAAyE;AAE7E,IAAI,8BAA2C;AAC/C,MAAM,oBAA+D;AAMrE,MAAM,iBAA2C;AAC1C,wBAAuB;AAC5B,iBAAe,aAAa;AAC5B,cAAY,SAAS;AACrB,iBAAe,SAAS;AACxB,qBAAmB;AAEnB,wBAAsB;AACtB,gCAA8B;AAC9B,oBAAkB,SAAS;AAC3B,iBAAe,SAAS;AAAA;AAGnB,6BAA4B;AACjC,MAAI,iBAAiB,aAAa,eAAe;AAC/C,UAAM,IAAI,MAAM;AAAA;AAGlB,iBAAe,aAAa;AAAA;AAGvB,4BAAqB,OAA+C;AAKzE,MAAI,MAAM,YAAY,kBAAkB,UAAU,MAAM,YAAY,wCAAwC,UACxG,MAAM,YAAY,wBAAwB,UAAU,MAAM,YAAY,uBAAuB,QAAQ;AACvG,mBAAe,KAAK;AAAA;AAAA;AAIxB,iCAAgD;AAC9C,MAAI,iBAAiB,aAAa,aAAa;AAC7C,UAAM,IAAI,MAAM;AAAA;AAGlB,QAAM,WAAW;AACjB,UAAQ,MAAM,uBAAuB;AAErC,aAAW,SAAS,gBAAgB;AAClC,QAAI,MAAM,YAAY,uBAAuB,QAAQ;AACnD,UAAI,SAAS,gBAAgB,MAAM,KAAK,KAAK,OAAO;AAElD;AAAA;AAEF,oCAA8B,MAAM,KAAK,KAAK;AAAA,eACrC,MAAM,YAAY,wBAAwB,QAAQ;AAK3D,wBAAkB,KAAK;AAAA,eACd,MAAM,YAAY,kBAAkB,QAAQ;AACrD,UAAI,CAAC,MAAM,KAAK,KAAK,SAAS;AAI5B;AAAA;AAEF,kBAAY,KAAK;AACjB,0BAAoB,MAAM,KAAK,KAAK,WAAW;AAC/C;AAAA,eACS,MAAM,YAAY,wCAAwC,QAAQ;AAK3E,UAAI,gCAA8E;AAClF,eAAS,IAAI,kBAAkB,SAAS,GAAG,IAAI,IAAI,KAAK;AACtD,cAAM,cAAc,kBAAkB;AACtC,YAAI,YAAY,QAAQ,MAAM,OAAO,YAAY,QAAQ,MAAM,KAAK;AAClE,0CAAgC;AAChC;AAAA;AAAA;AAGJ,UAAI,CAAC,+BAA+B;AAElC;AAAA;AAEF,UAAI,8BAA8B,KAAK,gBAAgB,6BAA6B;AAElF;AAAA;AAEF,YAAM,aAAa,oBAAoB,8BAA8B,KAAK;AAC1E,UAAI,CAAC,YAAY;AAEf;AAAA;AAEF,qBAAe,KAAK;AAGpB,yBAAmB,IAAI,YAAY;AAAA;AAAA;AAIvC,iBAAe,aAAa;AAAA;AASvB,uBAA+B;AACpC,SAAO;AAAA,IACL,QAAQ,MAAM,KAAK;AAAA,IACnB,WAAW,MAAM,KAAK;AAAA,IACtB,mBAAmB,IAAI,IAAI;AAAA;AAAA;AAIxB,uBAAyC;AAC9C,SAAO,CAAC;AAAA;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"LayerTreeHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/LayerTreeHandler.ts"],"names":[],"mappings":"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","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.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport {HandlerState, type TraceEventHandlerName} from './types.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst paintEvents: Types.TraceEvents.TraceEventPaint[] = [];\nconst snapshotEvents: Types.TraceEvents.TraceEventDisplayItemListSnapshot[] = [];\nconst paintToSnapshotMap =\n new Map<Types.TraceEvents.TraceEventPaint, Types.TraceEvents.TraceEventDisplayItemListSnapshot>();\n\nlet lastPaintForLayerId: Record<number, Types.TraceEvents.TraceEventPaint> = {};\n\nlet currentMainFrameLayerTreeId: number|null = null;\nconst updateLayerEvents: Types.TraceEvents.TraceEventUpdateLayer[] = [];\n\ntype RelevantLayerTreeEvent = Types.TraceEvents.TraceEventPaint|\n Types.TraceEvents.TraceEventDisplayItemListSnapshot|\n Types.TraceEvents.TraceEventUpdateLayer|Types.TraceEvents.TraceEventSetLayerTreeId;\n\nconst relevantEvents: RelevantLayerTreeEvent[] = [];\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n paintEvents.length = 0;\n snapshotEvents.length = 0;\n paintToSnapshotMap.clear();\n\n lastPaintForLayerId = {};\n currentMainFrameLayerTreeId = null;\n updateLayerEvents.length = 0;\n relevantEvents.length = 0;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('LayerTree Handler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n // We gather up the events here but do all the processing in finalize(). This\n // is because we need to have all the events before we process them, and we\n // need the Meta handler to be finalized() so we can use its data as we need\n // the mainFrameId to know which Layer(s) to care about.\n if (Types.TraceEvents.isTraceEventPaint(event) || Types.TraceEvents.isTraceEventDisplayListItemListSnapshot(event) ||\n Types.TraceEvents.isTraceEventUpdateLayer(event) || Types.TraceEvents.isTraceEventSetLayerId(event)) {\n relevantEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('LayerTree Handler is not initialized');\n }\n\n const metaData = metaHandlerData();\n Helpers.Trace.sortTraceEventsInPlace(relevantEvents);\n\n for (const event of relevantEvents) {\n if (Types.TraceEvents.isTraceEventSetLayerId(event)) {\n if (metaData.mainFrameId !== event.args.data.frame) {\n // We only care about LayerId changes that affect the main frame.\n continue;\n }\n currentMainFrameLayerTreeId = event.args.data.layerTreeId;\n } else if (Types.TraceEvents.isTraceEventUpdateLayer(event)) {\n // We don't do anything with this event, but we need to store it because\n // the information in it determines if we need to care about future\n // snapshot events - we need to know what the active layer is when we see a\n // snapshot.\n updateLayerEvents.push(event);\n } else if (Types.TraceEvents.isTraceEventPaint(event)) {\n if (!event.args.data.layerId) {\n // Note that this check purposefully includes excluding an event with a layerId of 0.\n // 0 indicates that this paint was for a subframe - we do not want these\n // as we only care about paints for top level frames.\n continue;\n }\n paintEvents.push(event);\n lastPaintForLayerId[event.args.data.layerId] = event;\n continue;\n } else if (Types.TraceEvents.isTraceEventDisplayListItemListSnapshot(event)) {\n // First we figure out which layer is active for this event's thread. To\n // do this we work backwards through the list of UpdateLayerEvents,\n // finding the first one (i.e. the most recent one) with the same pid and\n // tid.\n let lastUpdateLayerEventForThread: Types.TraceEvents.TraceEventUpdateLayer|null = null;\n for (let i = updateLayerEvents.length - 1; i > -1; i--) {\n const updateEvent = updateLayerEvents[i];\n if (updateEvent.pid === event.pid && updateEvent.tid === event.tid) {\n lastUpdateLayerEventForThread = updateEvent;\n break;\n }\n }\n if (!lastUpdateLayerEventForThread) {\n // No active layer, so this snapshot is not relevant.\n continue;\n }\n if (lastUpdateLayerEventForThread.args.layerTreeId !== currentMainFrameLayerTreeId) {\n // Snapshot applies to a layer that is not the main frame, so discard.\n continue;\n }\n const paintEvent = lastPaintForLayerId[lastUpdateLayerEventForThread.args.layerId];\n if (!paintEvent) {\n // No paint event for this layer, so discard.\n continue;\n }\n snapshotEvents.push(event);\n\n // Store the relationship between the paint and the snapshot.\n paintToSnapshotMap.set(paintEvent, event);\n }\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport interface LayerTreeData {\n paints: Types.TraceEvents.TraceEventPaint[];\n snapshots: Types.TraceEvents.TraceEventDisplayItemListSnapshot[];\n paintsToSnapshots: Map<Types.TraceEvents.TraceEventPaint, Types.TraceEvents.TraceEventDisplayItemListSnapshot>;\n}\n\nexport function data(): LayerTreeData {\n return {\n paints: Array.from(paintEvents),\n snapshots: Array.from(snapshotEvents),\n paintsToSnapshots: new Map(paintToSnapshotMap),\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
|
2
|
+
import * as Types from '../types/types.js';
|
|
3
|
+
import { ScoreClassification } from './PageLoadMetricsHandler.js';
|
|
4
|
+
import { type TraceEventHandlerName } from './types.js';
|
|
5
|
+
interface LayoutShifts {
|
|
6
|
+
clusters: LayoutShiftCluster[];
|
|
7
|
+
sessionMaxScore: number;
|
|
8
|
+
clsWindowID: number;
|
|
9
|
+
prePaintEvents: Types.TraceEvents.TraceEventPrePaint[];
|
|
10
|
+
layoutInvalidationEvents: Types.TraceEvents.TraceEventLayoutInvalidationTracking[];
|
|
11
|
+
scheduleStyleInvalidationEvents: Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking[];
|
|
12
|
+
styleRecalcInvalidationEvents: Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking[];
|
|
13
|
+
scoreRecords: ScoreRecord[];
|
|
14
|
+
backendNodeIds: Protocol.DOM.BackendNodeId[];
|
|
15
|
+
}
|
|
16
|
+
export declare const MAX_CLUSTER_DURATION: Types.Timing.MicroSeconds;
|
|
17
|
+
export declare const MAX_SHIFT_TIME_DELTA: Types.Timing.MicroSeconds;
|
|
18
|
+
type ScoreRecord = {
|
|
19
|
+
ts: number;
|
|
20
|
+
score: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function initialize(): void;
|
|
23
|
+
export declare function reset(): void;
|
|
24
|
+
export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
|
|
25
|
+
export declare function finalize(): Promise<void>;
|
|
26
|
+
export declare function data(): LayoutShifts;
|
|
27
|
+
export declare function deps(): TraceEventHandlerName[];
|
|
28
|
+
export declare function stateForLayoutShiftScore(score: number): ScoreClassification;
|
|
29
|
+
export interface LayoutShiftCluster {
|
|
30
|
+
clusterWindow: Types.Timing.TraceWindowMicroSeconds;
|
|
31
|
+
clusterCumulativeScore: number;
|
|
32
|
+
events: Types.TraceEvents.SyntheticLayoutShift[];
|
|
33
|
+
scoreWindows: {
|
|
34
|
+
good: Types.Timing.TraceWindowMicroSeconds;
|
|
35
|
+
needsImprovement: Types.Timing.TraceWindowMicroSeconds | null;
|
|
36
|
+
bad: Types.Timing.TraceWindowMicroSeconds | null;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export declare const enum LayoutShiftsThreshold {
|
|
40
|
+
GOOD = 0,
|
|
41
|
+
NEEDS_IMPROVEMENT = 0.1,
|
|
42
|
+
BAD = 0.25
|
|
43
|
+
}
|
|
44
|
+
export {};
|