@paulirish/trace_engine 0.0.42 → 0.0.43

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.
Files changed (106) hide show
  1. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  2. package/locales/en-US.json +0 -12
  3. package/locales/en-XL.json +0 -12
  4. package/models/cpu_profile/CPUProfileDataModel.js +2 -2
  5. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
  6. package/models/trace/LanternComputationData.js +1 -1
  7. package/models/trace/LanternComputationData.js.map +1 -1
  8. package/models/trace/extras/TraceTree.d.ts +15 -2
  9. package/models/trace/extras/TraceTree.js +2 -2
  10. package/models/trace/extras/TraceTree.js.map +1 -1
  11. package/models/trace/extras/extras.d.ts +0 -1
  12. package/models/trace/extras/extras.js +0 -1
  13. package/models/trace/handlers/MetaHandler.js +3 -3
  14. package/models/trace/handlers/MetaHandler.js.map +1 -1
  15. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
  16. package/models/trace/handlers/RendererHandler.d.ts +1 -1
  17. package/models/trace/handlers/RendererHandler.js +1 -1
  18. package/models/trace/handlers/RendererHandler.js.map +1 -1
  19. package/models/trace/handlers/ScreenshotsHandler.js +1 -1
  20. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
  21. package/models/trace/helpers/SamplesIntegrator.d.ts +1 -1
  22. package/models/trace/helpers/SamplesIntegrator.js +2 -2
  23. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  24. package/models/trace/helpers/Trace.d.ts +1 -1
  25. package/models/trace/helpers/Trace.js +1 -1
  26. package/models/trace/helpers/Trace.js.map +1 -1
  27. package/models/trace/helpers/TreeHelpers.js +1 -1
  28. package/models/trace/helpers/TreeHelpers.js.map +1 -1
  29. package/models/trace/insights/CLSCulprits.d.ts +2 -0
  30. package/models/trace/insights/CLSCulprits.js +41 -8
  31. package/models/trace/insights/CLSCulprits.js.map +1 -1
  32. package/models/trace/insights/DocumentLatency.d.ts +2 -12
  33. package/models/trace/insights/DocumentLatency.js +23 -14
  34. package/models/trace/insights/DocumentLatency.js.map +1 -1
  35. package/models/trace/insights/LCPDiscovery.d.ts +2 -14
  36. package/models/trace/insights/LCPDiscovery.js +8 -16
  37. package/models/trace/insights/LCPDiscovery.js.map +1 -1
  38. package/models/trace/insights/types.d.ts +4 -0
  39. package/models/trace/insights/types.js.map +1 -1
  40. package/models/trace/lantern/graph/BaseNode.d.ts +1 -1
  41. package/models/trace/lantern/graph/BaseNode.js +1 -1
  42. package/models/trace/lantern/graph/BaseNode.js.map +1 -1
  43. package/models/trace/lantern/metrics/FirstContentfulPaint.d.ts +1 -1
  44. package/models/trace/lantern/metrics/FirstContentfulPaint.js.map +1 -1
  45. package/models/trace/lantern/simulation/ConnectionPool.js +1 -1
  46. package/models/trace/lantern/simulation/ConnectionPool.js.map +1 -1
  47. package/models/trace/lantern/simulation/Simulator.d.ts +2 -2
  48. package/models/trace/lantern/simulation/Simulator.js +3 -3
  49. package/models/trace/lantern/simulation/Simulator.js.map +1 -1
  50. package/models/trace/lantern/types/Lantern.d.ts +2 -2
  51. package/models/trace/lantern/types/Lantern.js.map +1 -1
  52. package/models/trace/root-causes/LayoutShift.d.ts +1 -1
  53. package/models/trace/root-causes/LayoutShift.js +4 -4
  54. package/models/trace/root-causes/LayoutShift.js.map +1 -1
  55. package/models/trace/types/TraceEvents.d.ts +2 -2
  56. package/models/trace/types/TraceEvents.js.map +1 -1
  57. package/package.json +1 -1
  58. package/core/platform/PromiseUtilities.d.ts +0 -10
  59. package/core/platform/PromiseUtilities.js +0 -18
  60. package/core/platform/PromiseUtilities.js.map +0 -1
  61. package/core/platform/SetUtilities.d.ts +0 -2
  62. package/core/platform/SetUtilities.js +0 -23
  63. package/core/platform/SetUtilities.js.map +0 -1
  64. package/models/trace/EntriesFilter.d.ts +0 -72
  65. package/models/trace/EntriesFilter.js +0 -296
  66. package/models/trace/EntriesFilter.js.map +0 -1
  67. package/models/trace/LegacyTracingModel.js.map +0 -1
  68. package/models/trace/extras/URLForEntry.d.ts +0 -13
  69. package/models/trace/extras/URLForEntry.js +0 -44
  70. package/models/trace/extras/URLForEntry.js.map +0 -1
  71. package/models/trace/handlers/EnhancedTracesHandler.d.ts +0 -48
  72. package/models/trace/handlers/EnhancedTracesHandler.js +0 -165
  73. package/models/trace/handlers/EnhancedTracesHandler.js.map +0 -1
  74. package/models/trace/insights/CumulativeLayoutShift.d.ts +0 -34
  75. package/models/trace/insights/CumulativeLayoutShift.js +0 -209
  76. package/models/trace/insights/CumulativeLayoutShift.js.map +0 -1
  77. package/models/trace/insights/InsightRunners.d.ts +0 -6
  78. package/models/trace/insights/InsightRunners.js +0 -10
  79. package/models/trace/insights/InsightRunners.js.map +0 -1
  80. package/models/trace/insights/LargestContentfulPaint.d.ts +0 -25
  81. package/models/trace/insights/LargestContentfulPaint.js +0 -93
  82. package/models/trace/insights/LargestContentfulPaint.js.map +0 -1
  83. package/models/trace/lantern/BaseNode.d.ts +0 -91
  84. package/models/trace/lantern/BaseNode.js +0 -268
  85. package/models/trace/lantern/BaseNode.js.map +0 -1
  86. package/models/trace/lantern/CPUNode.d.ts +0 -24
  87. package/models/trace/lantern/CPUNode.js +0 -64
  88. package/models/trace/lantern/CPUNode.js.map +0 -1
  89. package/models/trace/lantern/LanternError.d.ts +0 -3
  90. package/models/trace/lantern/LanternError.js +0 -7
  91. package/models/trace/lantern/LanternError.js.map +0 -1
  92. package/models/trace/lantern/MetricsModule.d.ts +0 -11
  93. package/models/trace/lantern/MetricsModule.js +0 -14
  94. package/models/trace/lantern/MetricsModule.js.map +0 -1
  95. package/models/trace/lantern/NetworkNode.d.ts +0 -22
  96. package/models/trace/lantern/NetworkNode.js +0 -83
  97. package/models/trace/lantern/NetworkNode.js.map +0 -1
  98. package/models/trace/lantern/PageDependencyGraph.d.ts +0 -43
  99. package/models/trace/lantern/PageDependencyGraph.js +0 -509
  100. package/models/trace/lantern/PageDependencyGraph.js.map +0 -1
  101. package/models/trace/lantern/SimulationModule.d.ts +0 -17
  102. package/models/trace/lantern/SimulationModule.js +0 -13
  103. package/models/trace/lantern/SimulationModule.js.map +0 -1
  104. package/models/trace/lantern/simulation/NetworkAnalyzer.d.ts +0 -112
  105. package/models/trace/lantern/simulation/NetworkAnalyzer.js +0 -486
  106. package/models/trace/lantern/simulation/NetworkAnalyzer.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"URLForEntry.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/URLForEntry.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;;GAQG;AAEH,MAAM,UAAU,cAAc,CAC1B,WAAuC,EAAE,KAAyB;IACpE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC,SAAS,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAsC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,qEAAqE;IACrE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,0EAA0E;IAC1E,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QACvE,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvG,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,4DAA4D;IAC5D,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAsC,CAAC;IACrE,CAAC;IAED,6EAA6E;IAC7E,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,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 type * as Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport * as Types from '../types/types.js';\n\n/**\n * INSTEAD, you probably want `SourceMapsResolver.resolvedURLForEntry()`!\n * If an URL will be displayed in the UI, it's likely you should NOT use `getNonResolved`.\n *\n * Use `getNonResolved` method whenever resolving an URL's source mapping is not an\n * option. For example when processing non-ui data.\n *\n * TODO: migrate existing uses of this over to resolvedURLForEntry.\n */\n\nexport function getNonResolved(\n parsedTrace: Handlers.Types.ParsedTrace, entry: Types.Events.Event): Platform.DevToolsPath.UrlString|null {\n if (Types.Events.isProfileCall(entry)) {\n return entry.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) {\n return entry.args.data.stackTrace[0].url as Platform.DevToolsPath.UrlString;\n }\n\n if (Types.Events.isSyntheticNetworkRequest(entry)) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n // DecodeImage events use the URL from the relevant PaintImage event.\n if (Types.Events.isDecodeImage(entry)) {\n const paintEvent = parsedTrace.ImagePainting.paintImageForEvent.get(entry);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // DrawLazyPixelRef events use the URL from the relevant PaintImage event.\n if (Types.Events.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) {\n const paintEvent = parsedTrace.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // ParseHTML events store the URL under beginData, not data.\n if (Types.Events.isParseHTML(entry)) {\n return entry.args.beginData.url as Platform.DevToolsPath.UrlString;\n }\n\n // For all other events, try to see if the URL is provided, else return null.\n if (entry.args?.data?.url) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n return null;\n}\n"]}
@@ -1,48 +0,0 @@
1
- import * as Types from '../types/types.js';
2
- export declare const EnhancedTracesVersion: number;
3
- export interface Script {
4
- scriptId: number;
5
- isolate: string;
6
- url: string;
7
- executionContextId: number;
8
- startLine: number;
9
- startColumn: number;
10
- endLine: number;
11
- endColumn: number;
12
- hash: string;
13
- isModule?: boolean;
14
- hasSourceUrl?: boolean;
15
- sourceMapUrl?: string;
16
- length?: number;
17
- sourceText?: string;
18
- auxData?: ExecutionContextAuxData;
19
- }
20
- export interface ExecutionContextAuxData {
21
- frameId?: string;
22
- isDefault?: boolean;
23
- type?: string;
24
- }
25
- export interface ExecutionContext {
26
- id: number;
27
- origin: string;
28
- v8Context?: string;
29
- auxData?: ExecutionContextAuxData;
30
- isolate?: string;
31
- }
32
- export interface Target {
33
- targetId: string;
34
- type: string;
35
- url: string;
36
- pid?: number;
37
- isolate?: string;
38
- }
39
- export interface EnhancedTracesData {
40
- targets: Target[];
41
- executionContexts: ExecutionContext[];
42
- scripts: Script[];
43
- }
44
- export declare function initialize(): void;
45
- export declare function reset(): void;
46
- export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
47
- export declare function finalize(): Promise<void>;
48
- export declare function data(): EnhancedTracesData;
@@ -1,165 +0,0 @@
1
- // Copyright 2024 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 Types from '../types/types.js';
5
- export const EnhancedTracesVersion = 1;
6
- let handlerState = 1 /* HandlerState.UNINITIALIZED */;
7
- const scriptRundownEvents = [];
8
- const scriptToV8Context = new Map();
9
- const scriptToScriptSource = new Map();
10
- const largeScriptToScriptSource = new Map();
11
- const scriptToSourceLength = new Map();
12
- const targets = [];
13
- const executionContexts = [];
14
- const scripts = [];
15
- function getScriptIsolateId(isolate, scriptId) {
16
- return scriptId + '@' + isolate;
17
- }
18
- export function initialize() {
19
- if (handlerState !== 1 /* HandlerState.UNINITIALIZED */) {
20
- throw new Error('Enhanced Traces Handler was not reset');
21
- }
22
- handlerState = 2 /* HandlerState.INITIALIZED */;
23
- }
24
- export function reset() {
25
- scriptRundownEvents.length = 0;
26
- scriptToV8Context.clear();
27
- scriptToScriptSource.clear();
28
- largeScriptToScriptSource.clear();
29
- scriptToSourceLength.clear();
30
- targets.length = 0;
31
- executionContexts.length = 0;
32
- scripts.length = 0;
33
- handlerState = 1 /* HandlerState.UNINITIALIZED */;
34
- }
35
- export function handleEvent(event) {
36
- if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
37
- throw new Error('Enhanced Traces Handler is not initialized while handling event');
38
- }
39
- if (Types.TraceEvents.isTraceEventTargetRundown(event)) {
40
- // Set up script to v8 context mapping
41
- const data = event.args?.data;
42
- scriptToV8Context.set(getScriptIsolateId(data.isolate, data.scriptId), data.v8context);
43
- // Add target
44
- if (!targets.find(target => target.targetId === data.frame)) {
45
- targets.push({
46
- targetId: data.frame,
47
- type: data.frameType,
48
- isolate: data.isolate,
49
- pid: event.pid,
50
- url: data.url,
51
- });
52
- }
53
- // Add execution context, need to put back execution context id with info from other traces
54
- if (!executionContexts.find(executionContext => executionContext.v8Context === data.v8context)) {
55
- executionContexts.push({
56
- id: -1,
57
- origin: data.origin,
58
- v8Context: data.v8context,
59
- auxData: {
60
- frameId: data.frame,
61
- isDefault: data.isDefault,
62
- type: data.contextType,
63
- },
64
- isolate: data.isolate,
65
- });
66
- }
67
- }
68
- else if (Types.TraceEvents.isTraceEventScriptRundown(event)) {
69
- scriptRundownEvents.push(event);
70
- const data = event.args.data;
71
- // Add script
72
- if (!scripts.find(script => script.scriptId === data.scriptId && script.isolate === data.isolate)) {
73
- scripts.push({
74
- scriptId: data.scriptId,
75
- isolate: data.isolate,
76
- executionContextId: data.executionContextId,
77
- startLine: data.startLine,
78
- startColumn: data.startColumn,
79
- endLine: data.endLine,
80
- endColumn: data.endColumn,
81
- hash: data.hash,
82
- isModule: data.isModule,
83
- url: data.url,
84
- hasSourceUrl: data.hasSourceUrl,
85
- sourceMapUrl: data.sourceMapUrl,
86
- });
87
- }
88
- }
89
- else if (Types.TraceEvents.isTraceEventScriptRundownSource(event)) {
90
- // Set up script to source text and length mapping
91
- const data = event.args.data;
92
- const scriptIsolateId = getScriptIsolateId(data.isolate, data.scriptId);
93
- if ('splitIndex' in data && 'splitCount' in data) {
94
- if (!largeScriptToScriptSource.has(scriptIsolateId)) {
95
- largeScriptToScriptSource.set(scriptIsolateId, new Array(data.splitCount).fill(''));
96
- }
97
- const splittedSource = largeScriptToScriptSource.get(scriptIsolateId);
98
- if (splittedSource && data.sourceText) {
99
- splittedSource[data.splitIndex] = data.sourceText;
100
- }
101
- }
102
- else {
103
- if (data.sourceText) {
104
- scriptToScriptSource.set(scriptIsolateId, data.sourceText);
105
- }
106
- if (data.length) {
107
- scriptToSourceLength.set(scriptIsolateId, data.length);
108
- }
109
- }
110
- }
111
- }
112
- export async function finalize() {
113
- if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
114
- throw new Error('Enhanced Traces Handler is not initialized while being finalized');
115
- }
116
- // Put back execution context id
117
- const v8ContextToExecutionContextId = new Map();
118
- scriptRundownEvents.forEach(scriptRundownEvent => {
119
- const data = scriptRundownEvent.args.data;
120
- const v8Context = scriptToV8Context.get(getScriptIsolateId(data.isolate, data.scriptId));
121
- if (v8Context) {
122
- v8ContextToExecutionContextId.set(v8Context, data.executionContextId);
123
- }
124
- });
125
- executionContexts.forEach(executionContext => {
126
- if (executionContext.v8Context) {
127
- const id = v8ContextToExecutionContextId.get(executionContext.v8Context);
128
- if (id) {
129
- executionContext.id = id;
130
- }
131
- }
132
- });
133
- // Put back script source text and length
134
- scripts.forEach(script => {
135
- const scriptIsolateId = getScriptIsolateId(script.isolate, script.scriptId);
136
- if (scriptToScriptSource.has(scriptIsolateId)) {
137
- script.sourceText = scriptToScriptSource.get(scriptIsolateId);
138
- script.length = scriptToSourceLength.get(scriptIsolateId);
139
- }
140
- else if (largeScriptToScriptSource.has(scriptIsolateId)) {
141
- const splittedSources = largeScriptToScriptSource.get(scriptIsolateId);
142
- if (splittedSources) {
143
- script.sourceText = splittedSources.join('');
144
- script.length = script.sourceText.length;
145
- }
146
- }
147
- // put in the aux data
148
- script.auxData =
149
- executionContexts
150
- .find(context => context.id === script.executionContextId && context.isolate === script.isolate)
151
- ?.auxData;
152
- });
153
- handlerState = 3 /* HandlerState.FINALIZED */;
154
- }
155
- export function data() {
156
- if (handlerState !== 3 /* HandlerState.FINALIZED */) {
157
- throw new Error('Enhanced Traces Handler is not finalized');
158
- }
159
- return {
160
- targets: targets,
161
- executionContexts: executionContexts,
162
- scripts: scripts,
163
- };
164
- }
165
- //# sourceMappingURL=EnhancedTracesHandler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EnhancedTracesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/EnhancedTracesHandler.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 Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nexport const EnhancedTracesVersion: number = 1;\n\nexport interface Script {\n scriptId: number;\n isolate: string;\n url: string;\n executionContextId: number;\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n hash: string;\n isModule?: boolean;\n hasSourceUrl?: boolean;\n sourceMapUrl?: string;\n length?: number;\n sourceText?: string;\n auxData?: ExecutionContextAuxData;\n}\n\nexport interface ExecutionContextAuxData {\n frameId?: string;\n isDefault?: boolean;\n type?: string;\n}\n\nexport interface ExecutionContext {\n id: number;\n origin: string;\n v8Context?: string;\n auxData?: ExecutionContextAuxData;\n isolate?: string;\n}\n\nexport interface Target {\n targetId: string;\n type: string;\n url: string;\n pid?: number;\n isolate?: string;\n}\n\nexport interface EnhancedTracesData {\n targets: Target[];\n executionContexts: ExecutionContext[];\n scripts: Script[];\n}\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst scriptRundownEvents: Types.TraceEvents.TraceEventScriptRundown[] = [];\nconst scriptToV8Context: Map<string, string> = new Map<string, string>();\nconst scriptToScriptSource: Map<string, string> = new Map<string, string>();\nconst largeScriptToScriptSource: Map<string, string[]> = new Map<string, string[]>();\nconst scriptToSourceLength: Map<string, number> = new Map<string, number>();\nconst targets: Target[] = [];\nconst executionContexts: ExecutionContext[] = [];\nconst scripts: Script[] = [];\n\nfunction getScriptIsolateId(isolate: string, scriptId: number): string {\n return scriptId + '@' + isolate;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Enhanced Traces Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function reset(): void {\n scriptRundownEvents.length = 0;\n scriptToV8Context.clear();\n scriptToScriptSource.clear();\n largeScriptToScriptSource.clear();\n scriptToSourceLength.clear();\n targets.length = 0;\n executionContexts.length = 0;\n scripts.length = 0;\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Enhanced Traces Handler is not initialized while handling event');\n }\n if (Types.TraceEvents.isTraceEventTargetRundown(event)) {\n // Set up script to v8 context mapping\n const data = event.args?.data;\n scriptToV8Context.set(getScriptIsolateId(data.isolate, data.scriptId), data.v8context);\n // Add target\n if (!targets.find(target => target.targetId === data.frame)) {\n targets.push({\n targetId: data.frame,\n type: data.frameType,\n isolate: data.isolate,\n pid: event.pid,\n url: data.url,\n });\n }\n // Add execution context, need to put back execution context id with info from other traces\n if (!executionContexts.find(executionContext => executionContext.v8Context === data.v8context)) {\n executionContexts.push({\n id: -1,\n origin: data.origin,\n v8Context: data.v8context,\n auxData: {\n frameId: data.frame,\n isDefault: data.isDefault,\n type: data.contextType,\n },\n isolate: data.isolate,\n });\n }\n } else if (Types.TraceEvents.isTraceEventScriptRundown(event)) {\n scriptRundownEvents.push(event);\n const data = event.args.data;\n // Add script\n if (!scripts.find(script => script.scriptId === data.scriptId && script.isolate === data.isolate)) {\n scripts.push({\n scriptId: data.scriptId,\n isolate: data.isolate,\n executionContextId: data.executionContextId,\n startLine: data.startLine,\n startColumn: data.startColumn,\n endLine: data.endLine,\n endColumn: data.endColumn,\n hash: data.hash,\n isModule: data.isModule,\n url: data.url,\n hasSourceUrl: data.hasSourceUrl,\n sourceMapUrl: data.sourceMapUrl,\n });\n }\n } else if (Types.TraceEvents.isTraceEventScriptRundownSource(event)) {\n // Set up script to source text and length mapping\n const data = event.args.data;\n const scriptIsolateId = getScriptIsolateId(data.isolate, data.scriptId);\n if ('splitIndex' in data && 'splitCount' in data) {\n if (!largeScriptToScriptSource.has(scriptIsolateId)) {\n largeScriptToScriptSource.set(scriptIsolateId, new Array(data.splitCount).fill('') as string[]);\n }\n const splittedSource = largeScriptToScriptSource.get(scriptIsolateId);\n if (splittedSource && data.sourceText) {\n splittedSource[data.splitIndex as number] = data.sourceText;\n }\n } else {\n if (data.sourceText) {\n scriptToScriptSource.set(scriptIsolateId, data.sourceText);\n }\n if (data.length) {\n scriptToSourceLength.set(scriptIsolateId, data.length);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Enhanced Traces Handler is not initialized while being finalized');\n }\n // Put back execution context id\n const v8ContextToExecutionContextId: Map<string, number> = new Map<string, number>();\n scriptRundownEvents.forEach(scriptRundownEvent => {\n const data = scriptRundownEvent.args.data;\n const v8Context = scriptToV8Context.get(getScriptIsolateId(data.isolate, data.scriptId));\n if (v8Context) {\n v8ContextToExecutionContextId.set(v8Context, data.executionContextId);\n }\n });\n executionContexts.forEach(executionContext => {\n if (executionContext.v8Context) {\n const id = v8ContextToExecutionContextId.get(executionContext.v8Context);\n if (id) {\n executionContext.id = id;\n }\n }\n });\n\n // Put back script source text and length\n scripts.forEach(script => {\n const scriptIsolateId = getScriptIsolateId(script.isolate, script.scriptId);\n if (scriptToScriptSource.has(scriptIsolateId)) {\n script.sourceText = scriptToScriptSource.get(scriptIsolateId);\n script.length = scriptToSourceLength.get(scriptIsolateId);\n } else if (largeScriptToScriptSource.has(scriptIsolateId)) {\n const splittedSources = largeScriptToScriptSource.get(scriptIsolateId);\n if (splittedSources) {\n script.sourceText = splittedSources.join('');\n script.length = script.sourceText.length;\n }\n }\n // put in the aux data\n script.auxData =\n executionContexts\n .find(context => context.id === script.executionContextId && context.isolate === script.isolate)\n ?.auxData;\n });\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): EnhancedTracesData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Enhanced Traces Handler is not finalized');\n }\n\n return {\n targets: targets,\n executionContexts: executionContexts,\n scripts: scripts,\n };\n}\n"]}
@@ -1,34 +0,0 @@
1
- import * as Types from '../types/types.js';
2
- import { type InsightResult, type NavigationInsightContext, type RequiredData } from './types.js';
3
- export declare function deps(): ['Meta', 'Animations', 'LayoutShifts', 'NetworkRequests'];
4
- export declare const enum AnimationFailureReasons {
5
- UNSUPPORTED_CSS_PROPERTY = "UNSUPPORTED_CSS_PROPERTY",
6
- TRANSFROM_BOX_SIZE_DEPENDENT = "TRANSFROM_BOX_SIZE_DEPENDENT",
7
- FILTER_MAY_MOVE_PIXELS = "FILTER_MAY_MOVE_PIXELS",
8
- NON_REPLACE_COMPOSITE_MODE = "NON_REPLACE_COMPOSITE_MODE",
9
- INCOMPATIBLE_ANIMATIONS = "INCOMPATIBLE_ANIMATIONS",
10
- UNSUPPORTED_TIMING_PARAMS = "UNSUPPORTED_TIMING_PARAMS"
11
- }
12
- export interface NoncompositedAnimationFailure {
13
- /**
14
- * Animation name.
15
- */
16
- name?: string;
17
- /**
18
- * Failure reason based on mask number defined in
19
- * https://source.chromium.org/search?q=f:compositor_animations.h%20%22enum%20FailureReason%22.
20
- */
21
- failureReasons: AnimationFailureReasons[];
22
- /**
23
- * Unsupported properties.
24
- */
25
- unsupportedProperties?: Types.TraceEvents.TraceEventAnimation['args']['data']['unsupportedProperties'];
26
- }
27
- export interface LayoutShiftRootCausesData {
28
- iframes: Types.TraceEvents.TraceEventRenderFrameImplCreateChildFrame[];
29
- fontRequests: Types.TraceEvents.SyntheticNetworkRequest[];
30
- }
31
- export declare function generateInsight(traceParsedData: RequiredData<typeof deps>, context: NavigationInsightContext): InsightResult<{
32
- animationFailures?: readonly NoncompositedAnimationFailure[];
33
- shifts?: Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftRootCausesData>;
34
- }>;
@@ -1,209 +0,0 @@
1
- // Copyright 2024 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 Platform from '../../../core/platform/platform.js';
5
- import * as Helpers from '../helpers/helpers.js';
6
- import * as Types from '../types/types.js';
7
- export function deps() {
8
- return ['Meta', 'Animations', 'LayoutShifts', 'NetworkRequests'];
9
- }
10
- /**
11
- * Each failure reason is represented by a bit flag. The bit shift operator '<<' is used to define
12
- * which bit corresponds to each failure reason.
13
- * https://source.chromium.org/search?q=f:compositor_animations.h%20%22enum%20FailureReason%22
14
- * @type {{flag: number, failure: AnimationFailureReasons}[]}
15
- */
16
- const ACTIONABLE_FAILURE_REASONS = [
17
- {
18
- flag: 1 << 13,
19
- failure: "UNSUPPORTED_CSS_PROPERTY" /* AnimationFailureReasons.UNSUPPORTED_CSS_PROPERTY */,
20
- },
21
- {
22
- flag: 1 << 11,
23
- failure: "TRANSFROM_BOX_SIZE_DEPENDENT" /* AnimationFailureReasons.TRANSFROM_BOX_SIZE_DEPENDENT */,
24
- },
25
- {
26
- flag: 1 << 12,
27
- failure: "FILTER_MAY_MOVE_PIXELS" /* AnimationFailureReasons.FILTER_MAY_MOVE_PIXELS */,
28
- },
29
- {
30
- flag: 1 << 4,
31
- failure: "NON_REPLACE_COMPOSITE_MODE" /* AnimationFailureReasons.NON_REPLACE_COMPOSITE_MODE */,
32
- },
33
- {
34
- flag: 1 << 6,
35
- failure: "INCOMPATIBLE_ANIMATIONS" /* AnimationFailureReasons.INCOMPATIBLE_ANIMATIONS */,
36
- },
37
- {
38
- flag: 1 << 3,
39
- failure: "UNSUPPORTED_TIMING_PARAMS" /* AnimationFailureReasons.UNSUPPORTED_TIMING_PARAMS */,
40
- },
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
- }
49
- /**
50
- * Returns a list of NoncompositedAnimationFailures.
51
- */
52
- function getNonCompositedAnimations(animations) {
53
- const failures = [];
54
- for (const event of animations) {
55
- const beginEvent = event.args.data.beginEvent;
56
- const instantEvents = event.args.data.instantEvents || [];
57
- /**
58
- * Animation events containing composite information are ASYNC_NESTABLE_INSTANT ('n').
59
- * An animation may also contain multiple 'n' events, so we look through those with useful non-composited data.
60
- */
61
- for (const event of instantEvents) {
62
- const failureMask = event.args.data.compositeFailed;
63
- const unsupportedProperties = event.args.data.unsupportedProperties;
64
- if (!failureMask || !unsupportedProperties) {
65
- continue;
66
- }
67
- const failureReasons = ACTIONABLE_FAILURE_REASONS.filter(reason => failureMask & reason.flag).map(reason => {
68
- return reason.failure;
69
- });
70
- const failure = {
71
- name: beginEvent.args.data.displayName,
72
- failureReasons,
73
- unsupportedProperties,
74
- };
75
- failures.push(failure);
76
- }
77
- }
78
- return failures;
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
- }
183
- export function generateInsight(traceParsedData, context) {
184
- const isWithinSameNavigation = ((event) => {
185
- const nav = Helpers.Trace.getNavigationForTraceEvent(event, context.frameId, traceParsedData.Meta.navigationsByFrameId);
186
- return nav?.args.data?.navigationId === context.navigationId;
187
- });
188
- const compositeAnimationEvents = traceParsedData.Animations.animations.filter(isWithinSameNavigation);
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);
204
- return {
205
- animationFailures,
206
- shifts: rootCausesByShift,
207
- };
208
- }
209
- //# sourceMappingURL=CumulativeLayoutShift.js.map
@@ -1 +0,0 @@
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,6 +0,0 @@
1
- export * as CumulativeLayoutShift from './CumulativeLayoutShift.js';
2
- export * as DocumentLatency from './DocumentLatency.js';
3
- export * as InteractionToNextPaint from './InteractionToNextPaint.js';
4
- export * as LargestContentfulPaint from './LargestContentfulPaint.js';
5
- export * as RenderBlocking from './RenderBlocking.js';
6
- export * as Viewport from './Viewport.js';
@@ -1,10 +0,0 @@
1
- // Copyright 2024 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
- export * as CumulativeLayoutShift from './CumulativeLayoutShift.js';
5
- export * as DocumentLatency from './DocumentLatency.js';
6
- export * as InteractionToNextPaint from './InteractionToNextPaint.js';
7
- export * as LargestContentfulPaint from './LargestContentfulPaint.js';
8
- export * as RenderBlocking from './RenderBlocking.js';
9
- export * as Viewport from './Viewport.js';
10
- //# sourceMappingURL=InsightRunners.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"InsightRunners.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/InsightRunners.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,sBAAsB,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,sBAAsB,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,eAAe,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\nexport * as CumulativeLayoutShift from './CumulativeLayoutShift.js';\nexport * as DocumentLatency from './DocumentLatency.js';\nexport * as InteractionToNextPaint from './InteractionToNextPaint.js';\nexport * as LargestContentfulPaint from './LargestContentfulPaint.js';\nexport * as RenderBlocking from './RenderBlocking.js';\nexport * as Viewport from './Viewport.js';\n"]}
@@ -1,25 +0,0 @@
1
- import * as Types from '../types/types.js';
2
- import { type LCPInsightResult, type NavigationInsightContext, type RequiredData } from './types.js';
3
- export declare function deps(): ['NetworkRequests', 'PageLoadMetrics', 'LargestImagePaint', 'Meta'];
4
- export interface LCPPhases {
5
- /**
6
- * The time between when the user initiates loading the page until when
7
- * the browser receives the first byte of the html response.
8
- */
9
- ttfb: Types.Timing.MilliSeconds;
10
- /**
11
- * The time between ttfb and the LCP resource request being started.
12
- * For a text LCP, this is undefined given no resource is loaded.
13
- */
14
- loadDelay?: Types.Timing.MilliSeconds;
15
- /**
16
- * The time it takes to load the LCP resource.
17
- */
18
- loadTime?: Types.Timing.MilliSeconds;
19
- /**
20
- * The time between when the LCP resource finishes loading and when
21
- * the LCP element is rendered.
22
- */
23
- renderDelay: Types.Timing.MilliSeconds;
24
- }
25
- export declare function generateInsight(traceParsedData: RequiredData<typeof deps>, context: NavigationInsightContext): LCPInsightResult;