@paulirish/trace_engine 0.0.50 → 0.0.52

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 (236) hide show
  1. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  2. package/core/platform/Constructor.d.ts +2 -2
  3. package/core/platform/Constructor.js.map +1 -1
  4. package/core/platform/StringUtilities.d.ts +2 -5
  5. package/core/platform/StringUtilities.js +4 -4
  6. package/core/platform/StringUtilities.js.map +1 -1
  7. package/core/platform/TypescriptUtilities.d.ts +1 -1
  8. package/core/platform/TypescriptUtilities.js +1 -1
  9. package/core/platform/TypescriptUtilities.js.map +1 -1
  10. package/core/platform/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  11. package/core/platform/platform-tsconfig.json +3 -4
  12. package/core/platform/platform.d.ts +1 -2
  13. package/core/platform/platform.js +1 -2
  14. package/core/platform/platform.js.map +1 -1
  15. package/generated/protocol.d.ts +306 -62
  16. package/locales/af.json +63 -3
  17. package/locales/am.json +63 -3
  18. package/locales/ar.json +63 -3
  19. package/locales/as.json +63 -3
  20. package/locales/az.json +63 -3
  21. package/locales/be.json +64 -4
  22. package/locales/bg.json +62 -2
  23. package/locales/bn.json +63 -3
  24. package/locales/bs.json +63 -3
  25. package/locales/ca.json +62 -2
  26. package/locales/cs.json +62 -2
  27. package/locales/cy.json +63 -3
  28. package/locales/da.json +63 -3
  29. package/locales/de.json +63 -3
  30. package/locales/el.json +62 -2
  31. package/locales/en-GB.json +63 -3
  32. package/locales/en-US.json +58 -22
  33. package/locales/en-XL.json +58 -22
  34. package/locales/es-419.json +63 -3
  35. package/locales/es.json +64 -4
  36. package/locales/et.json +64 -4
  37. package/locales/eu.json +79 -19
  38. package/locales/fa.json +62 -2
  39. package/locales/fi.json +63 -3
  40. package/locales/fil.json +63 -3
  41. package/locales/fr-CA.json +63 -3
  42. package/locales/fr.json +63 -3
  43. package/locales/gl.json +62 -2
  44. package/locales/gu.json +63 -3
  45. package/locales/he.json +63 -3
  46. package/locales/hi.json +62 -2
  47. package/locales/hr.json +63 -3
  48. package/locales/hu.json +62 -2
  49. package/locales/hy.json +63 -3
  50. package/locales/id.json +62 -2
  51. package/locales/is.json +64 -4
  52. package/locales/it.json +64 -4
  53. package/locales/ja.json +63 -3
  54. package/locales/ka.json +63 -3
  55. package/locales/kk.json +62 -2
  56. package/locales/km.json +62 -2
  57. package/locales/kn.json +63 -3
  58. package/locales/ko.json +63 -3
  59. package/locales/ky.json +63 -3
  60. package/locales/lo.json +63 -3
  61. package/locales/lt.json +62 -2
  62. package/locales/lv.json +62 -2
  63. package/locales/mk.json +62 -2
  64. package/locales/ml.json +63 -3
  65. package/locales/mn.json +63 -3
  66. package/locales/mr.json +64 -4
  67. package/locales/ms.json +63 -3
  68. package/locales/my.json +63 -3
  69. package/locales/ne.json +64 -4
  70. package/locales/nl.json +63 -3
  71. package/locales/no.json +62 -2
  72. package/locales/or.json +63 -3
  73. package/locales/pa.json +62 -2
  74. package/locales/pl.json +62 -2
  75. package/locales/pt-PT.json +62 -2
  76. package/locales/pt.json +63 -3
  77. package/locales/ro.json +63 -3
  78. package/locales/ru.json +63 -3
  79. package/locales/si.json +63 -3
  80. package/locales/sk.json +63 -3
  81. package/locales/sl.json +62 -2
  82. package/locales/sq.json +63 -3
  83. package/locales/sr-Latn.json +62 -2
  84. package/locales/sr.json +62 -2
  85. package/locales/sv.json +62 -2
  86. package/locales/sw.json +63 -3
  87. package/locales/ta.json +66 -6
  88. package/locales/te.json +63 -3
  89. package/locales/th.json +63 -3
  90. package/locales/tr.json +63 -3
  91. package/locales/uk.json +63 -3
  92. package/locales/ur.json +64 -4
  93. package/locales/uz.json +62 -2
  94. package/locales/vi.json +62 -2
  95. package/locales/zh-HK.json +63 -3
  96. package/locales/zh-TW.json +63 -3
  97. package/locales/zh.json +62 -2
  98. package/locales/zu.json +63 -3
  99. package/models/cpu_profile/CPUProfileDataModel.d.ts +8 -0
  100. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
  101. package/models/cpu_profile/cpu_profile-tsconfig.json +3 -3
  102. package/models/cpu_profile/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  103. package/models/trace/Processor.d.ts +1 -1
  104. package/models/trace/Processor.js +94 -74
  105. package/models/trace/Processor.js.map +1 -1
  106. package/models/trace/TracingManager.js.map +1 -1
  107. package/models/trace/bundle-tsconfig.json +1 -1
  108. package/models/trace/devtools_entrypoint-bundle-typescript-tsconfig.json +21 -3
  109. package/models/trace/extras/ScriptDuplication.d.ts +15 -16
  110. package/models/trace/extras/ScriptDuplication.js +63 -79
  111. package/models/trace/extras/ScriptDuplication.js.map +1 -1
  112. package/models/trace/extras/StackTraceForEvent.js +80 -47
  113. package/models/trace/extras/StackTraceForEvent.js.map +1 -1
  114. package/models/trace/extras/ThirdParties.d.ts +14 -20
  115. package/models/trace/extras/ThirdParties.js +97 -130
  116. package/models/trace/extras/ThirdParties.js.map +1 -1
  117. package/models/trace/extras/TraceTree.d.ts +15 -3
  118. package/models/trace/extras/TraceTree.js +36 -8
  119. package/models/trace/extras/TraceTree.js.map +1 -1
  120. package/models/trace/extras/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  121. package/models/trace/extras/extras-tsconfig.json +3 -3
  122. package/models/trace/extras/extras.d.ts +1029 -844
  123. package/models/trace/extras/extras.js +1029 -844
  124. package/models/trace/handlers/AsyncJSCallsHandler.d.ts +5 -0
  125. package/models/trace/handlers/AsyncJSCallsHandler.js +48 -13
  126. package/models/trace/handlers/AsyncJSCallsHandler.js.map +1 -1
  127. package/models/trace/handlers/InvalidationsHandler.js +1 -0
  128. package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
  129. package/models/trace/handlers/ModelHandlers.d.ts +0 -1
  130. package/models/trace/handlers/ModelHandlers.js +0 -1
  131. package/models/trace/handlers/ModelHandlers.js.map +1 -1
  132. package/models/trace/handlers/NetworkRequestsHandler.js +1 -1
  133. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  134. package/models/trace/handlers/RendererHandler.d.ts +1 -1
  135. package/models/trace/handlers/RendererHandler.js +2 -2
  136. package/models/trace/handlers/RendererHandler.js.map +1 -1
  137. package/models/trace/handlers/ScreenshotsHandler.js +4 -1
  138. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
  139. package/models/trace/handlers/ScriptsHandler.d.ts +12 -0
  140. package/models/trace/handlers/ScriptsHandler.js +99 -1
  141. package/models/trace/handlers/ScriptsHandler.js.map +1 -1
  142. package/models/trace/handlers/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  143. package/models/trace/handlers/handlers-tsconfig.json +3 -4
  144. package/models/trace/handlers/helpers.js +9 -0
  145. package/models/trace/handlers/helpers.js.map +1 -1
  146. package/models/trace/helpers/Network.d.ts +5 -0
  147. package/models/trace/helpers/Network.js +17 -0
  148. package/models/trace/helpers/Network.js.map +1 -1
  149. package/models/trace/helpers/SamplesIntegrator.js +19 -23
  150. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  151. package/models/trace/helpers/SyntheticEvents.d.ts +0 -1
  152. package/models/trace/helpers/SyntheticEvents.js +0 -4
  153. package/models/trace/helpers/SyntheticEvents.js.map +1 -1
  154. package/models/trace/helpers/Trace.d.ts +2 -1
  155. package/models/trace/helpers/Trace.js +101 -1
  156. package/models/trace/helpers/Trace.js.map +1 -1
  157. package/models/trace/helpers/TreeHelpers.d.ts +2 -5
  158. package/models/trace/helpers/TreeHelpers.js +0 -4
  159. package/models/trace/helpers/TreeHelpers.js.map +1 -1
  160. package/models/trace/helpers/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  161. package/models/trace/helpers/helpers-tsconfig.json +3 -3
  162. package/models/trace/insights/CLSCulprits.d.ts +6 -1
  163. package/models/trace/insights/CLSCulprits.js +11 -2
  164. package/models/trace/insights/CLSCulprits.js.map +1 -1
  165. package/models/trace/insights/{UseCache.d.ts → Cache.d.ts} +2 -3
  166. package/models/trace/insights/{UseCache.js → Cache.js} +12 -6
  167. package/models/trace/insights/Cache.js.map +1 -0
  168. package/models/trace/insights/Common.d.ts +21 -2
  169. package/models/trace/insights/Common.js +89 -2
  170. package/models/trace/insights/Common.js.map +1 -1
  171. package/models/trace/insights/DocumentLatency.js +3 -8
  172. package/models/trace/insights/DocumentLatency.js.map +1 -1
  173. package/models/trace/insights/DuplicatedJavaScript.d.ts +7 -4
  174. package/models/trace/insights/DuplicatedJavaScript.js +31 -5
  175. package/models/trace/insights/DuplicatedJavaScript.js.map +1 -1
  176. package/models/trace/insights/ForcedReflow.d.ts +5 -1
  177. package/models/trace/insights/ForcedReflow.js +6 -2
  178. package/models/trace/insights/ForcedReflow.js.map +1 -1
  179. package/models/trace/insights/ImageDelivery.d.ts +0 -1
  180. package/models/trace/insights/ImageDelivery.js +1 -1
  181. package/models/trace/insights/ImageDelivery.js.map +1 -1
  182. package/models/trace/insights/InteractionToNextPaint.d.ts +1 -0
  183. package/models/trace/insights/InteractionToNextPaint.js +3 -0
  184. package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
  185. package/models/trace/insights/LegacyJavaScript.d.ts +32 -0
  186. package/models/trace/insights/LegacyJavaScript.js +80 -0
  187. package/models/trace/insights/LegacyJavaScript.js.map +1 -0
  188. package/models/trace/insights/Models.d.ts +3 -1
  189. package/models/trace/insights/Models.js +3 -1
  190. package/models/trace/insights/Models.js.map +1 -1
  191. package/models/trace/insights/ModernHTTP.d.ts +51 -0
  192. package/models/trace/insights/ModernHTTP.js +187 -0
  193. package/models/trace/insights/ModernHTTP.js.map +1 -0
  194. package/models/trace/insights/NetworkDependencyTree.js +1 -1
  195. package/models/trace/insights/NetworkDependencyTree.js.map +1 -1
  196. package/models/trace/insights/ThirdParties.d.ts +1 -5
  197. package/models/trace/insights/ThirdParties.js +8 -21
  198. package/models/trace/insights/ThirdParties.js.map +1 -1
  199. package/models/trace/insights/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  200. package/models/trace/insights/insights-tsconfig.json +9 -4
  201. package/models/trace/insights/types.d.ts +10 -0
  202. package/models/trace/insights/types.js.map +1 -1
  203. package/models/trace/lantern/core/core-tsconfig.json +3 -3
  204. package/models/trace/lantern/core/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  205. package/models/trace/lantern/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  206. package/models/trace/lantern/graph/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  207. package/models/trace/lantern/graph/graph-tsconfig.json +3 -3
  208. package/models/trace/lantern/lantern-tsconfig.json +3 -3
  209. package/models/trace/lantern/metrics/Metric.d.ts +4 -4
  210. package/models/trace/lantern/metrics/Metric.js +4 -6
  211. package/models/trace/lantern/metrics/Metric.js.map +1 -1
  212. package/models/trace/lantern/metrics/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  213. package/models/trace/lantern/metrics/metrics-tsconfig.json +3 -3
  214. package/models/trace/lantern/simulation/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  215. package/models/trace/lantern/simulation/simulation-tsconfig.json +3 -3
  216. package/models/trace/lantern/types/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  217. package/models/trace/lantern/types/types-tsconfig.json +3 -3
  218. package/models/trace/trace-tsconfig.json +3 -3
  219. package/models/trace/types/Configuration.d.ts +2 -0
  220. package/models/trace/types/Configuration.js.map +1 -1
  221. package/models/trace/types/TraceEvents.d.ts +30 -54
  222. package/models/trace/types/TraceEvents.js +8 -23
  223. package/models/trace/types/TraceEvents.js.map +1 -1
  224. package/models/trace/types/devtools_entrypoint-bundle-typescript-tsconfig.json +3 -3
  225. package/models/trace/types/types-tsconfig.json +3 -3
  226. package/package.json +3 -2
  227. package/test/test-trace-engine.mjs +19 -17
  228. package/third_party/legacy-javascript/legacy-javascript.d.ts +1 -0
  229. package/third_party/legacy-javascript/legacy-javascript.js +1 -0
  230. package/core/platform/ServerTiming.d.ts +0 -31
  231. package/core/platform/ServerTiming.js +0 -212
  232. package/core/platform/ServerTiming.js.map +0 -1
  233. package/models/trace/handlers/ServerTimingsHandler.d.ts +0 -9
  234. package/models/trace/handlers/ServerTimingsHandler.js +0 -106
  235. package/models/trace/handlers/ServerTimingsHandler.js.map +0 -1
  236. package/models/trace/insights/UseCache.js.map +0 -1
@@ -1,153 +1,120 @@
1
1
  // Copyright 2024 The Chromium Authors. All rights reserved.
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- import * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';
5
4
  import * as Handlers from '../handlers/handlers.js';
6
5
  import * as Helpers from '../helpers/helpers.js';
7
6
  import * as Types from '../types/types.js';
8
- function getOrMakeSummaryByEntity(thirdPartySummary, event, url) {
9
- const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ??
10
- Handlers.Helpers.makeUpEntity(thirdPartySummary.madeUpEntityCache, url);
11
- if (!entity) {
12
- return null;
13
- }
14
- const urls = thirdPartySummary.urlsByEntity.get(entity) ?? new Set();
15
- urls.add(url);
16
- thirdPartySummary.urlsByEntity.set(entity, urls);
17
- const events = thirdPartySummary.eventsByEntity.get(entity) ?? [];
18
- events.push(event);
19
- thirdPartySummary.eventsByEntity.set(entity, events);
20
- let summary = thirdPartySummary.byEntity.get(entity);
21
- if (summary) {
22
- return summary;
23
- }
24
- summary = { transferSize: 0, mainThreadTime: Types.Timing.Micro(0) };
25
- thirdPartySummary.byEntity.set(entity, summary);
26
- return summary;
27
- }
28
- function getOrMakeSummaryByURL(thirdPartySummary, url) {
29
- let summary = thirdPartySummary.byUrl.get(url);
30
- if (summary) {
31
- return summary;
32
- }
33
- summary = { transferSize: 0, mainThreadTime: Types.Timing.Micro(0) };
34
- thirdPartySummary.byUrl.set(url, summary);
35
- return summary;
36
- }
37
- // TODO: Remove and use the the BottomUpRootNode defined in ThirdPartyTreeView instead.
38
- function collectMainThreadActivity(thirdPartySummary, parsedTrace, bounds) {
39
- for (const process of parsedTrace.Renderer.processes.values()) {
40
- if (!process.isOnMainFrame) {
41
- continue;
42
- }
43
- for (const thread of process.threads.values()) {
44
- if (thread.name === 'CrRendererMain') {
45
- if (!thread.tree) {
46
- break;
47
- }
48
- for (const event of thread.entries) {
49
- if (!Helpers.Timing.eventIsInBounds(event, bounds)) {
50
- continue;
51
- }
52
- const node = parsedTrace.Renderer.entryToNode.get(event);
53
- if (!node || !node.selfTime) {
54
- continue;
55
- }
56
- const url = Handlers.Helpers.getNonResolvedURL(event, parsedTrace);
57
- if (!url) {
58
- continue;
59
- }
60
- let summary = getOrMakeSummaryByEntity(thirdPartySummary, event, url);
61
- if (summary) {
62
- summary.mainThreadTime = (summary.mainThreadTime + node.selfTime);
63
- }
64
- summary = getOrMakeSummaryByURL(thirdPartySummary, url);
65
- if (summary) {
66
- summary.mainThreadTime = (summary.mainThreadTime + node.selfTime);
67
- }
68
- }
69
- }
70
- }
7
+ import * as TraceFilter from './TraceFilter.js';
8
+ import * as TraceTree from './TraceTree.js';
9
+ /**
10
+ *
11
+ * Returns Main frame main thread events.
12
+ * These events are inline with the ones used by selectedEvents() of TimelineTreeViews
13
+ */
14
+ function collectMainThreadActivity(parsedTrace) {
15
+ // TODO: Note b/402658800 could be an issue here.
16
+ const mainFrameMainThread = parsedTrace.Renderer.processes.values()
17
+ .find(p => {
18
+ const url = p.url ?? '';
19
+ // Frame url checked a la CompatibilityTracksAppenders's addThreadAppenders
20
+ return p.isOnMainFrame && !url.startsWith('about:') && !url.startsWith('chrome:');
21
+ })
22
+ ?.threads.values()
23
+ .find(t => t.name === 'CrRendererMain');
24
+ if (!mainFrameMainThread) {
25
+ return [];
71
26
  }
27
+ return mainFrameMainThread.entries;
72
28
  }
73
- function collectNetworkActivity(thirdPartySummary, requests) {
74
- for (const request of requests) {
75
- const url = request.args.data.url;
76
- let summary = getOrMakeSummaryByEntity(thirdPartySummary, request, url);
77
- if (summary) {
78
- summary.transferSize += request.args.data.encodedDataLength;
79
- }
80
- summary = getOrMakeSummaryByURL(thirdPartySummary, url);
81
- if (summary) {
82
- summary.transferSize += request.args.data.encodedDataLength;
83
- }
84
- }
29
+ export function summarizeByThirdParty(parsedTrace, traceBounds) {
30
+ const mainThreadEvents = collectMainThreadActivity(parsedTrace).sort(Helpers.Trace.eventTimeComparator);
31
+ const groupingFunction = (event) => {
32
+ const entity = parsedTrace.Renderer.entityMappings.entityByEvent.get(event);
33
+ return entity?.name ?? '';
34
+ };
35
+ const node = getBottomUpTree(mainThreadEvents, traceBounds, groupingFunction);
36
+ const summaries = summarizeBottomUpByEntity(node, parsedTrace);
37
+ return summaries;
85
38
  }
86
39
  /**
87
- * @param networkRequests Won't be filtered by trace bounds, so callers should ensure it is filtered.
40
+ * Used only by Lighthouse.
88
41
  */
89
- export function summarizeThirdParties(parsedTrace, traceBounds, networkRequests) {
90
- const thirdPartySummary = {
91
- byEntity: new Map(),
92
- byUrl: new Map(),
93
- urlsByEntity: new Map(),
94
- eventsByEntity: new Map(),
95
- madeUpEntityCache: new Map(),
42
+ export function summarizeByURL(parsedTrace, traceBounds) {
43
+ const mainThreadEvents = collectMainThreadActivity(parsedTrace).sort(Helpers.Trace.eventTimeComparator);
44
+ const groupingFunction = (event) => {
45
+ return Handlers.Helpers.getNonResolvedURL(event, parsedTrace) ?? '';
96
46
  };
97
- collectMainThreadActivity(thirdPartySummary, parsedTrace, traceBounds);
98
- collectNetworkActivity(thirdPartySummary, networkRequests);
99
- return thirdPartySummary;
47
+ const node = getBottomUpTree(mainThreadEvents, traceBounds, groupingFunction);
48
+ const summaries = summarizeBottomUpByURL(node, parsedTrace);
49
+ return summaries;
100
50
  }
101
- function getSummaryMapWithMapping(events, entityByEvent, eventsByEntity) {
102
- const byEvent = new Map();
103
- const byEntity = new Map();
104
- const defaultSummary = { transferSize: 0, mainThreadTime: Types.Timing.Micro(0) };
105
- for (const event of events) {
106
- const urlSummary = byEvent.get(event) || { ...defaultSummary };
107
- if (Types.Events.isSyntheticNetworkRequest(event)) {
108
- urlSummary.transferSize += event.args.data.encodedDataLength;
51
+ function summarizeBottomUpByEntity(root, parsedTrace) {
52
+ const summaries = [];
53
+ // Top nodes are the 3P entities.
54
+ const topNodes = [...root.children().values()].flat();
55
+ for (const node of topNodes) {
56
+ if (node.id === '') {
57
+ continue;
58
+ }
59
+ const entity = parsedTrace.Renderer.entityMappings.entityByEvent.get(node.event);
60
+ if (!entity) {
61
+ continue;
109
62
  }
110
- byEvent.set(event, urlSummary);
63
+ // Lets use the mapper events as our source of events, since we use the main thread to construct
64
+ // the bottom up tree. The mapper will give us all related events.
65
+ const summary = {
66
+ transferSize: node.transferSize,
67
+ mainThreadTime: Types.Timing.Milli(node.selfTime),
68
+ entity,
69
+ relatedEvents: parsedTrace.Renderer.entityMappings.eventsByEntity.get(entity) ?? [],
70
+ };
71
+ summaries.push(summary);
111
72
  }
112
- // Map each request's stat to a particular entity.
113
- for (const [request, requestSummary] of byEvent.entries()) {
114
- const entity = entityByEvent.get(request);
73
+ return summaries;
74
+ }
75
+ function summarizeBottomUpByURL(root, parsedTrace) {
76
+ const summaries = [];
77
+ const allRequests = parsedTrace.NetworkRequests.byTime;
78
+ // Top nodes are URLs.
79
+ const topNodes = [...root.children().values()].flat();
80
+ for (const node of topNodes) {
81
+ if (node.id === '' || typeof node.id !== 'string') {
82
+ continue;
83
+ }
84
+ const entity = parsedTrace.Renderer.entityMappings.entityByEvent.get(node.event);
115
85
  if (!entity) {
116
- byEvent.delete(request);
117
86
  continue;
118
87
  }
119
- const entitySummary = byEntity.get(entity) || { ...defaultSummary };
120
- entitySummary.transferSize += requestSummary.transferSize;
121
- byEntity.set(entity, entitySummary);
88
+ const url = node.id;
89
+ const request = allRequests.find(r => r.args.data.url === url);
90
+ const summary = {
91
+ request,
92
+ url,
93
+ entity,
94
+ transferSize: node.transferSize,
95
+ mainThreadTime: Types.Timing.Milli(node.selfTime),
96
+ };
97
+ summaries.push(summary);
122
98
  }
123
- return { byEntity, eventsByEntity, madeUpEntityCache: new Map(), byUrl: new Map(), urlsByEntity: new Map() };
99
+ return summaries;
124
100
  }
125
- // TODO(crbug.com/352244718): Remove or refactor to use summarizeThirdParties/collectMainThreadActivity/etc.
126
- /**
127
- * Note: unlike summarizeThirdParties, this does not calculate mainThreadTime. The reason is that it is not
128
- * needed for its one use case, and when dragging the trace bounds it takes a long time to calculate.
129
- * If it is ever needed, we need to make getSelfTimeByUrl (see deleted code/blame) much faster (cache + bucket?).
130
- */
131
- export function getSummariesAndEntitiesWithMapping(parsedTrace, traceBounds, entityMapping) {
132
- const entityByEvent = new Map(entityMapping.entityByEvent);
133
- const eventsByEntity = new Map(entityMapping.eventsByEntity);
134
- // Consider events only in bounds.
135
- const entityByEventArr = Array.from(entityByEvent.entries());
136
- const filteredEntries = entityByEventArr.filter(([event]) => {
137
- return Helpers.Timing.eventIsInBounds(event, traceBounds);
138
- });
139
- const entityByEventFiltered = new Map(filteredEntries);
140
- // Consider events only in bounds.
141
- const eventsByEntityArr = Array.from(eventsByEntity.entries());
142
- const filtered = eventsByEntityArr.filter(([, events]) => {
143
- events.map(event => {
144
- return Helpers.Timing.eventIsInBounds(event, traceBounds);
145
- });
146
- return events.length > 0;
101
+ function getBottomUpTree(mainThreadEvents, tracebounds, groupingFunction) {
102
+ // Use the same filtering as front_end/panels/timeline/TimelineTreeView.ts.
103
+ const visibleEvents = Helpers.Trace.VISIBLE_TRACE_EVENT_TYPES.values().toArray();
104
+ const filter = new TraceFilter.VisibleEventsFilter(visibleEvents.concat(["SyntheticNetworkRequest" /* Types.Events.Name.SYNTHETIC_NETWORK_REQUEST */]));
105
+ // The bottom up root node handles all the "in Tracebounds" checks we need for the insight.
106
+ const startTime = Helpers.Timing.microToMilli(tracebounds.min);
107
+ const endTime = Helpers.Timing.microToMilli(tracebounds.max);
108
+ const node = new TraceTree.BottomUpRootNode(mainThreadEvents, {
109
+ textFilter: new TraceFilter.ExclusiveNameFilter([]),
110
+ filters: [filter],
111
+ startTime,
112
+ endTime,
113
+ eventGroupIdCallback: groupingFunction,
114
+ calculateTransferSize: true,
115
+ // Ensure we group by 3P alongside eventID for correct 3P grouping.
116
+ forceGroupIdCallback: true,
147
117
  });
148
- const eventsByEntityFiltered = new Map(filtered);
149
- const allEvents = Array.from(entityByEvent.keys());
150
- const summaries = getSummaryMapWithMapping(allEvents, entityByEventFiltered, eventsByEntityFiltered);
151
- return { summaries, entityByEvent: entityByEventFiltered };
118
+ return node;
152
119
  }
153
120
  //# sourceMappingURL=ThirdParties.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThirdParties.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/ThirdParties.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';\nimport * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nexport type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number];\n\nexport interface Summary {\n transferSize: number;\n mainThreadTime: Types.Timing.Micro;\n}\n\nexport interface ThirdPartySummary {\n byEntity: Map<Entity, Summary>;\n byUrl: Map<string, Summary>;\n urlsByEntity: Map<Entity, Set<string>>;\n eventsByEntity: Map<Entity, Types.Events.Event[]>;\n madeUpEntityCache: Map<string, Entity>;\n}\n\nfunction getOrMakeSummaryByEntity(\n thirdPartySummary: ThirdPartySummary, event: Types.Events.Event, url: string): Summary|null {\n const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ??\n Handlers.Helpers.makeUpEntity(thirdPartySummary.madeUpEntityCache, url);\n if (!entity) {\n return null;\n }\n\n const urls = thirdPartySummary.urlsByEntity.get(entity) ?? new Set();\n urls.add(url);\n thirdPartySummary.urlsByEntity.set(entity, urls);\n\n const events = thirdPartySummary.eventsByEntity.get(entity) ?? [];\n events.push(event);\n thirdPartySummary.eventsByEntity.set(entity, events);\n\n let summary = thirdPartySummary.byEntity.get(entity);\n if (summary) {\n return summary;\n }\n\n summary = {transferSize: 0, mainThreadTime: Types.Timing.Micro(0)};\n thirdPartySummary.byEntity.set(entity, summary);\n return summary;\n}\n\nfunction getOrMakeSummaryByURL(thirdPartySummary: ThirdPartySummary, url: string): Summary|null {\n let summary = thirdPartySummary.byUrl.get(url);\n if (summary) {\n return summary;\n }\n\n summary = {transferSize: 0, mainThreadTime: Types.Timing.Micro(0)};\n thirdPartySummary.byUrl.set(url, summary);\n return summary;\n}\n\n// TODO: Remove and use the the BottomUpRootNode defined in ThirdPartyTreeView instead.\nfunction collectMainThreadActivity(\n thirdPartySummary: ThirdPartySummary, parsedTrace: Handlers.Types.ParsedTrace,\n bounds: Types.Timing.TraceWindowMicro): void {\n for (const process of parsedTrace.Renderer.processes.values()) {\n if (!process.isOnMainFrame) {\n continue;\n }\n\n for (const thread of process.threads.values()) {\n if (thread.name === 'CrRendererMain') {\n if (!thread.tree) {\n break;\n }\n\n for (const event of thread.entries) {\n if (!Helpers.Timing.eventIsInBounds(event, bounds)) {\n continue;\n }\n\n const node = parsedTrace.Renderer.entryToNode.get(event);\n if (!node || !node.selfTime) {\n continue;\n }\n\n const url = Handlers.Helpers.getNonResolvedURL(event, parsedTrace);\n if (!url) {\n continue;\n }\n\n let summary = getOrMakeSummaryByEntity(thirdPartySummary, event, url);\n if (summary) {\n summary.mainThreadTime = (summary.mainThreadTime + node.selfTime) as Types.Timing.Micro;\n }\n\n summary = getOrMakeSummaryByURL(thirdPartySummary, url);\n if (summary) {\n summary.mainThreadTime = (summary.mainThreadTime + node.selfTime) as Types.Timing.Micro;\n }\n }\n }\n }\n }\n}\n\nfunction collectNetworkActivity(\n thirdPartySummary: ThirdPartySummary, requests: Types.Events.SyntheticNetworkRequest[]): void {\n for (const request of requests) {\n const url = request.args.data.url;\n\n let summary = getOrMakeSummaryByEntity(thirdPartySummary, request, url);\n if (summary) {\n summary.transferSize += request.args.data.encodedDataLength;\n }\n\n summary = getOrMakeSummaryByURL(thirdPartySummary, url);\n if (summary) {\n summary.transferSize += request.args.data.encodedDataLength;\n }\n }\n}\n\n/**\n * @param networkRequests Won't be filtered by trace bounds, so callers should ensure it is filtered.\n */\nexport function summarizeThirdParties(\n parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicro,\n networkRequests: Types.Events.SyntheticNetworkRequest[]): ThirdPartySummary {\n const thirdPartySummary: ThirdPartySummary = {\n byEntity: new Map(),\n byUrl: new Map(),\n urlsByEntity: new Map(),\n eventsByEntity: new Map(),\n madeUpEntityCache: new Map(),\n };\n\n collectMainThreadActivity(thirdPartySummary, parsedTrace, traceBounds);\n collectNetworkActivity(thirdPartySummary, networkRequests);\n\n return thirdPartySummary;\n}\n\nfunction getSummaryMapWithMapping(\n events: Types.Events.Event[], entityByEvent: Map<Types.Events.Event, Handlers.Helpers.Entity>,\n eventsByEntity: Map<Handlers.Helpers.Entity, Types.Events.Event[]>): ThirdPartySummary {\n const byEvent = new Map<Types.Events.Event, Summary>();\n const byEntity = new Map<Handlers.Helpers.Entity, Summary>();\n const defaultSummary: Summary = {transferSize: 0, mainThreadTime: Types.Timing.Micro(0)};\n\n for (const event of events) {\n const urlSummary = byEvent.get(event) || {...defaultSummary};\n if (Types.Events.isSyntheticNetworkRequest(event)) {\n urlSummary.transferSize += event.args.data.encodedDataLength;\n }\n byEvent.set(event, urlSummary);\n }\n\n // Map each request's stat to a particular entity.\n for (const [request, requestSummary] of byEvent.entries()) {\n const entity = entityByEvent.get(request);\n if (!entity) {\n byEvent.delete(request);\n continue;\n }\n\n const entitySummary = byEntity.get(entity) || {...defaultSummary};\n entitySummary.transferSize += requestSummary.transferSize;\n byEntity.set(entity, entitySummary);\n }\n\n return {byEntity, eventsByEntity, madeUpEntityCache: new Map(), byUrl: new Map(), urlsByEntity: new Map()};\n}\n\n// TODO(crbug.com/352244718): Remove or refactor to use summarizeThirdParties/collectMainThreadActivity/etc.\n/**\n * Note: unlike summarizeThirdParties, this does not calculate mainThreadTime. The reason is that it is not\n * needed for its one use case, and when dragging the trace bounds it takes a long time to calculate.\n * If it is ever needed, we need to make getSelfTimeByUrl (see deleted code/blame) much faster (cache + bucket?).\n */\nexport function getSummariesAndEntitiesWithMapping(\n parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicro,\n entityMapping: Handlers.Helpers.EntityMappings): {\n summaries: ThirdPartySummary,\n entityByEvent: Map<Types.Events.Event, Handlers.Helpers.Entity>,\n} {\n const entityByEvent = new Map(entityMapping.entityByEvent);\n const eventsByEntity = new Map(entityMapping.eventsByEntity);\n\n // Consider events only in bounds.\n const entityByEventArr = Array.from(entityByEvent.entries());\n const filteredEntries = entityByEventArr.filter(([event]) => {\n return Helpers.Timing.eventIsInBounds(event, traceBounds);\n });\n const entityByEventFiltered = new Map(filteredEntries);\n\n // Consider events only in bounds.\n const eventsByEntityArr = Array.from(eventsByEntity.entries());\n const filtered = eventsByEntityArr.filter(([, events]) => {\n events.map(event => {\n return Helpers.Timing.eventIsInBounds(event, traceBounds);\n });\n return events.length > 0;\n });\n const eventsByEntityFiltered = new Map(filtered);\n\n const allEvents = Array.from(entityByEvent.keys());\n const summaries = getSummaryMapWithMapping(allEvents, entityByEventFiltered, eventsByEntityFiltered);\n\n return {summaries, entityByEvent: entityByEventFiltered};\n}\n"]}
1
+ {"version":3,"file":"ThirdParties.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/ThirdParties.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';\nimport * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport * as TraceFilter from './TraceFilter.js';\nimport * as TraceTree from './TraceTree.js';\n\nexport type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number];\n\ninterface BaseSummary {\n entity: Entity;\n transferSize: number;\n mainThreadTime: Types.Timing.Milli;\n}\n\nexport interface EntitySummary extends BaseSummary {\n relatedEvents: Types.Events.Event[];\n}\n\nexport interface URLSummary extends BaseSummary {\n url: string;\n request?: Types.Events.SyntheticNetworkRequest;\n}\n\n/**\n *\n * Returns Main frame main thread events.\n * These events are inline with the ones used by selectedEvents() of TimelineTreeViews\n */\nfunction collectMainThreadActivity(parsedTrace: Handlers.Types.ParsedTrace): Types.Events.Event[] {\n // TODO: Note b/402658800 could be an issue here.\n const mainFrameMainThread = parsedTrace.Renderer.processes.values()\n .find(p => {\n const url = p.url ?? '';\n // Frame url checked a la CompatibilityTracksAppenders's addThreadAppenders\n return p.isOnMainFrame && !url.startsWith('about:') && !url.startsWith('chrome:');\n })\n ?.threads.values()\n .find(t => t.name === 'CrRendererMain');\n\n if (!mainFrameMainThread) {\n return [];\n }\n\n return mainFrameMainThread.entries;\n}\n\nexport function summarizeByThirdParty(\n parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicro): EntitySummary[] {\n const mainThreadEvents = collectMainThreadActivity(parsedTrace).sort(Helpers.Trace.eventTimeComparator);\n const groupingFunction = (event: Types.Events.Event): string => {\n const entity = parsedTrace.Renderer.entityMappings.entityByEvent.get(event);\n return entity?.name ?? '';\n };\n const node = getBottomUpTree(mainThreadEvents, traceBounds, groupingFunction);\n const summaries = summarizeBottomUpByEntity(node, parsedTrace);\n\n return summaries;\n}\n\n/**\n * Used only by Lighthouse.\n */\nexport function summarizeByURL(\n parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicro): URLSummary[] {\n const mainThreadEvents = collectMainThreadActivity(parsedTrace).sort(Helpers.Trace.eventTimeComparator);\n const groupingFunction = (event: Types.Events.Event): string => {\n return Handlers.Helpers.getNonResolvedURL(event, parsedTrace) ?? '';\n };\n const node = getBottomUpTree(mainThreadEvents, traceBounds, groupingFunction);\n const summaries = summarizeBottomUpByURL(node, parsedTrace);\n\n return summaries;\n}\n\nfunction summarizeBottomUpByEntity(\n root: TraceTree.BottomUpRootNode, parsedTrace: Handlers.Types.ParsedTrace): EntitySummary[] {\n const summaries: EntitySummary[] = [];\n\n // Top nodes are the 3P entities.\n const topNodes = [...root.children().values()].flat();\n for (const node of topNodes) {\n if (node.id === '') {\n continue;\n }\n\n const entity = parsedTrace.Renderer.entityMappings.entityByEvent.get(node.event);\n if (!entity) {\n continue;\n }\n\n // Lets use the mapper events as our source of events, since we use the main thread to construct\n // the bottom up tree. The mapper will give us all related events.\n const summary: EntitySummary = {\n transferSize: node.transferSize,\n mainThreadTime: Types.Timing.Milli(node.selfTime),\n entity,\n relatedEvents: parsedTrace.Renderer.entityMappings.eventsByEntity.get(entity) ?? [],\n };\n summaries.push(summary);\n }\n\n return summaries;\n}\n\nfunction summarizeBottomUpByURL(\n root: TraceTree.BottomUpRootNode, parsedTrace: Handlers.Types.ParsedTrace): URLSummary[] {\n const summaries: URLSummary[] = [];\n const allRequests = parsedTrace.NetworkRequests.byTime;\n\n // Top nodes are URLs.\n const topNodes = [...root.children().values()].flat();\n for (const node of topNodes) {\n if (node.id === '' || typeof node.id !== 'string') {\n continue;\n }\n\n const entity = parsedTrace.Renderer.entityMappings.entityByEvent.get(node.event);\n if (!entity) {\n continue;\n }\n\n const url = node.id;\n const request = allRequests.find(r => r.args.data.url === url);\n\n const summary: URLSummary = {\n request,\n url,\n entity,\n transferSize: node.transferSize,\n mainThreadTime: Types.Timing.Milli(node.selfTime),\n };\n summaries.push(summary);\n }\n\n return summaries;\n}\n\nfunction getBottomUpTree(\n mainThreadEvents: Types.Events.Event[], tracebounds: Types.Timing.TraceWindowMicro,\n groupingFunction: ((arg0: Types.Events.Event) => string)|null): TraceTree.BottomUpRootNode {\n // Use the same filtering as front_end/panels/timeline/TimelineTreeView.ts.\n const visibleEvents = Helpers.Trace.VISIBLE_TRACE_EVENT_TYPES.values().toArray();\n const filter =\n new TraceFilter.VisibleEventsFilter(visibleEvents.concat([Types.Events.Name.SYNTHETIC_NETWORK_REQUEST]));\n\n // The bottom up root node handles all the \"in Tracebounds\" checks we need for the insight.\n const startTime = Helpers.Timing.microToMilli(tracebounds.min);\n const endTime = Helpers.Timing.microToMilli(tracebounds.max);\n const node = new TraceTree.BottomUpRootNode(mainThreadEvents, {\n textFilter: new TraceFilter.ExclusiveNameFilter([]),\n filters: [filter],\n startTime,\n endTime,\n eventGroupIdCallback: groupingFunction,\n calculateTransferSize: true,\n // Ensure we group by 3P alongside eventID for correct 3P grouping.\n forceGroupIdCallback: true,\n }) as TraceTree.BottomUpRootNode;\n return node;\n}\n"]}
@@ -67,21 +67,33 @@ export declare class BottomUpRootNode extends Node {
67
67
  readonly filter: (e: Types.Events.Event) => boolean;
68
68
  readonly startTime: Types.Timing.Milli;
69
69
  readonly endTime: Types.Timing.Milli;
70
- private eventGroupIdCallback;
71
70
  totalTime: number;
71
+ eventGroupIdCallback: ((arg0: Types.Events.Event) => string) | null | undefined;
72
72
  private calculateTransferSize?;
73
- constructor(events: Types.Events.Event[], { textFilter, filters, startTime, endTime, eventGroupIdCallback, calculateTransferSize, }: {
73
+ private forceGroupIdCallback?;
74
+ constructor(events: Types.Events.Event[], { textFilter, filters, startTime, endTime, eventGroupIdCallback, calculateTransferSize, forceGroupIdCallback, }: {
74
75
  textFilter: TraceFilter;
75
76
  filters: readonly TraceFilter[];
76
77
  startTime: Types.Timing.Milli;
77
78
  endTime: Types.Timing.Milli;
78
79
  eventGroupIdCallback?: ((arg0: Types.Events.Event) => string) | null;
79
80
  calculateTransferSize?: boolean;
81
+ /**
82
+ * This forces using `eventGroupIdCallback` in combination with generateEventID
83
+ * to generate the ID of the node.
84
+ *
85
+ * This is used in the ThirdPartyTreeView and BottomUpTreeView, where we want to group all events
86
+ * related to a specific 3P entity together, regardless of the specific event name/type.
87
+ * There are cases where events under the same event name belong to different entities. But, because
88
+ * they get grouped first by event name/type, it throws off the 3P groupBy - grouping events of different
89
+ * 3P entities together.
90
+ */
91
+ forceGroupIdCallback?: boolean;
80
92
  });
81
93
  hasChildren(): boolean;
82
94
  filterChildren(children: ChildrenCache): ChildrenCache;
83
95
  children(): ChildrenCache;
84
- private ungrouppedTopNodes;
96
+ private ungroupedTopNodes;
85
97
  private grouppedTopNodes;
86
98
  }
87
99
  export declare class GroupNode extends Node {
@@ -283,10 +283,11 @@ export class BottomUpRootNode extends Node {
283
283
  filter;
284
284
  startTime;
285
285
  endTime;
286
- eventGroupIdCallback;
287
286
  totalTime;
287
+ eventGroupIdCallback;
288
288
  calculateTransferSize;
289
- constructor(events, { textFilter, filters, startTime, endTime, eventGroupIdCallback, calculateTransferSize, }) {
289
+ forceGroupIdCallback;
290
+ constructor(events, { textFilter, filters, startTime, endTime, eventGroupIdCallback, calculateTransferSize, forceGroupIdCallback, }) {
290
291
  super('', events[0]);
291
292
  this.childrenInternal = null;
292
293
  this.events = events;
@@ -297,6 +298,7 @@ export class BottomUpRootNode extends Node {
297
298
  this.eventGroupIdCallback = eventGroupIdCallback;
298
299
  this.totalTime = endTime - startTime;
299
300
  this.calculateTransferSize = calculateTransferSize;
301
+ this.forceGroupIdCallback = forceGroupIdCallback;
300
302
  }
301
303
  hasChildren() {
302
304
  return true;
@@ -320,7 +322,7 @@ export class BottomUpRootNode extends Node {
320
322
  // If no grouping is applied, the nodes returned here are what's initially shown in the bottom-up view.
321
323
  // "No grouping" == no grouping in UI dropdown == no groupingFunction…
322
324
  // … HOWEVER, nodes are still aggregated via `generateEventID`, which is ~= the event name.
323
- ungrouppedTopNodes() {
325
+ ungroupedTopNodes() {
324
326
  const root = this;
325
327
  const startTime = this.startTime;
326
328
  const endTime = this.endTime;
@@ -328,10 +330,16 @@ export class BottomUpRootNode extends Node {
328
330
  const selfTimeStack = [endTime - startTime];
329
331
  const firstNodeStack = [];
330
332
  const totalTimeById = new Map();
333
+ // TODO(paulirish): rename to getGroupNodeId
334
+ const eventGroupIdCallback = this.eventGroupIdCallback;
335
+ const forceGroupIdCallback = this.forceGroupIdCallback;
331
336
  // encodedDataLength is provided solely on instant events.
332
337
  const sumTransferSizeOfInstantEvent = (e) => {
333
338
  if (Types.Events.isReceivedDataEvent(e)) {
334
- const id = generateEventID(e);
339
+ let id = generateEventID(e);
340
+ if (this.forceGroupIdCallback && this.eventGroupIdCallback) {
341
+ id = `${id}-${this.eventGroupIdCallback(e)}`;
342
+ }
335
343
  let node = nodeById.get(id);
336
344
  if (!node) {
337
345
  node = new BottomUpNode(root, id, e, false, root);
@@ -340,7 +348,20 @@ export class BottomUpRootNode extends Node {
340
348
  else {
341
349
  node.events.push(e);
342
350
  }
343
- node.transferSize += e.args.data.encodedDataLength;
351
+ // ResourceReceivedData events tally up the transfer size over time, but the
352
+ // ResourceReceiveResponse / ResourceFinish events hold the final result.
353
+ if (e.name === 'ResourceReceivedData') {
354
+ node.transferSize += e.args.data.encodedDataLength;
355
+ }
356
+ else if (e.args.data.encodedDataLength > 0) {
357
+ // For some reason, ResourceFinish can be zero even if data was sent.
358
+ // Ignore that case.
359
+ // Note: this will count the entire resource size if just the last bit of a
360
+ // request is in view. If it isn't in view, the transfer size is counted
361
+ // gradually, in proportion with the ResourceReceivedData events in the
362
+ // current view.
363
+ node.transferSize = e.args.data.encodedDataLength;
364
+ }
344
365
  }
345
366
  };
346
367
  Helpers.Trace.forEachEvent(this.events, {
@@ -358,7 +379,10 @@ export class BottomUpRootNode extends Node {
358
379
  const duration = actualEndTime - Math.max(currentStartTime, startTime);
359
380
  selfTimeStack[selfTimeStack.length - 1] -= duration;
360
381
  selfTimeStack.push(duration);
361
- const id = generateEventID(e);
382
+ let id = generateEventID(e);
383
+ if (forceGroupIdCallback && eventGroupIdCallback) {
384
+ id = `${id}-${eventGroupIdCallback(e)}`;
385
+ }
362
386
  const noNodeOnStack = !totalTimeById.has(id);
363
387
  if (noNodeOnStack) {
364
388
  totalTimeById.set(id, duration);
@@ -366,7 +390,10 @@ export class BottomUpRootNode extends Node {
366
390
  firstNodeStack.push(noNodeOnStack);
367
391
  }
368
392
  function onEndEvent(event) {
369
- const id = generateEventID(event);
393
+ let id = generateEventID(event);
394
+ if (forceGroupIdCallback && eventGroupIdCallback) {
395
+ id = `${id}-${eventGroupIdCallback(event)}`;
396
+ }
370
397
  let node = nodeById.get(id);
371
398
  if (!node) {
372
399
  node = new BottomUpNode(root, id, event, false, root);
@@ -394,7 +421,7 @@ export class BottomUpRootNode extends Node {
394
421
  return nodeById;
395
422
  }
396
423
  grouppedTopNodes() {
397
- const flatNodes = this.ungrouppedTopNodes();
424
+ const flatNodes = this.ungroupedTopNodes();
398
425
  if (!this.eventGroupIdCallback) {
399
426
  return flatNodes;
400
427
  }
@@ -544,6 +571,7 @@ export function eventStackFrame(event) {
544
571
  }
545
572
  return { ...topFrame, scriptId: String(topFrame.scriptId) };
546
573
  }
574
+ // TODO(paulirish): rename to generateNodeId
547
575
  export function generateEventID(event) {
548
576
  if (Types.Events.isProfileCall(event)) {
549
577
  const name = SamplesIntegrator.isNativeRuntimeFrame(event.callFrame) ?