@paulirish/trace_engine 0.0.9 → 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.
Files changed (292) hide show
  1. package/analyze-trace.mjs +1 -1
  2. package/core/platform/DevToolsPath.d.ts +23 -0
  3. package/core/platform/DevToolsPath.js +7 -0
  4. package/core/platform/DevToolsPath.js.map +1 -0
  5. package/core/platform/MimeType.d.ts +27 -0
  6. package/core/platform/MimeType.js +137 -0
  7. package/core/platform/MimeType.js.map +1 -0
  8. package/core/platform/Timing.d.ts +7 -0
  9. package/core/platform/Timing.js +13 -0
  10. package/core/platform/Timing.js.map +1 -0
  11. package/core/platform/UIString.d.ts +3 -0
  12. package/core/platform/UIString.js +5 -0
  13. package/core/platform/UIString.js.map +1 -0
  14. package/core/platform/UserVisibleError.d.ts +12 -0
  15. package/core/platform/UserVisibleError.js +23 -0
  16. package/core/platform/UserVisibleError.js.map +1 -0
  17. package/core/platform/array-utilities.d.ts +66 -0
  18. package/core/platform/array-utilities.js +199 -0
  19. package/core/platform/array-utilities.js.map +1 -0
  20. package/core/platform/brand.d.ts +14 -0
  21. package/core/platform/brand.js +5 -0
  22. package/core/platform/brand.js.map +1 -0
  23. package/core/platform/bundle-tsconfig.json +1 -0
  24. package/core/platform/date-utilities.d.ts +2 -0
  25. package/core/platform/date-utilities.js +14 -0
  26. package/core/platform/date-utilities.js.map +1 -0
  27. package/core/platform/dcheck-tsconfig.json +8 -0
  28. package/core/platform/dcheck.d.ts +4 -0
  29. package/core/platform/dcheck.js +5 -0
  30. package/core/platform/devtools_entrypoint-bundle-tsconfig-tsconfig.json +40 -0
  31. package/core/platform/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  32. package/core/platform/dom-utilities.d.ts +8 -0
  33. package/core/platform/dom-utilities.js +109 -0
  34. package/core/platform/dom-utilities.js.map +1 -0
  35. package/core/platform/keyboard-utilities.d.ts +17 -0
  36. package/core/platform/keyboard-utilities.js +22 -0
  37. package/core/platform/keyboard-utilities.js.map +1 -0
  38. package/core/platform/map-utilities.d.ts +18 -0
  39. package/core/platform/map-utilities.js +76 -0
  40. package/core/platform/map-utilities.js.map +1 -0
  41. package/core/platform/number-utilities.d.ts +15 -0
  42. package/core/platform/number-utilities.js +82 -0
  43. package/core/platform/number-utilities.js.map +1 -0
  44. package/core/platform/platform-tsconfig.json +59 -0
  45. package/core/platform/platform.d.ts +19 -0
  46. package/core/platform/platform.js +54 -0
  47. package/core/platform/platform.js.compressed +0 -0
  48. package/core/platform/platform.js.hash +1 -0
  49. package/core/platform/platform.js.map +1 -0
  50. package/core/platform/platform.prebundle.d.ts +15 -0
  51. package/core/platform/platform.prebundle.js +50 -0
  52. package/core/platform/platform.prebundle.js.map +1 -0
  53. package/core/platform/platform.prebundle.ts +64 -0
  54. package/core/platform/promise-utilities.d.ts +10 -0
  55. package/core/platform/promise-utilities.js +18 -0
  56. package/core/platform/promise-utilities.js.map +1 -0
  57. package/core/platform/set-utilities.d.ts +2 -0
  58. package/core/platform/set-utilities.js +23 -0
  59. package/core/platform/set-utilities.js.map +1 -0
  60. package/core/platform/string-utilities.d.ts +71 -0
  61. package/core/platform/string-utilities.js +513 -0
  62. package/core/platform/string-utilities.js.map +1 -0
  63. package/core/platform/typescript-utilities.d.ts +56 -0
  64. package/core/platform/typescript-utilities.js +25 -0
  65. package/core/platform/typescript-utilities.js.map +1 -0
  66. package/generated/protocol.d.ts +17923 -0
  67. package/generated/protocol.js +5 -0
  68. package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
  69. package/models/cpu_profile/CPUProfileDataModel.js +508 -0
  70. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -0
  71. package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
  72. package/models/cpu_profile/ProfileTreeModel.js +95 -0
  73. package/models/cpu_profile/ProfileTreeModel.js.map +1 -0
  74. package/models/cpu_profile/bundle-tsconfig.json +1 -0
  75. package/models/cpu_profile/cpu_profile-tsconfig.json +51 -0
  76. package/models/cpu_profile/cpu_profile.d.ts +3 -0
  77. package/models/cpu_profile/cpu_profile.js +7 -0
  78. package/models/cpu_profile/cpu_profile.js.map +1 -0
  79. package/models/cpu_profile/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  80. package/models/trace/EntriesFilter.d.ts +55 -0
  81. package/models/trace/EntriesFilter.js +243 -0
  82. package/models/trace/EntriesFilter.js.map +1 -0
  83. package/models/trace/LegacyTracingModel.d.ts +1 -0
  84. package/models/trace/LegacyTracingModel.js +1 -0
  85. package/models/trace/LegacyTracingModel.js.map +1 -0
  86. package/models/trace/ModelImpl.d.ts +110 -0
  87. package/models/trace/ModelImpl.js +175 -0
  88. package/models/trace/ModelImpl.js.map +1 -0
  89. package/models/trace/Processor.d.ts +36 -0
  90. package/models/trace/Processor.js +213 -0
  91. package/models/trace/Processor.js.map +1 -0
  92. package/models/trace/SDKServices.js +104 -0
  93. package/models/trace/SDKServices.js.map +7 -0
  94. package/models/trace/TraceProcessor.js +133 -0
  95. package/models/trace/TraceProcessor.js.map +7 -0
  96. package/models/trace/TracingManager.d.ts +1 -0
  97. package/models/trace/TracingManager.js +1 -0
  98. package/models/trace/TracingManager.js.map +1 -0
  99. package/models/trace/TreeManipulator.js +85 -0
  100. package/models/trace/TreeManipulator.js.map +7 -0
  101. package/models/trace/bundle-tsconfig.json +1 -0
  102. package/models/trace/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  103. package/models/trace/devtools_entrypoint-legacy-typescript-tsconfig.json +43 -0
  104. package/models/trace/extras/FetchNodes.d.ts +46 -0
  105. package/models/trace/extras/FetchNodes.js +145 -0
  106. package/models/trace/extras/FetchNodes.js.map +1 -0
  107. package/models/trace/extras/FilmStrip.d.ts +19 -0
  108. package/models/trace/extras/FilmStrip.js +44 -0
  109. package/models/trace/extras/FilmStrip.js.map +1 -0
  110. package/models/trace/extras/MainThreadActivity.d.ts +2 -0
  111. package/models/trace/extras/MainThreadActivity.js +77 -0
  112. package/models/trace/extras/MainThreadActivity.js.map +1 -0
  113. package/models/trace/extras/Metadata.d.ts +2 -0
  114. package/models/trace/extras/Metadata.js +44 -0
  115. package/models/trace/extras/Metadata.js.map +1 -0
  116. package/models/trace/extras/bundle-tsconfig.json +1 -0
  117. package/models/trace/extras/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  118. package/models/trace/extras/extras-tsconfig.json +59 -0
  119. package/models/trace/extras/extras.d.ts +1 -0
  120. package/models/trace/extras/extras.js +1 -0
  121. package/models/trace/extras/extras.js.map +1 -0
  122. package/models/trace/frames/TimelineFrameModel.js +392 -0
  123. package/models/trace/frames/TimelineFrameModel.js.map +7 -0
  124. package/models/trace/frames/bundle-tsconfig.json +1 -0
  125. package/models/trace/frames/devtools_entrypoint-bundle-typescript-tsconfig.json +43 -0
  126. package/models/trace/frames/frames-tsconfig.json +58 -0
  127. package/models/trace/frames/frames.js +5 -0
  128. package/models/trace/frames/frames.js.map +7 -0
  129. package/models/trace/handlers/AnimationHandler.d.ts +8 -0
  130. package/models/trace/handlers/AnimationHandler.js +32 -0
  131. package/models/trace/handlers/AnimationHandler.js.map +1 -0
  132. package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
  133. package/models/trace/handlers/AuctionWorkletsHandler.js +160 -0
  134. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -0
  135. package/models/trace/handlers/FramesHandler.d.ts +76 -0
  136. package/models/trace/handlers/FramesHandler.js +457 -0
  137. package/models/trace/handlers/FramesHandler.js.map +1 -0
  138. package/models/trace/handlers/GPUHandler.d.ts +11 -0
  139. package/models/trace/handlers/GPUHandler.js +54 -0
  140. package/models/trace/handlers/GPUHandler.js.map +1 -0
  141. package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
  142. package/models/trace/handlers/InitiatorsHandler.js +184 -0
  143. package/models/trace/handlers/InitiatorsHandler.js.map +1 -0
  144. package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
  145. package/models/trace/handlers/InvalidationsHandler.js +120 -0
  146. package/models/trace/handlers/InvalidationsHandler.js.map +1 -0
  147. package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
  148. package/models/trace/handlers/LargestImagePaintHandler.js +38 -0
  149. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -0
  150. package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
  151. package/models/trace/handlers/LargestTextPaintHandler.js +26 -0
  152. package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -0
  153. package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
  154. package/models/trace/handlers/LayerTreeHandler.js +116 -0
  155. package/models/trace/handlers/LayerTreeHandler.js.map +1 -0
  156. package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
  157. package/models/trace/handlers/LayoutShiftsHandler.js +347 -0
  158. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -0
  159. package/models/trace/handlers/MemoryHandler.d.ts +7 -0
  160. package/models/trace/handlers/MemoryHandler.js +20 -0
  161. package/models/trace/handlers/MemoryHandler.js.map +1 -0
  162. package/models/trace/handlers/MetaHandler.d.ts +37 -0
  163. package/models/trace/handlers/MetaHandler.js +338 -0
  164. package/models/trace/handlers/MetaHandler.js.map +1 -0
  165. package/models/trace/handlers/Migration.js +27 -0
  166. package/models/trace/handlers/Migration.js.map +7 -0
  167. package/models/trace/handlers/ModelHandlers.d.ts +21 -0
  168. package/models/trace/handlers/ModelHandlers.js +25 -0
  169. package/models/trace/handlers/ModelHandlers.js.map +1 -0
  170. package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
  171. package/models/trace/handlers/NetworkRequestsHandler.js +361 -0
  172. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -0
  173. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
  174. package/models/trace/handlers/PageLoadMetricsHandler.js +407 -0
  175. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -0
  176. package/models/trace/handlers/RendererHandler.d.ts +101 -0
  177. package/models/trace/handlers/RendererHandler.js +325 -0
  178. package/models/trace/handlers/RendererHandler.js.map +1 -0
  179. package/models/trace/handlers/SamplesHandler.d.ts +46 -0
  180. package/models/trace/handlers/SamplesHandler.js +215 -0
  181. package/models/trace/handlers/SamplesHandler.js.map +1 -0
  182. package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
  183. package/models/trace/handlers/ScreenshotsHandler.js +79 -0
  184. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -0
  185. package/models/trace/handlers/Threads.d.ts +33 -0
  186. package/models/trace/handlers/Threads.js +95 -0
  187. package/models/trace/handlers/Threads.js.map +1 -0
  188. package/models/trace/handlers/UberFramesHandler.js +293 -0
  189. package/models/trace/handlers/UberFramesHandler.js.map +7 -0
  190. package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
  191. package/models/trace/handlers/UserInteractionsHandler.js +267 -0
  192. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -0
  193. package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
  194. package/models/trace/handlers/UserTimingsHandler.js +108 -0
  195. package/models/trace/handlers/UserTimingsHandler.js.map +1 -0
  196. package/models/trace/handlers/WarningsHandler.d.ts +14 -0
  197. package/models/trace/handlers/WarningsHandler.js +125 -0
  198. package/models/trace/handlers/WarningsHandler.js.map +1 -0
  199. package/models/trace/handlers/WorkersHandler.d.ts +11 -0
  200. package/models/trace/handlers/WorkersHandler.js +52 -0
  201. package/models/trace/handlers/WorkersHandler.js.map +1 -0
  202. package/models/trace/handlers/bundle-tsconfig.json +1 -0
  203. package/models/trace/handlers/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  204. package/models/trace/handlers/handlers-tsconfig.json +79 -0
  205. package/models/trace/handlers/handlers.d.ts +3 -0
  206. package/models/trace/handlers/handlers.js +7 -0
  207. package/models/trace/handlers/handlers.js.map +1 -0
  208. package/models/trace/handlers/types.d.ts +45 -0
  209. package/models/trace/handlers/types.js +18 -0
  210. package/models/trace/handlers/types.js.map +1 -0
  211. package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
  212. package/models/trace/helpers/SamplesIntegrator.js +397 -0
  213. package/models/trace/helpers/SamplesIntegrator.js.map +1 -0
  214. package/models/trace/helpers/Timing.d.ts +26 -0
  215. package/models/trace/helpers/Timing.js +162 -0
  216. package/models/trace/helpers/Timing.js.map +1 -0
  217. package/models/trace/helpers/Trace.d.ts +37 -0
  218. package/models/trace/helpers/Trace.js +230 -0
  219. package/models/trace/helpers/Trace.js.map +1 -0
  220. package/models/trace/helpers/TreeHelpers.d.ts +90 -0
  221. package/models/trace/helpers/TreeHelpers.js +222 -0
  222. package/models/trace/helpers/TreeHelpers.js.map +1 -0
  223. package/models/trace/helpers/bundle-tsconfig.json +1 -0
  224. package/models/trace/helpers/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  225. package/models/trace/helpers/helpers-tsconfig.json +59 -0
  226. package/models/trace/helpers/helpers.d.ts +4 -0
  227. package/models/trace/helpers/helpers.js +8 -0
  228. package/models/trace/helpers/helpers.js.map +1 -0
  229. package/models/trace/legacy-tsconfig.json +1 -0
  230. package/models/trace/root-causes/LayoutShift.d.ts +119 -0
  231. package/models/trace/root-causes/LayoutShift.js +517 -0
  232. package/models/trace/root-causes/LayoutShift.js.map +1 -0
  233. package/models/trace/root-causes/RootCauses.d.ts +14 -0
  234. package/models/trace/root-causes/RootCauses.js +11 -0
  235. package/models/trace/root-causes/RootCauses.js.map +1 -0
  236. package/models/trace/root-causes/bundle-tsconfig.json +1 -0
  237. package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  238. package/models/trace/root-causes/root-causes-tsconfig.json +57 -0
  239. package/models/trace/root-causes/root-causes.d.ts +1 -0
  240. package/models/trace/root-causes/root-causes.js +5 -0
  241. package/models/trace/root-causes/root-causes.js.map +1 -0
  242. package/models/trace/sdk_services/DOMNodeLookup.js +41 -0
  243. package/models/trace/sdk_services/DOMNodeLookup.js.map +7 -0
  244. package/models/trace/sdk_services/LayoutShifts.js +68 -0
  245. package/models/trace/sdk_services/LayoutShifts.js.map +7 -0
  246. package/models/trace/sdk_services/bundle-tsconfig.json +1 -0
  247. package/models/trace/sdk_services/devtools_entrypoint-bundle-typescript-tsconfig.json +41 -0
  248. package/models/trace/sdk_services/sdk_services-tsconfig.json +57 -0
  249. package/models/trace/sdk_services/sdk_services.js +7 -0
  250. package/models/trace/sdk_services/sdk_services.js.map +7 -0
  251. package/models/trace/trace-legacy.js +16 -0
  252. package/models/trace/trace-legacy.js.map +7 -0
  253. package/models/trace/trace-tsconfig.json +69 -0
  254. package/models/trace/trace.d.ts +11 -0
  255. package/models/trace/trace.js +17 -0
  256. package/models/trace/trace.js.map +1 -0
  257. package/models/trace/types/Configuration.d.ts +33 -0
  258. package/models/trace/types/Configuration.js +29 -0
  259. package/models/trace/types/Configuration.js.map +1 -0
  260. package/models/trace/types/File.d.ts +23 -0
  261. package/models/trace/types/File.js +5 -0
  262. package/models/trace/types/File.js.map +1 -0
  263. package/models/trace/types/Timing.d.ts +25 -0
  264. package/models/trace/types/Timing.js +16 -0
  265. package/models/trace/types/Timing.js.map +1 -0
  266. package/models/trace/types/TraceEvents.d.ts +1571 -0
  267. package/models/trace/types/TraceEvents.js +388 -0
  268. package/models/trace/types/TraceEvents.js.map +1 -0
  269. package/models/trace/types/bundle-tsconfig.json +1 -0
  270. package/models/trace/types/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
  271. package/models/trace/types/types-tsconfig.json +47 -0
  272. package/models/trace/types/types.d.ts +4 -0
  273. package/models/trace/types/types.js +8 -0
  274. package/models/trace/types/types.js.map +1 -0
  275. package/models/trace/worker/Processor.js +143 -0
  276. package/models/trace/worker/Processor.js.map +7 -0
  277. package/models/trace/worker/Types.js +1 -0
  278. package/models/trace/worker/Types.js.map +7 -0
  279. package/models/trace/worker/bundle-tsconfig.json +1 -0
  280. package/models/trace/worker/devtools_entrypoint-bundle-typescript-tsconfig.json +41 -0
  281. package/models/trace/worker/devtools_entrypoint-worker_entrypoint-typescript-tsconfig.json +41 -0
  282. package/models/trace/worker/processor-tsconfig.json +45 -0
  283. package/models/trace/worker/worker.js +7 -0
  284. package/models/trace/worker/worker.js.map +7 -0
  285. package/models/trace/worker/worker_entrypoint-tsconfig.json +1 -0
  286. package/models/trace/worker/worker_entrypoint.js +36 -0
  287. package/models/trace/worker/worker_entrypoint.js.map +7 -0
  288. package/package.json +2 -2
  289. package/TracingManager.js +0 -0
  290. package/extras/extras.js +0 -0
  291. package/trace.mjs +0 -6980
  292. package/trace.mjs.map +0 -8
@@ -0,0 +1,184 @@
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
+ let handlerState = 1 /* HandlerState.UNINITIALIZED */;
7
+ const lastScheduleStyleRecalcByFrame = new Map();
8
+ // This tracks the last event that is considered to have invalidated the layout
9
+ // for a given frame.
10
+ // Note that although there is an InvalidateLayout event, there are also other
11
+ // events (ScheduleStyleRecalculation) that could be the reason a layout was
12
+ // invalidated.
13
+ const lastInvalidationEventForFrame = new Map();
14
+ // Important: although the event is called UpdateLayoutTree, in the UI we
15
+ // present these to the user as "Recalculate Style". So don't get confused!
16
+ // These are the same - just UpdateLayoutTree is what the event from Chromium
17
+ // is called.
18
+ const lastUpdateLayoutTreeByFrame = new Map();
19
+ // These two maps store the same data but in different directions.
20
+ //
21
+ // For a given event, tell me what its initiator was. An event can only have one initiator.
22
+ const eventToInitiatorMap = new Map();
23
+ // For a given event, tell me what events it initiated. An event can initiate
24
+ // multiple events, hence why the value for this map is an array.
25
+ const initiatorToEventsMap = new Map();
26
+ const requestAnimationFrameEventsById = new Map();
27
+ const timerInstallEventsById = new Map();
28
+ const requestIdleCallbackEventsById = new Map();
29
+ const webSocketCreateEventsById = new Map();
30
+ export function reset() {
31
+ lastScheduleStyleRecalcByFrame.clear();
32
+ lastInvalidationEventForFrame.clear();
33
+ lastUpdateLayoutTreeByFrame.clear();
34
+ timerInstallEventsById.clear();
35
+ eventToInitiatorMap.clear();
36
+ initiatorToEventsMap.clear();
37
+ requestAnimationFrameEventsById.clear();
38
+ requestIdleCallbackEventsById.clear();
39
+ webSocketCreateEventsById.clear();
40
+ handlerState = 1 /* HandlerState.UNINITIALIZED */;
41
+ }
42
+ export function initialize() {
43
+ if (handlerState !== 1 /* HandlerState.UNINITIALIZED */) {
44
+ throw new Error('InitiatorsHandler was not reset before being initialized');
45
+ }
46
+ handlerState = 2 /* HandlerState.INITIALIZED */;
47
+ }
48
+ function storeInitiator(data) {
49
+ eventToInitiatorMap.set(data.event, data.initiator);
50
+ const eventsForInitiator = initiatorToEventsMap.get(data.initiator) || [];
51
+ eventsForInitiator.push(data.event);
52
+ initiatorToEventsMap.set(data.initiator, eventsForInitiator);
53
+ }
54
+ export function handleEvent(event) {
55
+ if (Types.TraceEvents.isTraceEventScheduleStyleRecalculation(event)) {
56
+ lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event);
57
+ }
58
+ else if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {
59
+ // IMPORTANT: although the trace event is called UpdateLayoutTree, this
60
+ // represents a Styles Recalculation. This event in the timeline is shown to
61
+ // the user as "Recalculate Styles."
62
+ if (event.args.beginData) {
63
+ // Store the last UpdateLayout event: we use this when we see an
64
+ // InvalidateLayout and try to figure out its initiator.
65
+ lastUpdateLayoutTreeByFrame.set(event.args.beginData.frame, event);
66
+ // If this frame has seen a ScheduleStyleRecalc event, then that event is
67
+ // considered to be the initiator of this StylesRecalc.
68
+ const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame);
69
+ if (scheduledStyleForFrame) {
70
+ storeInitiator({
71
+ event,
72
+ initiator: scheduledStyleForFrame,
73
+ });
74
+ }
75
+ }
76
+ }
77
+ else if (Types.TraceEvents.isTraceEventInvalidateLayout(event)) {
78
+ // By default, the InvalidateLayout event is what triggered the layout invalidation for this frame.
79
+ let invalidationInitiator = event;
80
+ // However, if we have not had any prior invalidations for this frame, we
81
+ // want to consider StyleRecalculation events as they might be the actual
82
+ // cause of this layout invalidation.
83
+ if (!lastInvalidationEventForFrame.has(event.args.data.frame)) {
84
+ // 1. If we have not had an invalidation event for this frame
85
+ // 2. AND we have had an UpdateLayoutTree for this frame
86
+ // 3. AND the UpdateLayoutTree event ended AFTER the InvalidateLayout startTime
87
+ // 4. AND we have an initiator for the UpdateLayoutTree event
88
+ // 5. Then we set the last invalidation event for this frame to be the UpdateLayoutTree's initiator.
89
+ const lastUpdateLayoutTreeForFrame = lastUpdateLayoutTreeByFrame.get(event.args.data.frame);
90
+ if (lastUpdateLayoutTreeForFrame) {
91
+ const { endTime } = Helpers.Timing.eventTimingsMicroSeconds(lastUpdateLayoutTreeForFrame);
92
+ const initiatorOfUpdateLayout = eventToInitiatorMap.get(lastUpdateLayoutTreeForFrame);
93
+ if (initiatorOfUpdateLayout && endTime && endTime > event.ts) {
94
+ invalidationInitiator = initiatorOfUpdateLayout;
95
+ }
96
+ }
97
+ }
98
+ lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator);
99
+ }
100
+ else if (Types.TraceEvents.isTraceEventLayout(event)) {
101
+ // The initiator of a Layout event is the last Invalidation event.
102
+ const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame);
103
+ if (lastInvalidation) {
104
+ storeInitiator({
105
+ event,
106
+ initiator: lastInvalidation,
107
+ });
108
+ }
109
+ // Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.
110
+ lastInvalidationEventForFrame.delete(event.args.beginData.frame);
111
+ }
112
+ else if (Types.TraceEvents.isTraceEventRequestAnimationFrame(event)) {
113
+ requestAnimationFrameEventsById.set(event.args.data.id, event);
114
+ }
115
+ else if (Types.TraceEvents.isTraceEventFireAnimationFrame(event)) {
116
+ // If we get a fire event, that means we should have had the
117
+ // RequestAnimationFrame event by now. If so, we can set that as the
118
+ // initiator for the fire event.
119
+ const matchingRequestEvent = requestAnimationFrameEventsById.get(event.args.data.id);
120
+ if (matchingRequestEvent) {
121
+ storeInitiator({
122
+ event,
123
+ initiator: matchingRequestEvent,
124
+ });
125
+ }
126
+ }
127
+ else if (Types.TraceEvents.isTraceEventTimerInstall(event)) {
128
+ timerInstallEventsById.set(event.args.data.timerId, event);
129
+ }
130
+ else if (Types.TraceEvents.isTraceEventTimerFire(event)) {
131
+ const matchingInstall = timerInstallEventsById.get(event.args.data.timerId);
132
+ if (matchingInstall) {
133
+ storeInitiator({ event, initiator: matchingInstall });
134
+ }
135
+ }
136
+ else if (Types.TraceEvents.isTraceEventRequestIdleCallback(event)) {
137
+ requestIdleCallbackEventsById.set(event.args.data.id, event);
138
+ }
139
+ else if (Types.TraceEvents.isTraceEventFireIdleCallback(event)) {
140
+ const matchingRequestEvent = requestIdleCallbackEventsById.get(event.args.data.id);
141
+ if (matchingRequestEvent) {
142
+ storeInitiator({
143
+ event,
144
+ initiator: matchingRequestEvent,
145
+ });
146
+ }
147
+ }
148
+ else if (Types.TraceEvents.isTraceEventWebSocketCreate(event)) {
149
+ webSocketCreateEventsById.set(event.args.data.identifier, event);
150
+ }
151
+ else if (Types.TraceEvents.isTraceEventWebSocketSendHandshakeRequest(event)) {
152
+ const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);
153
+ if (matchingCreateEvent) {
154
+ storeInitiator({
155
+ event,
156
+ initiator: matchingCreateEvent,
157
+ });
158
+ }
159
+ }
160
+ else if (Types.TraceEvents.isTraceEventWebSocketSendHandshakeRequest(event) ||
161
+ Types.TraceEvents.isTraceEventWebSocketReceiveHandshakeResponse(event) ||
162
+ Types.TraceEvents.isTraceEventWebSocketDestroy(event)) {
163
+ const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);
164
+ if (matchingCreateEvent) {
165
+ storeInitiator({
166
+ event,
167
+ initiator: matchingCreateEvent,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ export async function finalize() {
173
+ if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
174
+ throw new Error('InitiatorsHandler is not initialized');
175
+ }
176
+ handlerState = 3 /* HandlerState.FINALIZED */;
177
+ }
178
+ export function data() {
179
+ return {
180
+ eventToInitiator: new Map(eventToInitiatorMap),
181
+ initiatorToEvents: new Map(initiatorToEventsMap),
182
+ };
183
+ }
184
+ //# sourceMappingURL=InitiatorsHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InitiatorsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InitiatorsHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,IAAI,YAAY,qCAA6B,CAAC;AAE9C,MAAM,8BAA8B,GAAG,IAAI,GAAG,EAAkE,CAAC;AAEjH,+EAA+E;AAC/E,qBAAqB;AACrB,8EAA8E;AAC9E,4EAA4E;AAC5E,eAAe;AACf,MAAM,6BAA6B,GAAG,IAAI,GAAG,EAA4C,CAAC;AAE1F,yEAAyE;AACzE,2EAA2E;AAC3E,6EAA6E;AAC7E,aAAa;AACb,MAAM,2BAA2B,GAAG,IAAI,GAAG,EAAwD,CAAC;AAEpG,kEAAkE;AAClE,EAAE;AACF,2FAA2F;AAC3F,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAsE,CAAC;AAC1G,6EAA6E;AAC7E,iEAAiE;AACjE,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAwE,CAAC;AAE7G,MAAM,+BAA+B,GAAmE,IAAI,GAAG,EAAE,CAAC;AAClH,MAAM,sBAAsB,GAA0D,IAAI,GAAG,EAAE,CAAC;AAChG,MAAM,6BAA6B,GAAiE,IAAI,GAAG,EAAE,CAAC;AAC9G,MAAM,yBAAyB,GAA6D,IAAI,GAAG,EAAE,CAAC;AAEtG,MAAM,UAAU,KAAK;IACnB,8BAA8B,CAAC,KAAK,EAAE,CAAC;IACvC,6BAA6B,CAAC,KAAK,EAAE,CAAC;IACtC,2BAA2B,CAAC,KAAK,EAAE,CAAC;IACpC,sBAAsB,CAAC,KAAK,EAAE,CAAC;IAC/B,mBAAmB,CAAC,KAAK,EAAE,CAAC;IAC5B,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,+BAA+B,CAAC,KAAK,EAAE,CAAC;IACxC,6BAA6B,CAAC,KAAK,EAAE,CAAC;IACtC,yBAAyB,CAAC,KAAK,EAAE,CAAC;IAElC,YAAY,qCAA6B,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,YAAY,uCAA+B,EAAE;QAC/C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;KAC7E;IAED,YAAY,mCAA2B,CAAC;AAC1C,CAAC;AAED,SAAS,cAAc,CAAC,IAA4F;IAElH,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC1E,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,KAAK,CAAC,WAAW,CAAC,sCAAsC,CAAC,KAAK,CAAC,EAAE;QACnE,8BAA8B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;KAClE;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE;QAChE,uEAAuE;QACvE,4EAA4E;QAC5E,oCAAoC;QACpC,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE;YACxB,gEAAgE;YAChE,wDAAwD;YACxD,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAEnE,yEAAyE;YACzE,uDAAuD;YACvD,MAAM,sBAAsB,GAAG,8BAA8B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC9F,IAAI,sBAAsB,EAAE;gBAC1B,cAAc,CAAC;oBACb,KAAK;oBACL,SAAS,EAAE,sBAAsB;iBAClC,CAAC,CAAC;aACJ;SACF;KACF;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE;QAChE,mGAAmG;QACnG,IAAI,qBAAqB,GAAqC,KAAK,CAAC;QAEpE,yEAAyE;QACzE,yEAAyE;QACzE,qCAAqC;QACrC,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAC7D,6DAA6D;YAC7D,wDAAwD;YACxD,+EAA+E;YAC/E,6DAA6D;YAC7D,oGAAoG;YACpG,MAAM,4BAA4B,GAAG,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5F,IAAI,4BAA4B,EAAE;gBAChC,MAAM,EAAC,OAAO,EAAC,GAAG,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC,4BAA4B,CAAC,CAAC;gBACxF,MAAM,uBAAuB,GAAG,mBAAmB,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;gBAEtF,IAAI,uBAAuB,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK,CAAC,EAAE,EAAE;oBAC5D,qBAAqB,GAAG,uBAAuB,CAAC;iBACjD;aACF;SACF;QACD,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;KACjF;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;QACtD,kEAAkE;QAClE,MAAM,gBAAgB,GAAG,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvF,IAAI,gBAAgB,EAAE;YACpB,cAAc,CAAC;gBACb,KAAK;gBACL,SAAS,EAAE,gBAAgB;aAC5B,CAAC,CAAC;SACJ;QACD,gKAAgK;QAChK,6BAA6B,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;KAClE;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,iCAAiC,CAAC,KAAK,CAAC,EAAE;QACrE,+BAA+B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;KAChE;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,8BAA8B,CAAC,KAAK,CAAC,EAAE;QAClE,4DAA4D;QAC5D,oEAAoE;QACpE,gCAAgC;QAChC,MAAM,oBAAoB,GAAG,+BAA+B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,IAAI,oBAAoB,EAAE;YACxB,cAAc,CAAC;gBACb,KAAK;gBACL,SAAS,EAAE,oBAAoB;aAChC,CAAC,CAAC;SACJ;KACF;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE;QAC5D,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;KAC5D;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE;QACzD,MAAM,eAAe,GAAG,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5E,IAAI,eAAe,EAAE;YACnB,cAAc,CAAC,EAAC,KAAK,EAAE,SAAS,EAAE,eAAe,EAAC,CAAC,CAAC;SACrD;KACF;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,+BAA+B,CAAC,KAAK,CAAC,EAAE;QACnE,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;KAC9D;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE;QAChE,MAAM,oBAAoB,GAAG,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnF,IAAI,oBAAoB,EAAE;YACxB,cAAc,CAAC;gBACb,KAAK;gBACL,SAAS,EAAE,oBAAoB;aAChC,CAAC,CAAC;SACJ;KACF;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,2BAA2B,CAAC,KAAK,CAAC,EAAE;QAC/D,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;KAClE;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,yCAAyC,CAAC,KAAK,CAAC,EAAE;QAC7E,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtF,IAAI,mBAAmB,EAAE;YACvB,cAAc,CAAC;gBACb,KAAK;gBACL,SAAS,EAAE,mBAAmB;aAC/B,CAAC,CAAC;SACJ;KACF;SAAM,IACH,KAAK,CAAC,WAAW,CAAC,yCAAyC,CAAC,KAAK,CAAC;QAClE,KAAK,CAAC,WAAW,CAAC,6CAA6C,CAAC,KAAK,CAAC;QACtE,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE;QACzD,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtF,IAAI,mBAAmB,EAAE;YACvB,cAAc,CAAC;gBACb,KAAK;gBACL,SAAS,EAAE,mBAAmB;aAC/B,CAAC,CAAC;SACJ;KACF;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,YAAY,qCAA6B,EAAE;QAC7C,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;KACzD;IAED,YAAY,iCAAyB,CAAC;AACxC,CAAC;AAMD,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,gBAAgB,EAAE,IAAI,GAAG,CAAC,mBAAmB,CAAC;QAC9C,iBAAiB,EAAE,IAAI,GAAG,CAAC,oBAAoB,CAAC;KACjD,CAAC;AACJ,CAAC","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 {HandlerState} from './types.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst lastScheduleStyleRecalcByFrame = new Map<string, Types.TraceEvents.TraceEventScheduleStyleRecalculation>();\n\n// This tracks the last event that is considered to have invalidated the layout\n// for a given frame.\n// Note that although there is an InvalidateLayout event, there are also other\n// events (ScheduleStyleRecalculation) that could be the reason a layout was\n// invalidated.\nconst lastInvalidationEventForFrame = new Map<string, Types.TraceEvents.TraceEventData>();\n\n// Important: although the event is called UpdateLayoutTree, in the UI we\n// present these to the user as \"Recalculate Style\". So don't get confused!\n// These are the same - just UpdateLayoutTree is what the event from Chromium\n// is called.\nconst lastUpdateLayoutTreeByFrame = new Map<string, Types.TraceEvents.TraceEventUpdateLayoutTree>();\n\n// These two maps store the same data but in different directions.\n//\n// For a given event, tell me what its initiator was. An event can only have one initiator.\nconst eventToInitiatorMap = new Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.TraceEventData>();\n// For a given event, tell me what events it initiated. An event can initiate\n// multiple events, hence why the value for this map is an array.\nconst initiatorToEventsMap = new Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.TraceEventData[]>();\n\nconst requestAnimationFrameEventsById: Map<number, Types.TraceEvents.TraceEventRequestAnimationFrame> = new Map();\nconst timerInstallEventsById: Map<number, Types.TraceEvents.TraceEventTimerInstall> = new Map();\nconst requestIdleCallbackEventsById: Map<number, Types.TraceEvents.TraceEventRequestIdleCallback> = new Map();\nconst webSocketCreateEventsById: Map<number, Types.TraceEvents.TraceEventWebSocketCreate> = new Map();\n\nexport function reset(): void {\n lastScheduleStyleRecalcByFrame.clear();\n lastInvalidationEventForFrame.clear();\n lastUpdateLayoutTreeByFrame.clear();\n timerInstallEventsById.clear();\n eventToInitiatorMap.clear();\n initiatorToEventsMap.clear();\n requestAnimationFrameEventsById.clear();\n requestIdleCallbackEventsById.clear();\n webSocketCreateEventsById.clear();\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('InitiatorsHandler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction storeInitiator(data: {initiator: Types.TraceEvents.TraceEventData, event: Types.TraceEvents.TraceEventData}):\n void {\n eventToInitiatorMap.set(data.event, data.initiator);\n const eventsForInitiator = initiatorToEventsMap.get(data.initiator) || [];\n eventsForInitiator.push(data.event);\n initiatorToEventsMap.set(data.initiator, eventsForInitiator);\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventScheduleStyleRecalculation(event)) {\n lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event);\n } else if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {\n // IMPORTANT: although the trace event is called UpdateLayoutTree, this\n // represents a Styles Recalculation. This event in the timeline is shown to\n // the user as \"Recalculate Styles.\"\n if (event.args.beginData) {\n // Store the last UpdateLayout event: we use this when we see an\n // InvalidateLayout and try to figure out its initiator.\n lastUpdateLayoutTreeByFrame.set(event.args.beginData.frame, event);\n\n // If this frame has seen a ScheduleStyleRecalc event, then that event is\n // considered to be the initiator of this StylesRecalc.\n const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame);\n if (scheduledStyleForFrame) {\n storeInitiator({\n event,\n initiator: scheduledStyleForFrame,\n });\n }\n }\n } else if (Types.TraceEvents.isTraceEventInvalidateLayout(event)) {\n // By default, the InvalidateLayout event is what triggered the layout invalidation for this frame.\n let invalidationInitiator: Types.TraceEvents.TraceEventData = event;\n\n // However, if we have not had any prior invalidations for this frame, we\n // want to consider StyleRecalculation events as they might be the actual\n // cause of this layout invalidation.\n if (!lastInvalidationEventForFrame.has(event.args.data.frame)) {\n // 1. If we have not had an invalidation event for this frame\n // 2. AND we have had an UpdateLayoutTree for this frame\n // 3. AND the UpdateLayoutTree event ended AFTER the InvalidateLayout startTime\n // 4. AND we have an initiator for the UpdateLayoutTree event\n // 5. Then we set the last invalidation event for this frame to be the UpdateLayoutTree's initiator.\n const lastUpdateLayoutTreeForFrame = lastUpdateLayoutTreeByFrame.get(event.args.data.frame);\n if (lastUpdateLayoutTreeForFrame) {\n const {endTime} = Helpers.Timing.eventTimingsMicroSeconds(lastUpdateLayoutTreeForFrame);\n const initiatorOfUpdateLayout = eventToInitiatorMap.get(lastUpdateLayoutTreeForFrame);\n\n if (initiatorOfUpdateLayout && endTime && endTime > event.ts) {\n invalidationInitiator = initiatorOfUpdateLayout;\n }\n }\n }\n lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator);\n } else if (Types.TraceEvents.isTraceEventLayout(event)) {\n // The initiator of a Layout event is the last Invalidation event.\n const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame);\n if (lastInvalidation) {\n storeInitiator({\n event,\n initiator: lastInvalidation,\n });\n }\n // Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.\n lastInvalidationEventForFrame.delete(event.args.beginData.frame);\n } else if (Types.TraceEvents.isTraceEventRequestAnimationFrame(event)) {\n requestAnimationFrameEventsById.set(event.args.data.id, event);\n } else if (Types.TraceEvents.isTraceEventFireAnimationFrame(event)) {\n // If we get a fire event, that means we should have had the\n // RequestAnimationFrame event by now. If so, we can set that as the\n // initiator for the fire event.\n const matchingRequestEvent = requestAnimationFrameEventsById.get(event.args.data.id);\n if (matchingRequestEvent) {\n storeInitiator({\n event,\n initiator: matchingRequestEvent,\n });\n }\n } else if (Types.TraceEvents.isTraceEventTimerInstall(event)) {\n timerInstallEventsById.set(event.args.data.timerId, event);\n } else if (Types.TraceEvents.isTraceEventTimerFire(event)) {\n const matchingInstall = timerInstallEventsById.get(event.args.data.timerId);\n if (matchingInstall) {\n storeInitiator({event, initiator: matchingInstall});\n }\n } else if (Types.TraceEvents.isTraceEventRequestIdleCallback(event)) {\n requestIdleCallbackEventsById.set(event.args.data.id, event);\n } else if (Types.TraceEvents.isTraceEventFireIdleCallback(event)) {\n const matchingRequestEvent = requestIdleCallbackEventsById.get(event.args.data.id);\n if (matchingRequestEvent) {\n storeInitiator({\n event,\n initiator: matchingRequestEvent,\n });\n }\n } else if (Types.TraceEvents.isTraceEventWebSocketCreate(event)) {\n webSocketCreateEventsById.set(event.args.data.identifier, event);\n } else if (Types.TraceEvents.isTraceEventWebSocketSendHandshakeRequest(event)) {\n const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);\n if (matchingCreateEvent) {\n storeInitiator({\n event,\n initiator: matchingCreateEvent,\n });\n }\n } else if (\n Types.TraceEvents.isTraceEventWebSocketSendHandshakeRequest(event) ||\n Types.TraceEvents.isTraceEventWebSocketReceiveHandshakeResponse(event) ||\n Types.TraceEvents.isTraceEventWebSocketDestroy(event)) {\n const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);\n if (matchingCreateEvent) {\n storeInitiator({\n event,\n initiator: matchingCreateEvent,\n });\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('InitiatorsHandler is not initialized');\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport interface InitiatorsData {\n eventToInitiator: Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.TraceEventData>;\n initiatorToEvents: Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.TraceEventData[]>;\n}\nexport function data(): InitiatorsData {\n return {\n eventToInitiator: new Map(eventToInitiatorMap),\n initiatorToEvents: new Map(initiatorToEventsMap),\n };\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import * as Types from '../types/types.js';
2
+ export declare function reset(): void;
3
+ export declare function initialize(): void;
4
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
5
+ export declare function finalize(): Promise<void>;
6
+ interface InvalidationsData {
7
+ invalidationsForEvent: Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>;
8
+ }
9
+ export declare function data(): InvalidationsData;
10
+ export {};
@@ -0,0 +1,120 @@
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 Types from '../types/types.js';
5
+ let handlerState = 1 /* HandlerState.UNINITIALIZED */;
6
+ const invalidationsForEvent = new Map();
7
+ let lastRecalcStyleEvent = null;
8
+ // Used to track paints so we track invalidations correctly per paint.
9
+ let hasPainted = false;
10
+ const allInvalidationTrackingEvents = [];
11
+ export function reset() {
12
+ handlerState = 1 /* HandlerState.UNINITIALIZED */;
13
+ invalidationsForEvent.clear();
14
+ lastRecalcStyleEvent = null;
15
+ allInvalidationTrackingEvents.length = 0;
16
+ hasPainted = false;
17
+ }
18
+ export function initialize() {
19
+ if (handlerState !== 1 /* HandlerState.UNINITIALIZED */) {
20
+ throw new Error('InvalidationsHandler was not reset before being initialized');
21
+ }
22
+ handlerState = 2 /* HandlerState.INITIALIZED */;
23
+ }
24
+ function addInvalidationToEvent(event, invalidation) {
25
+ const existingInvalidations = invalidationsForEvent.get(event) || [];
26
+ const syntheticInvalidation = {
27
+ ...invalidation,
28
+ name: 'SyntheticInvalidation',
29
+ frame: invalidation.args.data.frame,
30
+ nodeId: invalidation.args.data.nodeId,
31
+ rawEvent: invalidation,
32
+ };
33
+ if (invalidation.args.data.nodeName) {
34
+ syntheticInvalidation.nodeName = invalidation.args.data.nodeName;
35
+ }
36
+ if (invalidation.args.data.reason) {
37
+ syntheticInvalidation.reason = invalidation.args.data.reason;
38
+ }
39
+ if (invalidation.args.data.stackTrace) {
40
+ syntheticInvalidation.stackTrace = invalidation.args.data.stackTrace;
41
+ }
42
+ existingInvalidations.push(syntheticInvalidation);
43
+ invalidationsForEvent.set(event, existingInvalidations);
44
+ }
45
+ export function handleEvent(event) {
46
+ if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {
47
+ lastRecalcStyleEvent = event;
48
+ // Associate any prior invalidations with this recalc event.
49
+ for (const invalidation of allInvalidationTrackingEvents) {
50
+ if (Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {
51
+ // LayoutInvalidation events cannot be associated with a LayoutTree
52
+ // event.
53
+ continue;
54
+ }
55
+ const recalcFrameId = lastRecalcStyleEvent.args.beginData?.frame;
56
+ if (recalcFrameId && invalidation.args.data.frame === recalcFrameId) {
57
+ addInvalidationToEvent(event, invalidation);
58
+ }
59
+ }
60
+ return;
61
+ }
62
+ if (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||
63
+ Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||
64
+ Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event) ||
65
+ Types.TraceEvents.isTraceEventLayoutInvalidationTracking(event)) {
66
+ if (hasPainted) {
67
+ // If we have painted, then we can clear out the list of all existing
68
+ // invalidations, as we cannot associate them across frames.
69
+ allInvalidationTrackingEvents.length = 0;
70
+ lastRecalcStyleEvent = null;
71
+ hasPainted = false;
72
+ }
73
+ // Style invalidation events can occur before and during recalc styles. When we get a recalc style event (aka TraceEventUpdateLayoutTree), we check and associate any prior invalidations with it.
74
+ // But any invalidations that occur during a TraceEventUpdateLayoutTree
75
+ // event would be reported in trace events after. So each time we get an
76
+ // invalidation that might be due to a style recalc, we check if the
77
+ // timings overlap and if so associate them.
78
+ if (lastRecalcStyleEvent &&
79
+ (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||
80
+ Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||
81
+ Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event))) {
82
+ const recalcEndTime = lastRecalcStyleEvent.ts + (lastRecalcStyleEvent.dur || 0);
83
+ if (event.ts >= lastRecalcStyleEvent.ts && event.ts <= recalcEndTime &&
84
+ lastRecalcStyleEvent.args.beginData?.frame === event.args.data.frame) {
85
+ addInvalidationToEvent(lastRecalcStyleEvent, event);
86
+ }
87
+ }
88
+ allInvalidationTrackingEvents.push(event);
89
+ return;
90
+ }
91
+ if (Types.TraceEvents.isTraceEventPaint(event)) {
92
+ // Used to ensure that we do not create relationships across frames.
93
+ hasPainted = true;
94
+ return;
95
+ }
96
+ if (Types.TraceEvents.isTraceEventLayout(event)) {
97
+ const layoutFrame = event.args.beginData.frame;
98
+ for (const invalidation of allInvalidationTrackingEvents) {
99
+ // The only invalidations that cause a Layout are LayoutInvalidations :)
100
+ if (!Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {
101
+ continue;
102
+ }
103
+ if (invalidation.args.data.frame === layoutFrame) {
104
+ addInvalidationToEvent(event, invalidation);
105
+ }
106
+ }
107
+ }
108
+ }
109
+ export async function finalize() {
110
+ if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
111
+ throw new Error('InvalidationsHandler is not initialized');
112
+ }
113
+ handlerState = 3 /* HandlerState.FINALIZED */;
114
+ }
115
+ export function data() {
116
+ return {
117
+ invalidationsForEvent: new Map(invalidationsForEvent),
118
+ };
119
+ }
120
+ //# sourceMappingURL=InvalidationsHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvalidationsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InvalidationsHandler.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 Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst invalidationsForEvent = new Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>();\n\nlet lastRecalcStyleEvent: Types.TraceEvents.TraceEventUpdateLayoutTree|null = null;\n\n// Used to track paints so we track invalidations correctly per paint.\nlet hasPainted = false;\n\nconst allInvalidationTrackingEvents:\n Array<Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking|\n Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking|Types.TraceEvents\n .TraceEventStyleInvalidatorInvalidationTracking|Types.TraceEvents.TraceEventLayoutInvalidationTracking> =\n [];\n\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n invalidationsForEvent.clear();\n lastRecalcStyleEvent = null;\n allInvalidationTrackingEvents.length = 0;\n hasPainted = false;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('InvalidationsHandler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction addInvalidationToEvent(\n event: Types.TraceEvents.TraceEventData,\n invalidation: Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking|\n Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking|\n Types.TraceEvents.TraceEventStyleInvalidatorInvalidationTracking|\n Types.TraceEvents.TraceEventLayoutInvalidationTracking): void {\n const existingInvalidations = invalidationsForEvent.get(event) || [];\n\n const syntheticInvalidation: Types.TraceEvents.SyntheticInvalidation = {\n ...invalidation,\n name: 'SyntheticInvalidation',\n frame: invalidation.args.data.frame,\n nodeId: invalidation.args.data.nodeId,\n rawEvent: invalidation,\n };\n\n if (invalidation.args.data.nodeName) {\n syntheticInvalidation.nodeName = invalidation.args.data.nodeName;\n }\n if (invalidation.args.data.reason) {\n syntheticInvalidation.reason = invalidation.args.data.reason;\n }\n if (invalidation.args.data.stackTrace) {\n syntheticInvalidation.stackTrace = invalidation.args.data.stackTrace;\n }\n\n existingInvalidations.push(syntheticInvalidation);\n invalidationsForEvent.set(event, existingInvalidations);\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {\n lastRecalcStyleEvent = event;\n\n // Associate any prior invalidations with this recalc event.\n for (const invalidation of allInvalidationTrackingEvents) {\n if (Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {\n // LayoutInvalidation events cannot be associated with a LayoutTree\n // event.\n continue;\n }\n\n const recalcFrameId = lastRecalcStyleEvent.args.beginData?.frame;\n\n if (recalcFrameId && invalidation.args.data.frame === recalcFrameId) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n return;\n }\n\n if (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventLayoutInvalidationTracking(event)) {\n if (hasPainted) {\n // If we have painted, then we can clear out the list of all existing\n // invalidations, as we cannot associate them across frames.\n allInvalidationTrackingEvents.length = 0;\n lastRecalcStyleEvent = null;\n hasPainted = false;\n }\n\n // Style invalidation events can occur before and during recalc styles. When we get a recalc style event (aka TraceEventUpdateLayoutTree), we check and associate any prior invalidations with it.\n // But any invalidations that occur during a TraceEventUpdateLayoutTree\n // event would be reported in trace events after. So each time we get an\n // invalidation that might be due to a style recalc, we check if the\n // timings overlap and if so associate them.\n if (lastRecalcStyleEvent &&\n (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event))) {\n const recalcEndTime = lastRecalcStyleEvent.ts + (lastRecalcStyleEvent.dur || 0);\n if (event.ts >= lastRecalcStyleEvent.ts && event.ts <= recalcEndTime &&\n lastRecalcStyleEvent.args.beginData?.frame === event.args.data.frame) {\n addInvalidationToEvent(lastRecalcStyleEvent, event);\n }\n }\n\n allInvalidationTrackingEvents.push(event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventPaint(event)) {\n // Used to ensure that we do not create relationships across frames.\n hasPainted = true;\n return;\n }\n\n if (Types.TraceEvents.isTraceEventLayout(event)) {\n const layoutFrame = event.args.beginData.frame;\n for (const invalidation of allInvalidationTrackingEvents) {\n // The only invalidations that cause a Layout are LayoutInvalidations :)\n if (!Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {\n continue;\n }\n\n if (invalidation.args.data.frame === layoutFrame) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('InvalidationsHandler is not initialized');\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\ninterface InvalidationsData {\n invalidationsForEvent: Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>;\n}\n\nexport function data(): InvalidationsData {\n return {\n invalidationsForEvent: new Map(invalidationsForEvent),\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import * as Types from '../types/types.js';
2
+ import type * as Protocol from '../../../generated/protocol.js';
3
+ export declare function reset(): void;
4
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
5
+ export declare function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate>;
@@ -0,0 +1,38 @@
1
+ // Copyright 2022 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
+ /**
6
+ * If the LCP resource was an image, and that image was fetched over the
7
+ * network, we want to be able to find the network request in order to construct
8
+ * the critical path for an LCP image.
9
+ * Within the trace file there are `LargestImagePaint::Candidate` events.
10
+ * Within their data object, they contain a `DOMNodeId` property, which maps to
11
+ * the DOM Node ID for that image.
12
+ *
13
+ * This id maps exactly to the `data.nodeId` property that a
14
+ * `LargestContentfulPaint::Candidate` will have. So, when we find an image
15
+ * paint candidate, we can store it, keying it on the node ID.
16
+ * Then, when it comes to finding the network request for an LCP image, we can
17
+ *
18
+ * use the nodeId from the LCP candidate to find the image candidate. That image
19
+ * candidate also contains a `imageUrl` property, which will have the full URL
20
+ * to the image.
21
+ **/
22
+ const imageByDOMNodeId = new Map();
23
+ export function reset() {
24
+ imageByDOMNodeId.clear();
25
+ }
26
+ export function handleEvent(event) {
27
+ if (!Types.TraceEvents.isTraceEventLargestImagePaintCandidate(event)) {
28
+ return;
29
+ }
30
+ if (!event.args.data) {
31
+ return;
32
+ }
33
+ imageByDOMNodeId.set(event.args.data.DOMNodeId, event);
34
+ }
35
+ export function data() {
36
+ return new Map(imageByDOMNodeId);
37
+ }
38
+ //# sourceMappingURL=LargestImagePaintHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LargestImagePaintHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/LargestImagePaintHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;;;;;;;;;;IAgBI;AACJ,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAsF,CAAC;AAEvH,MAAM,UAAU,KAAK;IACnB,gBAAgB,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,sCAAsC,CAAC,KAAK,CAAC,EAAE;QACpE,OAAO;KACR;IAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;QACpB,OAAO;KACR;IAED,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACnC,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\nimport type * as Protocol from '../../../generated/protocol.js';\n/**\n * If the LCP resource was an image, and that image was fetched over the\n * network, we want to be able to find the network request in order to construct\n * the critical path for an LCP image.\n * Within the trace file there are `LargestImagePaint::Candidate` events.\n * Within their data object, they contain a `DOMNodeId` property, which maps to\n * the DOM Node ID for that image.\n *\n * This id maps exactly to the `data.nodeId` property that a\n * `LargestContentfulPaint::Candidate` will have. So, when we find an image\n * paint candidate, we can store it, keying it on the node ID.\n * Then, when it comes to finding the network request for an LCP image, we can\n *\n * use the nodeId from the LCP candidate to find the image candidate. That image\n * candidate also contains a `imageUrl` property, which will have the full URL\n * to the image.\n **/\nconst imageByDOMNodeId = new Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate>();\n\nexport function reset(): void {\n imageByDOMNodeId.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!Types.TraceEvents.isTraceEventLargestImagePaintCandidate(event)) {\n return;\n }\n\n if (!event.args.data) {\n return;\n }\n\n imageByDOMNodeId.set(event.args.data.DOMNodeId, event);\n}\n\nexport function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate> {\n return new Map(imageByDOMNodeId);\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type * as Protocol from '../../../generated/protocol.js';
2
+ import * as Types from '../types/types.js';
3
+ export declare function reset(): void;
4
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
5
+ export declare function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate>;
@@ -0,0 +1,26 @@
1
+ // Copyright 2022 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
+ /**
6
+ * A trace file will contain all the text paints that were candidates for the
7
+ * LargestTextPaint. If an LCP event is text, it will point to one of these
8
+ * candidates, so we store them by their DOM Node ID.
9
+ **/
10
+ const textPaintByDOMNodeId = new Map();
11
+ export function reset() {
12
+ textPaintByDOMNodeId.clear();
13
+ }
14
+ export function handleEvent(event) {
15
+ if (!Types.TraceEvents.isTraceEventLargestTextPaintCandidate(event)) {
16
+ return;
17
+ }
18
+ if (!event.args.data) {
19
+ return;
20
+ }
21
+ textPaintByDOMNodeId.set(event.args.data.DOMNodeId, event);
22
+ }
23
+ export function data() {
24
+ return new Map(textPaintByDOMNodeId);
25
+ }
26
+ //# sourceMappingURL=LargestTextPaintHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LargestTextPaintHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/LargestTextPaintHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAG7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAC3C;;;;IAII;AACJ,MAAM,oBAAoB,GACtB,IAAI,GAAG,EAAqF,CAAC;AAEjG,MAAM,UAAU,KAAK;IACnB,oBAAoB,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,qCAAqC,CAAC,KAAK,CAAC,EAAE;QACnE,OAAO;KACR;IAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;QACpB,OAAO;KACR;IAED,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,IAAI,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACvC,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../../generated/protocol.js';\nimport * as Types from '../types/types.js';\n/**\n * A trace file will contain all the text paints that were candidates for the\n * LargestTextPaint. If an LCP event is text, it will point to one of these\n * candidates, so we store them by their DOM Node ID.\n **/\nconst textPaintByDOMNodeId =\n new Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate>();\n\nexport function reset(): void {\n textPaintByDOMNodeId.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!Types.TraceEvents.isTraceEventLargestTextPaintCandidate(event)) {\n return;\n }\n\n if (!event.args.data) {\n return;\n }\n\n textPaintByDOMNodeId.set(event.args.data.DOMNodeId, event);\n}\n\nexport function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate> {\n return new Map(textPaintByDOMNodeId);\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import * as Types from '../types/types.js';
2
+ import { type TraceEventHandlerName } from './types.js';
3
+ export declare function reset(): void;
4
+ export declare function initialize(): void;
5
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
6
+ export declare function finalize(): Promise<void>;
7
+ export interface LayerTreeData {
8
+ paints: Types.TraceEvents.TraceEventPaint[];
9
+ snapshots: Types.TraceEvents.TraceEventDisplayItemListSnapshot[];
10
+ paintsToSnapshots: Map<Types.TraceEvents.TraceEventPaint, Types.TraceEvents.TraceEventDisplayItemListSnapshot>;
11
+ }
12
+ export declare function data(): LayerTreeData;
13
+ export declare function deps(): TraceEventHandlerName[];
@@ -0,0 +1,116 @@
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 */;
8
+ const paintEvents = [];
9
+ const snapshotEvents = [];
10
+ const paintToSnapshotMap = new Map();
11
+ let lastPaintForLayerId = {};
12
+ let currentMainFrameLayerTreeId = null;
13
+ const updateLayerEvents = [];
14
+ const relevantEvents = [];
15
+ export function reset() {
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;
24
+ }
25
+ export function initialize() {
26
+ if (handlerState !== 1 /* HandlerState.UNINITIALIZED */) {
27
+ throw new Error('LayerTree Handler was not reset before being initialized');
28
+ }
29
+ handlerState = 2 /* HandlerState.INITIALIZED */;
30
+ }
31
+ export function handleEvent(event) {
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
+ }
40
+ }
41
+ export async function finalize() {
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);
102
+ }
103
+ }
104
+ handlerState = 3 /* HandlerState.FINALIZED */;
105
+ }
106
+ export function data() {
107
+ return {
108
+ paints: Array.from(paintEvents),
109
+ snapshots: Array.from(snapshotEvents),
110
+ paintsToSnapshots: new Map(paintToSnapshotMap),
111
+ };
112
+ }
113
+ export function deps() {
114
+ return ['Meta'];
115
+ }
116
+ //# sourceMappingURL=LayerTreeHandler.js.map
@@ -0,0 +1 @@
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"]}