@paulirish/trace_engine 0.0.10 → 0.0.12

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 (256) hide show
  1. package/README.md +1 -1
  2. package/analyze-trace.mjs +1 -1
  3. package/core/platform/DevToolsPath.d.ts +4 -13
  4. package/core/platform/DevToolsPath.js +7 -4
  5. package/core/platform/DevToolsPath.js.map +1 -7
  6. package/core/platform/MimeType.d.ts +27 -0
  7. package/core/platform/MimeType.js +119 -86
  8. package/core/platform/MimeType.js.map +1 -7
  9. package/core/platform/Timing.d.ts +7 -0
  10. package/core/platform/Timing.js +7 -4
  11. package/core/platform/Timing.js.map +1 -7
  12. package/core/platform/UIString.d.ts +2 -5
  13. package/core/platform/UIString.js +5 -2
  14. package/core/platform/UIString.js.map +1 -7
  15. package/core/platform/UserVisibleError.js +19 -10
  16. package/core/platform/UserVisibleError.js.map +1 -7
  17. package/core/platform/array-utilities.d.ts +48 -10
  18. package/core/platform/array-utilities.js +160 -124
  19. package/core/platform/array-utilities.js.map +1 -7
  20. package/core/platform/brand.d.ts +14 -0
  21. package/core/platform/brand.js +5 -1
  22. package/core/platform/brand.js.map +1 -7
  23. package/core/platform/date-utilities.js +10 -6
  24. package/core/platform/date-utilities.js.map +1 -7
  25. package/core/platform/dom-utilities.d.ts +3 -1
  26. package/core/platform/dom-utilities.js +94 -83
  27. package/core/platform/dom-utilities.js.map +1 -7
  28. package/core/platform/keyboard-utilities.d.ts +2 -0
  29. package/core/platform/keyboard-utilities.js +15 -24
  30. package/core/platform/keyboard-utilities.js.map +1 -7
  31. package/core/platform/map-utilities.d.ts +4 -0
  32. package/core/platform/map-utilities.js +66 -60
  33. package/core/platform/map-utilities.js.map +1 -7
  34. package/core/platform/number-utilities.js +66 -55
  35. package/core/platform/number-utilities.js.map +1 -7
  36. package/core/platform/platform.d.ts +5 -1
  37. package/core/platform/platform.js +54 -37
  38. package/core/platform/platform.js.map +1 -7
  39. package/core/platform/promise-utilities.d.ts +10 -0
  40. package/core/platform/promise-utilities.js +16 -8
  41. package/core/platform/promise-utilities.js.map +1 -7
  42. package/core/platform/set-utilities.js +20 -17
  43. package/core/platform/set-utilities.js.map +1 -7
  44. package/core/platform/string-utilities.d.ts +32 -1
  45. package/core/platform/string-utilities.js +453 -379
  46. package/core/platform/string-utilities.js.map +1 -7
  47. package/core/platform/typescript-utilities.d.ts +5 -5
  48. package/core/platform/typescript-utilities.js +19 -7
  49. package/core/platform/typescript-utilities.js.map +1 -7
  50. package/generated/protocol.d.ts +2081 -347
  51. package/generated/protocol.js +5 -2230
  52. package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
  53. package/models/cpu_profile/CPUProfileDataModel.js +492 -359
  54. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -7
  55. package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
  56. package/models/cpu_profile/ProfileTreeModel.js +87 -82
  57. package/models/cpu_profile/ProfileTreeModel.js.map +1 -7
  58. package/models/cpu_profile/cpu_profile.d.ts +3 -0
  59. package/models/cpu_profile/cpu_profile.js +7 -7
  60. package/models/cpu_profile/cpu_profile.js.map +1 -7
  61. package/models/trace/EntriesFilter.d.ts +55 -0
  62. package/models/trace/EntriesFilter.js +227 -166
  63. package/models/trace/EntriesFilter.js.map +1 -7
  64. package/models/trace/LegacyTracingModel.js.map +1 -7
  65. package/models/trace/ModelImpl.d.ts +110 -0
  66. package/models/trace/ModelImpl.js +161 -102
  67. package/models/trace/ModelImpl.js.map +1 -7
  68. package/models/trace/Processor.d.ts +36 -0
  69. package/models/trace/Processor.js +197 -163
  70. package/models/trace/Processor.js.map +1 -7
  71. package/models/trace/TracingManager.js.map +1 -7
  72. package/models/trace/extras/FetchNodes.d.ts +46 -0
  73. package/models/trace/extras/FetchNodes.js +132 -91
  74. package/models/trace/extras/FetchNodes.js.map +1 -7
  75. package/models/trace/extras/FilmStrip.d.ts +19 -0
  76. package/models/trace/extras/FilmStrip.js +38 -31
  77. package/models/trace/extras/FilmStrip.js.map +1 -7
  78. package/models/trace/extras/MainThreadActivity.d.ts +2 -0
  79. package/models/trace/extras/MainThreadActivity.js +72 -56
  80. package/models/trace/extras/MainThreadActivity.js.map +1 -7
  81. package/models/trace/extras/Metadata.d.ts +2 -0
  82. package/models/trace/extras/Metadata.js +42 -26
  83. package/models/trace/extras/Metadata.js.map +1 -7
  84. package/models/trace/extras/extras.js.map +1 -7
  85. package/models/trace/handlers/AnimationHandler.d.ts +8 -0
  86. package/models/trace/handlers/AnimationHandler.js +22 -20
  87. package/models/trace/handlers/AnimationHandler.js.map +1 -7
  88. package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
  89. package/models/trace/handlers/AuctionWorkletsHandler.js +143 -89
  90. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -7
  91. package/models/trace/handlers/FramesHandler.d.ts +76 -0
  92. package/models/trace/handlers/FramesHandler.js +424 -355
  93. package/models/trace/handlers/FramesHandler.js.map +1 -7
  94. package/models/trace/handlers/GPUHandler.d.ts +11 -0
  95. package/models/trace/handlers/GPUHandler.js +41 -37
  96. package/models/trace/handlers/GPUHandler.js.map +1 -7
  97. package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
  98. package/models/trace/handlers/InitiatorsHandler.js +164 -113
  99. package/models/trace/handlers/InitiatorsHandler.js.map +1 -7
  100. package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
  101. package/models/trace/handlers/InvalidationsHandler.js +101 -79
  102. package/models/trace/handlers/InvalidationsHandler.js.map +1 -7
  103. package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
  104. package/models/trace/handlers/LargestImagePaintHandler.js +32 -12
  105. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -7
  106. package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
  107. package/models/trace/handlers/LargestTextPaintHandler.js +20 -12
  108. package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -7
  109. package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
  110. package/models/trace/handlers/LayerTreeHandler.js +96 -70
  111. package/models/trace/handlers/LayerTreeHandler.js.map +1 -7
  112. package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
  113. package/models/trace/handlers/LayoutShiftsHandler.js +304 -227
  114. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -7
  115. package/models/trace/handlers/MemoryHandler.d.ts +7 -0
  116. package/models/trace/handlers/MemoryHandler.js +14 -11
  117. package/models/trace/handlers/MemoryHandler.js.map +1 -7
  118. package/models/trace/handlers/MetaHandler.d.ts +37 -0
  119. package/models/trace/handlers/MetaHandler.js +314 -226
  120. package/models/trace/handlers/MetaHandler.js.map +1 -7
  121. package/models/trace/handlers/ModelHandlers.d.ts +21 -0
  122. package/models/trace/handlers/ModelHandlers.js +25 -22
  123. package/models/trace/handlers/ModelHandlers.js.map +1 -7
  124. package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
  125. package/models/trace/handlers/NetworkRequestsHandler.js +342 -218
  126. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -7
  127. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
  128. package/models/trace/handlers/PageLoadMetricsHandler.js +357 -284
  129. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -7
  130. package/models/trace/handlers/RendererHandler.d.ts +101 -0
  131. package/models/trace/handlers/RendererHandler.js +295 -191
  132. package/models/trace/handlers/RendererHandler.js.map +1 -7
  133. package/models/trace/handlers/SamplesHandler.d.ts +46 -0
  134. package/models/trace/handlers/SamplesHandler.js +195 -158
  135. package/models/trace/handlers/SamplesHandler.js.map +1 -7
  136. package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
  137. package/models/trace/handlers/ScreenshotsHandler.js +63 -41
  138. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -7
  139. package/models/trace/handlers/Threads.d.ts +33 -0
  140. package/models/trace/handlers/Threads.js +85 -67
  141. package/models/trace/handlers/Threads.js.map +1 -7
  142. package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
  143. package/models/trace/handlers/UserInteractionsHandler.js +240 -141
  144. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -7
  145. package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
  146. package/models/trace/handlers/UserTimingsHandler.js +91 -80
  147. package/models/trace/handlers/UserTimingsHandler.js.map +1 -7
  148. package/models/trace/handlers/WarningsHandler.d.ts +14 -0
  149. package/models/trace/handlers/WarningsHandler.js +100 -62
  150. package/models/trace/handlers/WarningsHandler.js.map +1 -7
  151. package/models/trace/handlers/WorkersHandler.d.ts +11 -0
  152. package/models/trace/handlers/WorkersHandler.js +40 -38
  153. package/models/trace/handlers/WorkersHandler.js.map +1 -7
  154. package/models/trace/handlers/handlers.d.ts +3 -0
  155. package/models/trace/handlers/handlers.js +7 -4
  156. package/models/trace/handlers/handlers.js.map +1 -7
  157. package/models/trace/handlers/types.d.ts +45 -0
  158. package/models/trace/handlers/types.js +15 -15
  159. package/models/trace/handlers/types.js.map +1 -7
  160. package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
  161. package/models/trace/helpers/SamplesIntegrator.js +381 -204
  162. package/models/trace/helpers/SamplesIntegrator.js.map +1 -7
  163. package/models/trace/helpers/Timing.d.ts +26 -0
  164. package/models/trace/helpers/Timing.js +131 -110
  165. package/models/trace/helpers/Timing.js.map +1 -7
  166. package/models/trace/helpers/Trace.d.ts +37 -0
  167. package/models/trace/helpers/Trace.js +200 -166
  168. package/models/trace/helpers/Trace.js.map +1 -7
  169. package/models/trace/helpers/TreeHelpers.d.ts +90 -0
  170. package/models/trace/helpers/TreeHelpers.js +203 -100
  171. package/models/trace/helpers/TreeHelpers.js.map +1 -7
  172. package/models/trace/helpers/helpers.d.ts +4 -0
  173. package/models/trace/helpers/helpers.js +8 -5
  174. package/models/trace/helpers/helpers.js.map +1 -7
  175. package/models/trace/root-causes/LayoutShift.d.ts +119 -0
  176. package/models/trace/root-causes/LayoutShift.js +470 -323
  177. package/models/trace/root-causes/LayoutShift.js.map +1 -7
  178. package/models/trace/root-causes/RootCauses.d.ts +14 -0
  179. package/models/trace/root-causes/RootCauses.js +9 -6
  180. package/models/trace/root-causes/RootCauses.js.map +1 -7
  181. package/models/trace/root-causes/root-causes.d.ts +1 -0
  182. package/models/trace/root-causes/root-causes.js +5 -2
  183. package/models/trace/root-causes/root-causes.js.map +1 -7
  184. package/models/trace/trace.d.ts +11 -0
  185. package/models/trace/trace.js +17 -23
  186. package/models/trace/trace.js.map +1 -7
  187. package/models/trace/types/Configuration.d.ts +33 -0
  188. package/models/trace/types/Configuration.js +25 -14
  189. package/models/trace/types/Configuration.js.map +1 -7
  190. package/models/trace/types/File.d.ts +23 -0
  191. package/models/trace/types/File.js +5 -6
  192. package/models/trace/types/File.js.map +1 -7
  193. package/models/trace/types/Timing.d.ts +25 -0
  194. package/models/trace/types/Timing.js +10 -11
  195. package/models/trace/types/Timing.js.map +1 -7
  196. package/models/trace/types/TraceEvents.d.ts +1571 -0
  197. package/models/trace/types/TraceEvents.js +174 -381
  198. package/models/trace/types/TraceEvents.js.map +1 -7
  199. package/models/trace/types/types.d.ts +4 -0
  200. package/models/trace/types/types.js +8 -5
  201. package/models/trace/types/types.js.map +1 -7
  202. package/package.json +1 -1
  203. package/TracingManager.js +0 -0
  204. package/core/platform/devtools_entrypoint-bundle-tsconfig-tsconfig.json +0 -40
  205. package/core/platform/platform.js.compressed +0 -0
  206. package/core/platform/platform.js.hash +0 -1
  207. package/core/platform/platform.prebundle.d.ts +0 -15
  208. package/core/platform/platform.prebundle.js +0 -50
  209. package/core/platform/platform.prebundle.js.map +0 -1
  210. package/core/platform/platform.prebundle.ts +0 -64
  211. package/extras/extras.js +0 -0
  212. package/models/trace/SDKServices.js +0 -104
  213. package/models/trace/SDKServices.js.map +0 -7
  214. package/models/trace/TraceProcessor.js +0 -133
  215. package/models/trace/TraceProcessor.js.map +0 -7
  216. package/models/trace/TreeManipulator.js +0 -85
  217. package/models/trace/TreeManipulator.js.map +0 -7
  218. package/models/trace/devtools_entrypoint-legacy-typescript-tsconfig.json +0 -43
  219. package/models/trace/frames/TimelineFrameModel.js +0 -392
  220. package/models/trace/frames/TimelineFrameModel.js.map +0 -7
  221. package/models/trace/frames/bundle-tsconfig.json +0 -1
  222. package/models/trace/frames/devtools_entrypoint-bundle-typescript-tsconfig.json +0 -43
  223. package/models/trace/frames/frames-tsconfig.json +0 -58
  224. package/models/trace/frames/frames.js +0 -5
  225. package/models/trace/frames/frames.js.map +0 -7
  226. package/models/trace/handlers/Migration.js +0 -27
  227. package/models/trace/handlers/Migration.js.map +0 -7
  228. package/models/trace/handlers/UberFramesHandler.js +0 -293
  229. package/models/trace/handlers/UberFramesHandler.js.map +0 -7
  230. package/models/trace/legacy-tsconfig.json +0 -1
  231. package/models/trace/sdk_services/DOMNodeLookup.js +0 -41
  232. package/models/trace/sdk_services/DOMNodeLookup.js.map +0 -7
  233. package/models/trace/sdk_services/LayoutShifts.js +0 -68
  234. package/models/trace/sdk_services/LayoutShifts.js.map +0 -7
  235. package/models/trace/sdk_services/bundle-tsconfig.json +0 -1
  236. package/models/trace/sdk_services/devtools_entrypoint-bundle-typescript-tsconfig.json +0 -41
  237. package/models/trace/sdk_services/sdk_services-tsconfig.json +0 -57
  238. package/models/trace/sdk_services/sdk_services.js +0 -7
  239. package/models/trace/sdk_services/sdk_services.js.map +0 -7
  240. package/models/trace/trace-legacy.js +0 -16
  241. package/models/trace/trace-legacy.js.map +0 -7
  242. package/models/trace/worker/Processor.js +0 -143
  243. package/models/trace/worker/Processor.js.map +0 -7
  244. package/models/trace/worker/Types.js +0 -1
  245. package/models/trace/worker/Types.js.map +0 -7
  246. package/models/trace/worker/bundle-tsconfig.json +0 -1
  247. package/models/trace/worker/devtools_entrypoint-bundle-typescript-tsconfig.json +0 -41
  248. package/models/trace/worker/devtools_entrypoint-worker_entrypoint-typescript-tsconfig.json +0 -41
  249. package/models/trace/worker/processor-tsconfig.json +0 -45
  250. package/models/trace/worker/worker.js +0 -7
  251. package/models/trace/worker/worker.js.map +0 -7
  252. package/models/trace/worker/worker_entrypoint-tsconfig.json +0 -1
  253. package/models/trace/worker/worker_entrypoint.js +0 -36
  254. package/models/trace/worker/worker_entrypoint.js.map +0 -7
  255. package/trace.mjs +0 -6980
  256. package/trace.mjs.map +0 -8
@@ -1,119 +1,222 @@
1
- import * as Types from "../types/types.js";
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';
2
5
  let nodeIdCount = 0;
3
- export const makeTraceEntryNodeId = () => ++nodeIdCount;
6
+ export const makeTraceEntryNodeId = () => (++nodeIdCount);
4
7
  export const makeEmptyTraceEntryTree = () => ({
5
- roots: /* @__PURE__ */ new Set(),
6
- maxDepth: 0
8
+ roots: new Set(),
9
+ maxDepth: 0,
7
10
  });
8
11
  export const makeEmptyTraceEntryNode = (entry, id) => ({
9
- entry,
10
- id,
11
- parent: null,
12
- children: [],
13
- depth: 0
12
+ entry,
13
+ id,
14
+ parent: null,
15
+ children: [],
16
+ depth: 0,
14
17
  });
15
18
  class TraceEntryNodeIdTag {
16
- #tag;
19
+ /* eslint-disable-next-line no-unused-private-class-members */
20
+ #tag;
17
21
  }
22
+ /**
23
+ * Builds a hierarchy of the entries (trace events and profile calls) in
24
+ * a particular thread of a particular process, assuming that they're
25
+ * sorted, by iterating through all of the events in order.
26
+ *
27
+ * The approach is analogous to how a parser would be implemented. A
28
+ * stack maintains local context. A scanner peeks and pops from the data
29
+ * stream. Various "tokens" (events) are treated as "whitespace"
30
+ * (ignored).
31
+ *
32
+ * The tree starts out empty and is populated as the hierarchy is built.
33
+ * The nodes are also assumed to be created empty, with no known parent
34
+ * or children.
35
+ *
36
+ * Complexity: O(n), where n = number of events
37
+ */
18
38
  export function treify(entries, options) {
19
- const entryToNode = /* @__PURE__ */ new Map();
20
- const stack = [];
21
- nodeIdCount = -1;
22
- const tree = makeEmptyTraceEntryTree();
23
- for (let i = 0; i < entries.length; i++) {
24
- const event = entries[i];
25
- if (options && !options.filter.has(event.name)) {
26
- continue;
39
+ // As we construct the tree, store a map of each entry to its node. This
40
+ // means if you are iterating over a list of RendererEntry events you can
41
+ // easily look up that node in the tree.
42
+ const entryToNode = new Map();
43
+ const stack = [];
44
+ // Reset the node id counter for every new renderer.
45
+ nodeIdCount = -1;
46
+ const tree = makeEmptyTraceEntryTree();
47
+ for (let i = 0; i < entries.length; i++) {
48
+ const event = entries[i];
49
+ // If the current event should not be part of the tree, then simply proceed
50
+ // with the next event.
51
+ if (options && !options.filter.has(event.name)) {
52
+ continue;
53
+ }
54
+ const duration = event.dur || 0;
55
+ const nodeId = makeTraceEntryNodeId();
56
+ const node = makeEmptyTraceEntryNode(event, nodeId);
57
+ // If the parent stack is empty, then the current event is a root. Create a
58
+ // node for it, mark it as a root, then proceed with the next event.
59
+ if (stack.length === 0) {
60
+ tree.roots.add(node);
61
+ event.selfTime = Types.Timing.MicroSeconds(duration);
62
+ stack.push(node);
63
+ tree.maxDepth = Math.max(tree.maxDepth, stack.length);
64
+ entryToNode.set(event, node);
65
+ continue;
66
+ }
67
+ const parentNode = stack.at(-1);
68
+ if (parentNode === undefined) {
69
+ throw new Error('Impossible: no parent node found in the stack');
70
+ }
71
+ const parentEvent = parentNode.entry;
72
+ const begin = event.ts;
73
+ const parentBegin = parentEvent.ts;
74
+ const parentDuration = parentEvent.dur || 0;
75
+ const end = begin + duration;
76
+ const parentEnd = parentBegin + parentDuration;
77
+ // Check the relationship between the parent event at the top of the stack,
78
+ // and the current event being processed. There are only 4 distinct
79
+ // possiblities, only 2 of them actually valid, given the assumed sorting:
80
+ // 1. Current event starts before the parent event, ends whenever. (invalid)
81
+ // 2. Current event starts after the parent event, ends whenever. (valid)
82
+ // 3. Current event starts during the parent event, ends after. (invalid)
83
+ // 4. Current event starts and ends during the parent event. (valid)
84
+ // 1. If the current event starts before the parent event, then the data is
85
+ // not sorted properly, messed up some way, or this logic is incomplete.
86
+ const startsBeforeParent = begin < parentBegin;
87
+ if (startsBeforeParent) {
88
+ throw new Error('Impossible: current event starts before the parent event');
89
+ }
90
+ // 2. If the current event starts after the parent event, then it's a new
91
+ // parent. Pop, then handle current event again.
92
+ const startsAfterParent = begin >= parentEnd;
93
+ if (startsAfterParent) {
94
+ stack.pop();
95
+ i--;
96
+ // The last created node has been discarded, so discard this id.
97
+ nodeIdCount--;
98
+ continue;
99
+ }
100
+ // 3. If the current event starts during the parent event, but ends
101
+ // after it, then the data is messed up some way, for example a
102
+ // profile call was sampled too late after its start, ignore the
103
+ // problematic event.
104
+ const endsAfterParent = end > parentEnd;
105
+ if (endsAfterParent) {
106
+ continue;
107
+ }
108
+ // 4. The only remaining case is the common case, where the current event is
109
+ // contained within the parent event. Create a node for the current
110
+ // event, establish the parent/child relationship, then proceed with the
111
+ // next event.
112
+ node.depth = stack.length;
113
+ node.parent = parentNode;
114
+ parentNode.children.push(node);
115
+ event.selfTime = Types.Timing.MicroSeconds(duration);
116
+ if (parentEvent.selfTime !== undefined) {
117
+ parentEvent.selfTime = Types.Timing.MicroSeconds(parentEvent.selfTime - (event.dur || 0));
118
+ }
119
+ stack.push(node);
120
+ tree.maxDepth = Math.max(tree.maxDepth, stack.length);
121
+ entryToNode.set(event, node);
27
122
  }
28
- const duration = event.dur || 0;
29
- const nodeId = makeTraceEntryNodeId();
30
- const node = makeEmptyTraceEntryNode(event, nodeId);
31
- if (stack.length === 0) {
32
- tree.roots.add(node);
33
- event.selfTime = Types.Timing.MicroSeconds(duration);
34
- stack.push(node);
35
- tree.maxDepth = Math.max(tree.maxDepth, stack.length);
36
- entryToNode.set(event, node);
37
- continue;
38
- }
39
- const parentNode = stack.at(-1);
40
- if (parentNode === void 0) {
41
- throw new Error("Impossible: no parent node found in the stack");
42
- }
43
- const parentEvent = parentNode.entry;
44
- const begin = event.ts;
45
- const parentBegin = parentEvent.ts;
46
- const parentDuration = parentEvent.dur || 0;
47
- const end = begin + duration;
48
- const parentEnd = parentBegin + parentDuration;
49
- const startsBeforeParent = begin < parentBegin;
50
- if (startsBeforeParent) {
51
- throw new Error("Impossible: current event starts before the parent event");
52
- }
53
- const startsAfterParent = begin >= parentEnd;
54
- if (startsAfterParent) {
55
- stack.pop();
56
- i--;
57
- nodeIdCount--;
58
- continue;
59
- }
60
- const endsAfterParent = end > parentEnd;
61
- if (endsAfterParent) {
62
- continue;
63
- }
64
- node.depth = stack.length;
65
- node.parent = parentNode;
66
- parentNode.children.push(node);
67
- event.selfTime = Types.Timing.MicroSeconds(duration);
68
- if (parentEvent.selfTime !== void 0) {
69
- parentEvent.selfTime = Types.Timing.MicroSeconds(parentEvent.selfTime - (event.dur || 0));
70
- }
71
- stack.push(node);
72
- tree.maxDepth = Math.max(tree.maxDepth, stack.length);
73
- entryToNode.set(event, node);
74
- }
75
- return { tree, entryToNode };
123
+ return { tree, entryToNode };
76
124
  }
125
+ /**
126
+ * Iterates events in a tree hierarchically, from top to bottom,
127
+ * calling back on every event's start and end in the order
128
+ * as it traverses down and then up the tree.
129
+ *
130
+ * For example, given this tree, the following callbacks
131
+ * are expected to be made in the following order
132
+ * |---------------A---------------|
133
+ * |------B------||-------D------|
134
+ * |---C---|
135
+ *
136
+ * 1. Start A
137
+ * 3. Start B
138
+ * 4. Start C
139
+ * 5. End C
140
+ * 6. End B
141
+ * 7. Start D
142
+ * 8. End D
143
+ * 9. End A
144
+ *
145
+ */
77
146
  export function walkTreeFromEntry(entryToNode, rootEntry, onEntryStart, onEntryEnd) {
78
- const startNode = entryToNode.get(rootEntry);
79
- if (!startNode) {
80
- return;
81
- }
82
- walkTreeByNode(entryToNode, startNode, onEntryStart, onEntryEnd);
147
+ const startNode = entryToNode.get(rootEntry);
148
+ if (!startNode) {
149
+ return;
150
+ }
151
+ walkTreeByNode(entryToNode, startNode, onEntryStart, onEntryEnd);
83
152
  }
153
+ /**
154
+ * Given a Helpers.TreeHelpers.RendererTree, this will iterates events in hierarchically, visiting
155
+ * each root node and working from top to bottom, calling back on every event's
156
+ * start and end in the order as it traverses down and then up the tree.
157
+ *
158
+ * For example, given this tree, the following callbacks
159
+ * are expected to be made in the following order
160
+ * |------------- Task A -------------||-- Task E --|
161
+ * |-- Task B --||-- Task D --|
162
+ * |- Task C -|
163
+ *
164
+ * 1. Start A
165
+ * 3. Start B
166
+ * 4. Start C
167
+ * 5. End C
168
+ * 6. End B
169
+ * 7. Start D
170
+ * 8. End D
171
+ * 9. End A
172
+ * 10. Start E
173
+ * 11. End E
174
+ *
175
+ */
84
176
  export function walkEntireTree(entryToNode, tree, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration) {
85
- for (const rootNode of tree.roots) {
86
- walkTreeByNode(entryToNode, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);
87
- }
177
+ for (const rootNode of tree.roots) {
178
+ walkTreeByNode(entryToNode, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);
179
+ }
88
180
  }
89
181
  function walkTreeByNode(entryToNode, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration) {
90
- if (traceWindowToInclude && !treeNodeIsInWindow(rootNode, traceWindowToInclude)) {
91
- return;
92
- }
93
- if (typeof minDuration !== "undefined") {
94
- const duration = Types.Timing.MicroSeconds(rootNode.entry.ts + Types.Timing.MicroSeconds(rootNode.entry.dur || 0));
95
- if (duration < minDuration) {
96
- return;
182
+ if (traceWindowToInclude && !treeNodeIsInWindow(rootNode, traceWindowToInclude)) {
183
+ // If this node is not within the provided window, we can skip it. We also
184
+ // can skip all its children too, as we know they won't be in the window if
185
+ // their parent is not.
186
+ return;
187
+ }
188
+ if (typeof minDuration !== 'undefined') {
189
+ const duration = Types.Timing.MicroSeconds(rootNode.entry.ts + Types.Timing.MicroSeconds(rootNode.entry.dur || 0));
190
+ if (duration < minDuration) {
191
+ return;
192
+ }
193
+ }
194
+ onEntryStart(rootNode.entry);
195
+ for (const child of rootNode.children) {
196
+ walkTreeByNode(entryToNode, child, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);
97
197
  }
98
- }
99
- onEntryStart(rootNode.entry);
100
- for (const child of rootNode.children) {
101
- walkTreeByNode(entryToNode, child, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);
102
- }
103
- onEntryEnd(rootNode.entry);
198
+ onEntryEnd(rootNode.entry);
104
199
  }
200
+ /**
201
+ * Returns true if the provided node is partially or fully within the trace
202
+ * window. The entire node does not have to fit inside the window, but it does
203
+ * have to partially intersect it.
204
+ */
105
205
  function treeNodeIsInWindow(node, traceWindow) {
106
- const startTime = node.entry.ts;
107
- const endTime = node.entry.ts + (node.entry.dur || 0);
108
- if (startTime >= traceWindow.min && startTime < traceWindow.max) {
109
- return true;
110
- }
111
- if (endTime > traceWindow.min && endTime <= traceWindow.max) {
112
- return true;
113
- }
114
- if (startTime <= traceWindow.min && endTime >= traceWindow.max) {
115
- return true;
116
- }
117
- return false;
206
+ const startTime = node.entry.ts;
207
+ const endTime = node.entry.ts + (node.entry.dur || 0);
208
+ // Min ======= startTime ========= Max => node is within window
209
+ if (startTime >= traceWindow.min && startTime < traceWindow.max) {
210
+ return true;
211
+ }
212
+ // Min ======= endTime ========= Max => node is within window
213
+ if (endTime > traceWindow.min && endTime <= traceWindow.max) {
214
+ return true;
215
+ }
216
+ // startTime ==== Min ======== Max === endTime => node spans greater than the window so is in it.
217
+ if (startTime <= traceWindow.min && endTime >= traceWindow.max) {
218
+ return true;
219
+ }
220
+ return false;
118
221
  }
119
- //# sourceMappingURL=TreeHelpers.js.map
222
+ //# sourceMappingURL=TreeHelpers.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../front_end/models/trace/helpers/TreeHelpers.ts"],
4
- "sourcesContent": ["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\nlet nodeIdCount = 0;\nexport const makeTraceEntryNodeId = (): TraceEntryNodeId => (++nodeIdCount) as TraceEntryNodeId;\n\nexport const makeEmptyTraceEntryTree = (): TraceEntryTree => ({\n roots: new Set(),\n maxDepth: 0,\n});\n\nexport const makeEmptyTraceEntryNode =\n (entry: Types.TraceEvents.SyntheticTraceEntry, id: TraceEntryNodeId): TraceEntryNode => ({\n entry,\n id,\n parent: null,\n children: [],\n depth: 0,\n });\n\nexport interface TraceEntryTree {\n roots: Set<TraceEntryNode>;\n maxDepth: number;\n}\n\nexport interface TraceEntryNode {\n entry: Types.TraceEvents.SyntheticTraceEntry;\n depth: number;\n id: TraceEntryNodeId;\n parent: TraceEntryNode|null;\n children: TraceEntryNode[];\n}\n\nclass TraceEntryNodeIdTag {\n /* eslint-disable-next-line no-unused-private-class-members */\n readonly #tag: (symbol|undefined);\n}\nexport type TraceEntryNodeId = number&TraceEntryNodeIdTag;\n\n/**\n * Builds a hierarchy of the entries (trace events and profile calls) in\n * a particular thread of a particular process, assuming that they're\n * sorted, by iterating through all of the events in order.\n *\n * The approach is analogous to how a parser would be implemented. A\n * stack maintains local context. A scanner peeks and pops from the data\n * stream. Various \"tokens\" (events) are treated as \"whitespace\"\n * (ignored).\n *\n * The tree starts out empty and is populated as the hierarchy is built.\n * The nodes are also assumed to be created empty, with no known parent\n * or children.\n *\n * Complexity: O(n), where n = number of events\n */\nexport function treify(entries: Types.TraceEvents.SyntheticTraceEntry[], options?: {\n filter: {has: (name: Types.TraceEvents.KnownEventName) => boolean},\n}): {tree: TraceEntryTree, entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>} {\n // As we construct the tree, store a map of each entry to its node. This\n // means if you are iterating over a list of RendererEntry events you can\n // easily look up that node in the tree.\n const entryToNode = new Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>();\n\n const stack = [];\n // Reset the node id counter for every new renderer.\n nodeIdCount = -1;\n const tree = makeEmptyTraceEntryTree();\n\n for (let i = 0; i < entries.length; i++) {\n const event = entries[i];\n // If the current event should not be part of the tree, then simply proceed\n // with the next event.\n if (options && !options.filter.has(event.name as Types.TraceEvents.KnownEventName)) {\n continue;\n }\n\n const duration = event.dur || 0;\n const nodeId = makeTraceEntryNodeId();\n const node = makeEmptyTraceEntryNode(event, nodeId);\n\n // If the parent stack is empty, then the current event is a root. Create a\n // node for it, mark it as a root, then proceed with the next event.\n if (stack.length === 0) {\n tree.roots.add(node);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n continue;\n }\n\n const parentNode = stack.at(-1);\n if (parentNode === undefined) {\n throw new Error('Impossible: no parent node found in the stack');\n }\n\n const parentEvent = parentNode.entry;\n\n const begin = event.ts;\n const parentBegin = parentEvent.ts;\n const parentDuration = parentEvent.dur || 0;\n const end = begin + duration;\n const parentEnd = parentBegin + parentDuration;\n // Check the relationship between the parent event at the top of the stack,\n // and the current event being processed. There are only 4 distinct\n // possiblities, only 2 of them actually valid, given the assumed sorting:\n // 1. Current event starts before the parent event, ends whenever. (invalid)\n // 2. Current event starts after the parent event, ends whenever. (valid)\n // 3. Current event starts during the parent event, ends after. (invalid)\n // 4. Current event starts and ends during the parent event. (valid)\n\n // 1. If the current event starts before the parent event, then the data is\n // not sorted properly, messed up some way, or this logic is incomplete.\n const startsBeforeParent = begin < parentBegin;\n if (startsBeforeParent) {\n throw new Error('Impossible: current event starts before the parent event');\n }\n\n // 2. If the current event starts after the parent event, then it's a new\n // parent. Pop, then handle current event again.\n const startsAfterParent = begin >= parentEnd;\n if (startsAfterParent) {\n stack.pop();\n i--;\n // The last created node has been discarded, so discard this id.\n nodeIdCount--;\n continue;\n }\n // 3. If the current event starts during the parent event, but ends\n // after it, then the data is messed up some way, for example a\n // profile call was sampled too late after its start, ignore the\n // problematic event.\n const endsAfterParent = end > parentEnd;\n if (endsAfterParent) {\n continue;\n }\n\n // 4. The only remaining case is the common case, where the current event is\n // contained within the parent event. Create a node for the current\n // event, establish the parent/child relationship, then proceed with the\n // next event.\n node.depth = stack.length;\n node.parent = parentNode;\n parentNode.children.push(node);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n if (parentEvent.selfTime !== undefined) {\n parentEvent.selfTime = Types.Timing.MicroSeconds(parentEvent.selfTime - (event.dur || 0));\n }\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n }\n return {tree, entryToNode};\n}\n\n/**\n * Iterates events in a tree hierarchically, from top to bottom,\n * calling back on every event's start and end in the order\n * as it traverses down and then up the tree.\n *\n * For example, given this tree, the following callbacks\n * are expected to be made in the following order\n * |---------------A---------------|\n * |------B------||-------D------|\n * |---C---|\n *\n * 1. Start A\n * 3. Start B\n * 4. Start C\n * 5. End C\n * 6. End B\n * 7. Start D\n * 8. End D\n * 9. End A\n *\n */\nexport function walkTreeFromEntry(\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>,\n rootEntry: Types.TraceEvents.SyntheticTraceEntry,\n onEntryStart: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n onEntryEnd: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n ): void {\n const startNode = entryToNode.get(rootEntry);\n if (!startNode) {\n return;\n }\n walkTreeByNode(entryToNode, startNode, onEntryStart, onEntryEnd);\n}\n\n/**\n * Given a Helpers.TreeHelpers.RendererTree, this will iterates events in hierarchically, visiting\n * each root node and working from top to bottom, calling back on every event's\n * start and end in the order as it traverses down and then up the tree.\n *\n * For example, given this tree, the following callbacks\n * are expected to be made in the following order\n * |------------- Task A -------------||-- Task E --|\n * |-- Task B --||-- Task D --|\n * |- Task C -|\n *\n * 1. Start A\n * 3. Start B\n * 4. Start C\n * 5. End C\n * 6. End B\n * 7. Start D\n * 8. End D\n * 9. End A\n * 10. Start E\n * 11. End E\n *\n */\n\nexport function walkEntireTree(\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>,\n tree: TraceEntryTree,\n onEntryStart: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n onEntryEnd: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n traceWindowToInclude?: Types.Timing.TraceWindowMicroSeconds,\n minDuration?: Types.Timing.MicroSeconds,\n ): void {\n for (const rootNode of tree.roots) {\n walkTreeByNode(entryToNode, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);\n }\n}\n\nfunction walkTreeByNode(\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>,\n rootNode: TraceEntryNode,\n onEntryStart: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n onEntryEnd: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n traceWindowToInclude?: Types.Timing.TraceWindowMicroSeconds,\n minDuration?: Types.Timing.MicroSeconds,\n ): void {\n if (traceWindowToInclude && !treeNodeIsInWindow(rootNode, traceWindowToInclude)) {\n // If this node is not within the provided window, we can skip it. We also\n // can skip all its children too, as we know they won't be in the window if\n // their parent is not.\n return;\n }\n\n if (typeof minDuration !== 'undefined') {\n const duration = Types.Timing.MicroSeconds(\n rootNode.entry.ts + Types.Timing.MicroSeconds(rootNode.entry.dur || 0),\n );\n if (duration < minDuration) {\n return;\n }\n }\n\n onEntryStart(rootNode.entry);\n for (const child of rootNode.children) {\n walkTreeByNode(entryToNode, child, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);\n }\n onEntryEnd(rootNode.entry);\n}\n\n/**\n * Returns true if the provided node is partially or fully within the trace\n * window. The entire node does not have to fit inside the window, but it does\n * have to partially intersect it.\n */\nfunction treeNodeIsInWindow(node: TraceEntryNode, traceWindow: Types.Timing.TraceWindowMicroSeconds): boolean {\n const startTime = node.entry.ts;\n const endTime = node.entry.ts + (node.entry.dur || 0);\n\n // Min ======= startTime ========= Max => node is within window\n if (startTime >= traceWindow.min && startTime < traceWindow.max) {\n return true;\n }\n\n // Min ======= endTime ========= Max => node is within window\n if (endTime > traceWindow.min && endTime <= traceWindow.max) {\n return true;\n }\n\n // startTime ==== Min ======== Max === endTime => node spans greater than the window so is in it.\n if (startTime <= traceWindow.min && endTime >= traceWindow.max) {\n return true;\n }\n\n return false;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
1
+ {"version":3,"file":"TreeHelpers.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/helpers/TreeHelpers.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\nlet nodeIdCount = 0;\nexport const makeTraceEntryNodeId = (): TraceEntryNodeId => (++nodeIdCount) as TraceEntryNodeId;\n\nexport const makeEmptyTraceEntryTree = (): TraceEntryTree => ({\n roots: new Set(),\n maxDepth: 0,\n});\n\nexport const makeEmptyTraceEntryNode =\n (entry: Types.TraceEvents.SyntheticTraceEntry, id: TraceEntryNodeId): TraceEntryNode => ({\n entry,\n id,\n parent: null,\n children: [],\n depth: 0,\n });\n\nexport interface TraceEntryTree {\n roots: Set<TraceEntryNode>;\n maxDepth: number;\n}\n\nexport interface TraceEntryNode {\n entry: Types.TraceEvents.SyntheticTraceEntry;\n depth: number;\n id: TraceEntryNodeId;\n parent: TraceEntryNode|null;\n children: TraceEntryNode[];\n}\n\nclass TraceEntryNodeIdTag {\n /* eslint-disable-next-line no-unused-private-class-members */\n readonly #tag: (symbol|undefined);\n}\nexport type TraceEntryNodeId = number&TraceEntryNodeIdTag;\n\n/**\n * Builds a hierarchy of the entries (trace events and profile calls) in\n * a particular thread of a particular process, assuming that they're\n * sorted, by iterating through all of the events in order.\n *\n * The approach is analogous to how a parser would be implemented. A\n * stack maintains local context. A scanner peeks and pops from the data\n * stream. Various \"tokens\" (events) are treated as \"whitespace\"\n * (ignored).\n *\n * The tree starts out empty and is populated as the hierarchy is built.\n * The nodes are also assumed to be created empty, with no known parent\n * or children.\n *\n * Complexity: O(n), where n = number of events\n */\nexport function treify(entries: Types.TraceEvents.SyntheticTraceEntry[], options?: {\n filter: {has: (name: Types.TraceEvents.KnownEventName) => boolean},\n}): {tree: TraceEntryTree, entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>} {\n // As we construct the tree, store a map of each entry to its node. This\n // means if you are iterating over a list of RendererEntry events you can\n // easily look up that node in the tree.\n const entryToNode = new Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>();\n\n const stack = [];\n // Reset the node id counter for every new renderer.\n nodeIdCount = -1;\n const tree = makeEmptyTraceEntryTree();\n\n for (let i = 0; i < entries.length; i++) {\n const event = entries[i];\n // If the current event should not be part of the tree, then simply proceed\n // with the next event.\n if (options && !options.filter.has(event.name as Types.TraceEvents.KnownEventName)) {\n continue;\n }\n\n const duration = event.dur || 0;\n const nodeId = makeTraceEntryNodeId();\n const node = makeEmptyTraceEntryNode(event, nodeId);\n\n // If the parent stack is empty, then the current event is a root. Create a\n // node for it, mark it as a root, then proceed with the next event.\n if (stack.length === 0) {\n tree.roots.add(node);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n continue;\n }\n\n const parentNode = stack.at(-1);\n if (parentNode === undefined) {\n throw new Error('Impossible: no parent node found in the stack');\n }\n\n const parentEvent = parentNode.entry;\n\n const begin = event.ts;\n const parentBegin = parentEvent.ts;\n const parentDuration = parentEvent.dur || 0;\n const end = begin + duration;\n const parentEnd = parentBegin + parentDuration;\n // Check the relationship between the parent event at the top of the stack,\n // and the current event being processed. There are only 4 distinct\n // possiblities, only 2 of them actually valid, given the assumed sorting:\n // 1. Current event starts before the parent event, ends whenever. (invalid)\n // 2. Current event starts after the parent event, ends whenever. (valid)\n // 3. Current event starts during the parent event, ends after. (invalid)\n // 4. Current event starts and ends during the parent event. (valid)\n\n // 1. If the current event starts before the parent event, then the data is\n // not sorted properly, messed up some way, or this logic is incomplete.\n const startsBeforeParent = begin < parentBegin;\n if (startsBeforeParent) {\n throw new Error('Impossible: current event starts before the parent event');\n }\n\n // 2. If the current event starts after the parent event, then it's a new\n // parent. Pop, then handle current event again.\n const startsAfterParent = begin >= parentEnd;\n if (startsAfterParent) {\n stack.pop();\n i--;\n // The last created node has been discarded, so discard this id.\n nodeIdCount--;\n continue;\n }\n // 3. If the current event starts during the parent event, but ends\n // after it, then the data is messed up some way, for example a\n // profile call was sampled too late after its start, ignore the\n // problematic event.\n const endsAfterParent = end > parentEnd;\n if (endsAfterParent) {\n continue;\n }\n\n // 4. The only remaining case is the common case, where the current event is\n // contained within the parent event. Create a node for the current\n // event, establish the parent/child relationship, then proceed with the\n // next event.\n node.depth = stack.length;\n node.parent = parentNode;\n parentNode.children.push(node);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n if (parentEvent.selfTime !== undefined) {\n parentEvent.selfTime = Types.Timing.MicroSeconds(parentEvent.selfTime - (event.dur || 0));\n }\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n }\n return {tree, entryToNode};\n}\n\n/**\n * Iterates events in a tree hierarchically, from top to bottom,\n * calling back on every event's start and end in the order\n * as it traverses down and then up the tree.\n *\n * For example, given this tree, the following callbacks\n * are expected to be made in the following order\n * |---------------A---------------|\n * |------B------||-------D------|\n * |---C---|\n *\n * 1. Start A\n * 3. Start B\n * 4. Start C\n * 5. End C\n * 6. End B\n * 7. Start D\n * 8. End D\n * 9. End A\n *\n */\nexport function walkTreeFromEntry(\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>,\n rootEntry: Types.TraceEvents.SyntheticTraceEntry,\n onEntryStart: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n onEntryEnd: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n ): void {\n const startNode = entryToNode.get(rootEntry);\n if (!startNode) {\n return;\n }\n walkTreeByNode(entryToNode, startNode, onEntryStart, onEntryEnd);\n}\n\n/**\n * Given a Helpers.TreeHelpers.RendererTree, this will iterates events in hierarchically, visiting\n * each root node and working from top to bottom, calling back on every event's\n * start and end in the order as it traverses down and then up the tree.\n *\n * For example, given this tree, the following callbacks\n * are expected to be made in the following order\n * |------------- Task A -------------||-- Task E --|\n * |-- Task B --||-- Task D --|\n * |- Task C -|\n *\n * 1. Start A\n * 3. Start B\n * 4. Start C\n * 5. End C\n * 6. End B\n * 7. Start D\n * 8. End D\n * 9. End A\n * 10. Start E\n * 11. End E\n *\n */\n\nexport function walkEntireTree(\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>,\n tree: TraceEntryTree,\n onEntryStart: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n onEntryEnd: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n traceWindowToInclude?: Types.Timing.TraceWindowMicroSeconds,\n minDuration?: Types.Timing.MicroSeconds,\n ): void {\n for (const rootNode of tree.roots) {\n walkTreeByNode(entryToNode, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);\n }\n}\n\nfunction walkTreeByNode(\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, TraceEntryNode>,\n rootNode: TraceEntryNode,\n onEntryStart: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n onEntryEnd: (entry: Types.TraceEvents.SyntheticTraceEntry) => void,\n traceWindowToInclude?: Types.Timing.TraceWindowMicroSeconds,\n minDuration?: Types.Timing.MicroSeconds,\n ): void {\n if (traceWindowToInclude && !treeNodeIsInWindow(rootNode, traceWindowToInclude)) {\n // If this node is not within the provided window, we can skip it. We also\n // can skip all its children too, as we know they won't be in the window if\n // their parent is not.\n return;\n }\n\n if (typeof minDuration !== 'undefined') {\n const duration = Types.Timing.MicroSeconds(\n rootNode.entry.ts + Types.Timing.MicroSeconds(rootNode.entry.dur || 0),\n );\n if (duration < minDuration) {\n return;\n }\n }\n\n onEntryStart(rootNode.entry);\n for (const child of rootNode.children) {\n walkTreeByNode(entryToNode, child, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration);\n }\n onEntryEnd(rootNode.entry);\n}\n\n/**\n * Returns true if the provided node is partially or fully within the trace\n * window. The entire node does not have to fit inside the window, but it does\n * have to partially intersect it.\n */\nfunction treeNodeIsInWindow(node: TraceEntryNode, traceWindow: Types.Timing.TraceWindowMicroSeconds): boolean {\n const startTime = node.entry.ts;\n const endTime = node.entry.ts + (node.entry.dur || 0);\n\n // Min ======= startTime ========= Max => node is within window\n if (startTime >= traceWindow.min && startTime < traceWindow.max) {\n return true;\n }\n\n // Min ======= endTime ========= Max => node is within window\n if (endTime > traceWindow.min && endTime <= traceWindow.max) {\n return true;\n }\n\n // startTime ==== Min ======== Max === endTime => node spans greater than the window so is in it.\n if (startTime <= traceWindow.min && endTime >= traceWindow.max) {\n return true;\n }\n\n return false;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export * as SamplesIntegrator from './SamplesIntegrator.js';
2
+ export * as Timing from './Timing.js';
3
+ export * as Trace from './Trace.js';
4
+ export * as TreeHelpers from './TreeHelpers.js';
@@ -1,5 +1,8 @@
1
- export * as SamplesIntegrator from "./SamplesIntegrator.js";
2
- export * as Timing from "./Timing.js";
3
- export * as Trace from "./Trace.js";
4
- export * as TreeHelpers from "./TreeHelpers.js";
5
- //# sourceMappingURL=helpers.js.map
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
+ export * as SamplesIntegrator from './SamplesIntegrator.js';
5
+ export * as Timing from './Timing.js';
6
+ export * as Trace from './Trace.js';
7
+ export * as TreeHelpers from './TreeHelpers.js';
8
+ //# sourceMappingURL=helpers.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../front_end/models/trace/helpers/helpers.ts"],
4
- "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\nexport * as SamplesIntegrator from './SamplesIntegrator.js';\nexport * as Timing from './Timing.js';\nexport * as Trace from './Trace.js';\nexport * as TreeHelpers from './TreeHelpers.js';\n"],
5
- "mappings": "AAIA;AACA;AACA;AACA;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/helpers/helpers.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,WAAW,MAAM,kBAAkB,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\nexport * as SamplesIntegrator from './SamplesIntegrator.js';\nexport * as Timing from './Timing.js';\nexport * as Trace from './Trace.js';\nexport * as TreeHelpers from './TreeHelpers.js';\n"]}
@@ -0,0 +1,119 @@
1
+ import type * as Protocol from '../../../generated/protocol.js';
2
+ import { type TraceParseData } from '../handlers/types.js';
3
+ import * as Types from '../types/types.js';
4
+ import { type RootCauseProtocolInterface } from './RootCauses.js';
5
+ export type CSSDimensions = {
6
+ width?: string;
7
+ height?: string;
8
+ aspectRatio?: string;
9
+ };
10
+ export interface UnsizedMedia {
11
+ node: Protocol.DOM.Node;
12
+ authoredDimensions?: CSSDimensions;
13
+ computedDimensions: CSSDimensions;
14
+ }
15
+ export interface InjectedIframe {
16
+ iframe: Protocol.DOM.Node;
17
+ }
18
+ export interface RootCauseRequest {
19
+ request: Types.TraceEvents.SyntheticNetworkRequest;
20
+ initiator?: Protocol.Network.Initiator;
21
+ }
22
+ export interface FontChange extends RootCauseRequest {
23
+ fontFace: Protocol.CSS.FontFace;
24
+ }
25
+ export interface RenderBlockingRequest extends RootCauseRequest {
26
+ }
27
+ export interface LayoutShiftRootCausesData {
28
+ unsizedMedia: UnsizedMedia[];
29
+ iframes: InjectedIframe[];
30
+ fontChanges: FontChange[];
31
+ renderBlockingRequests: RenderBlockingRequest[];
32
+ scriptStackTrace: Types.TraceEvents.TraceEventCallFrame[];
33
+ }
34
+ export declare class LayoutShiftRootCauses {
35
+ #private;
36
+ constructor(protocolInterface: RootCauseProtocolInterface);
37
+ /**
38
+ * Calculates the potential root causes for a given layout shift event. Once
39
+ * calculated, this data is cached.
40
+ * Note: because you need all layout shift data at once to calculate these
41
+ * correctly, this function will parse the root causes for _all_ layout shift
42
+ * events the first time that it's called. That then populates the cache for
43
+ * each shift, so any subsequent calls are just a constant lookup.
44
+ */
45
+ rootCausesForEvent(modelData: TraceParseData, event: Types.TraceEvents.TraceEventLayoutShift): Promise<Readonly<LayoutShiftRootCausesData> | null>;
46
+ /**
47
+ * Determines potential root causes for shifts
48
+ */
49
+ blameShifts(layoutShifts: Types.TraceEvents.TraceEventLayoutShift[], modelData: TraceParseData): Promise<void>;
50
+ /**
51
+ * "LayoutInvalidations" are a set of trace events dispatched in Blink under the name
52
+ * "layoutInvalidationTracking", which track invalidations on the "Layout"stage of the
53
+ * rendering pipeline. This function utilizes this event to flag potential root causes
54
+ * to layout shifts.
55
+ */
56
+ linkShiftsToLayoutInvalidations(layoutShifts: Types.TraceEvents.TraceEventLayoutShift[], modelData: TraceParseData): Promise<void>;
57
+ /**
58
+ * For every shift looks up the initiator of its corresponding Layout event. This initiator
59
+ * is assigned by the RendererHandler and contains the stack trace of the point in a script
60
+ * that caused a style recalculation or a relayout. This stack trace is added to the shift's
61
+ * potential root causes.
62
+ * Note that a Layout cannot always be linked to a script, in that case, we cannot add a
63
+ * "script causing reflow" as a potential root cause to the corresponding shift.
64
+ */
65
+ linkShiftsToLayoutEvents(layoutShifts: Types.TraceEvents.TraceEventLayoutShift[], modelData: TraceParseData): void;
66
+ /**
67
+ * Given a LayoutInvalidation trace event, determines if it was dispatched
68
+ * because a media element without dimensions was resized.
69
+ */
70
+ getUnsizedMediaRootCause(reason: Types.TraceEvents.LayoutInvalidationReason, layoutInvalidationNode: Protocol.DOM.Node): Promise<UnsizedMedia | null>;
71
+ /**
72
+ * Given a LayoutInvalidation trace event, determines if it was dispatched
73
+ * because a node, which is an ancestor to an iframe, was injected.
74
+ */
75
+ getIframeRootCause(reason: Types.TraceEvents.LayoutInvalidationReason, layoutInvalidationDOMNode: Protocol.DOM.Node): InjectedIframe | null;
76
+ /**
77
+ * Given a layout invalidation event and a sorted array, returns the subset of requests that arrived within a
78
+ * 500ms window before the layout invalidation.
79
+ */
80
+ requestsInInvalidationWindow(layoutInvalidation: Types.TraceEvents.TraceEventLayoutInvalidationTracking | Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking, modelData: TraceParseData): RootCauseRequest[];
81
+ /**
82
+ * Given a LayoutInvalidation trace event, determines if it was dispatched
83
+ * because fonts were changed and if so returns the information of all network
84
+ * request with which the fonts were possibly fetched, if any. The computed
85
+ * network requests are cached for the corresponding prepaint event, meaning
86
+ * that other LayoutInvalidation events that correspond to the same prepaint
87
+ * are not processed and the cached network requests for the prepaint is
88
+ * returned instead.
89
+ */
90
+ getFontChangeRootCause(layoutInvalidation: Types.TraceEvents.TraceEventLayoutInvalidationTracking | Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking, nextPrePaint: Types.TraceEvents.TraceEventPrePaint, modelData: TraceParseData): FontChange[] | null;
91
+ /**
92
+ * Given the requests that arrived within a 500ms window before the layout invalidation, returns the font
93
+ * requests of them.
94
+ */
95
+ getFontRequestsInInvalidationWindow(requestsInInvalidationWindow: RootCauseRequest[]): FontChange[];
96
+ /**
97
+ * Given a LayoutInvalidation trace event, determines if it arrived within a 500ms window before the layout
98
+ * invalidation and if so returns the information of all network request, if any. The computed network
99
+ * requests are cached for the corresponding prepaint event, meaning that other LayoutInvalidation events
100
+ * that correspond to the same prepaint are not processed and the cached network requests for the prepaint is
101
+ * returned instead.
102
+ */
103
+ getRenderBlockRootCause(layoutInvalidation: Types.TraceEvents.TraceEventLayoutInvalidationTracking | Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking, nextPrePaint: Types.TraceEvents.TraceEventPrePaint, modelData: TraceParseData): RenderBlockingRequest[] | null;
104
+ /**
105
+ * Returns a function that retrieves the active value of a given
106
+ * CSS property within the matched styles of the param node.
107
+ * The first occurence within the matched styles is returned and the
108
+ * value is looked up in the following order, which follows CSS
109
+ * specificity:
110
+ * 1. Inline styles.
111
+ * 2. CSS rules matching this node, from all applicable stylesheets.
112
+ * 3. Attribute defined styles.
113
+ */
114
+ nodeMatchedStylesPropertyGetter(node: Protocol.DOM.Node): Promise<((property: string) => string | null)>;
115
+ /**
116
+ * Returns the CSS dimensions set to the node from its matched styles.
117
+ */
118
+ getNodeAuthoredDimensions(node: Protocol.DOM.Node): Promise<CSSDimensions>;
119
+ }