@paulirish/trace_engine 0.0.41 → 0.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  2. package/generated/protocol.d.ts +79 -3
  3. package/locales/en-US.json +210 -0
  4. package/locales/en-XL.json +210 -0
  5. package/models/cpu_profile/CPUProfileDataModel.d.ts +7 -0
  6. package/models/cpu_profile/CPUProfileDataModel.js +9 -2
  7. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
  8. package/models/cpu_profile/ProfileTreeModel.d.ts +1 -1
  9. package/models/cpu_profile/ProfileTreeModel.js.map +1 -1
  10. package/models/trace/LanternComputationData.d.ts +1 -1
  11. package/models/trace/LanternComputationData.js +8 -6
  12. package/models/trace/LanternComputationData.js.map +1 -1
  13. package/models/trace/Processor.d.ts +2 -16
  14. package/models/trace/Processor.js +6 -4
  15. package/models/trace/Processor.js.map +1 -1
  16. package/models/trace/extras/FilmStrip.d.ts +5 -5
  17. package/models/trace/extras/FilmStrip.js +2 -1
  18. package/models/trace/extras/FilmStrip.js.map +1 -1
  19. package/models/trace/extras/MainThreadActivity.d.ts +1 -1
  20. package/models/trace/extras/MainThreadActivity.js +3 -3
  21. package/models/trace/extras/MainThreadActivity.js.map +1 -1
  22. package/models/trace/extras/ThirdParties.d.ts +14 -13
  23. package/models/trace/extras/ThirdParties.js +51 -61
  24. package/models/trace/extras/ThirdParties.js.map +1 -1
  25. package/models/trace/extras/TimelineJSProfile.d.ts +1 -1
  26. package/models/trace/extras/TimelineJSProfile.js +9 -4
  27. package/models/trace/extras/TimelineJSProfile.js.map +1 -1
  28. package/models/trace/extras/TraceTree.d.ts +19 -6
  29. package/models/trace/extras/TraceTree.js +6 -3
  30. package/models/trace/extras/TraceTree.js.map +1 -1
  31. package/models/trace/extras/extras.d.ts +0 -1
  32. package/models/trace/extras/extras.js +0 -1
  33. package/models/trace/handlers/AnimationFramesHandler.js +1 -1
  34. package/models/trace/handlers/AnimationFramesHandler.js.map +1 -1
  35. package/models/trace/handlers/ExtensionTraceDataHandler.js +8 -2
  36. package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
  37. package/models/trace/handlers/FlowsHandler.js.map +1 -1
  38. package/models/trace/handlers/FramesHandler.d.ts +12 -12
  39. package/models/trace/handlers/FramesHandler.js +3 -3
  40. package/models/trace/handlers/FramesHandler.js.map +1 -1
  41. package/models/trace/handlers/LayoutShiftsHandler.d.ts +2 -2
  42. package/models/trace/handlers/LayoutShiftsHandler.js +25 -16
  43. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
  44. package/models/trace/handlers/MetaHandler.d.ts +2 -2
  45. package/models/trace/handlers/MetaHandler.js +21 -21
  46. package/models/trace/handlers/MetaHandler.js.map +1 -1
  47. package/models/trace/handlers/NetworkRequestsHandler.js +37 -38
  48. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  49. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +6 -6
  50. package/models/trace/handlers/PageLoadMetricsHandler.js +9 -9
  51. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
  52. package/models/trace/handlers/RendererHandler.d.ts +1 -1
  53. package/models/trace/handlers/RendererHandler.js +4 -4
  54. package/models/trace/handlers/RendererHandler.js.map +1 -1
  55. package/models/trace/handlers/SamplesHandler.d.ts +1 -1
  56. package/models/trace/handlers/SamplesHandler.js +50 -42
  57. package/models/trace/handlers/SamplesHandler.js.map +1 -1
  58. package/models/trace/handlers/ScreenshotsHandler.d.ts +6 -3
  59. package/models/trace/handlers/ScreenshotsHandler.js +22 -8
  60. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
  61. package/models/trace/handlers/ServerTimingsHandler.js +4 -4
  62. package/models/trace/handlers/ServerTimingsHandler.js.map +1 -1
  63. package/models/trace/handlers/Threads.js +3 -4
  64. package/models/trace/handlers/Threads.js.map +1 -1
  65. package/models/trace/handlers/UserInteractionsHandler.d.ts +2 -2
  66. package/models/trace/handlers/UserInteractionsHandler.js +12 -12
  67. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
  68. package/models/trace/handlers/WarningsHandler.d.ts +2 -2
  69. package/models/trace/handlers/WarningsHandler.js +2 -2
  70. package/models/trace/handlers/WarningsHandler.js.map +1 -1
  71. package/models/trace/handlers/helpers.d.ts +3 -3
  72. package/models/trace/handlers/helpers.js +16 -19
  73. package/models/trace/handlers/helpers.js.map +1 -1
  74. package/models/trace/handlers/types.d.ts +1 -1
  75. package/models/trace/handlers/types.js.map +1 -1
  76. package/models/trace/helpers/SamplesIntegrator.d.ts +1 -1
  77. package/models/trace/helpers/SamplesIntegrator.js +54 -15
  78. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  79. package/models/trace/helpers/Timing.d.ts +23 -23
  80. package/models/trace/helpers/Timing.js +11 -11
  81. package/models/trace/helpers/Timing.js.map +1 -1
  82. package/models/trace/helpers/Trace.d.ts +15 -14
  83. package/models/trace/helpers/Trace.js +11 -5
  84. package/models/trace/helpers/Trace.js.map +1 -1
  85. package/models/trace/helpers/TreeHelpers.d.ts +2 -2
  86. package/models/trace/helpers/TreeHelpers.js +5 -5
  87. package/models/trace/helpers/TreeHelpers.js.map +1 -1
  88. package/models/trace/insights/CLSCulprits.d.ts +46 -1
  89. package/models/trace/insights/CLSCulprits.js +85 -10
  90. package/models/trace/insights/CLSCulprits.js.map +1 -1
  91. package/models/trace/insights/Common.d.ts +11 -7
  92. package/models/trace/insights/Common.js +85 -26
  93. package/models/trace/insights/Common.js.map +1 -1
  94. package/models/trace/insights/DOMSize.d.ts +26 -1
  95. package/models/trace/insights/DOMSize.js +44 -7
  96. package/models/trace/insights/DOMSize.js.map +1 -1
  97. package/models/trace/insights/DocumentLatency.d.ts +42 -5
  98. package/models/trace/insights/DocumentLatency.js +64 -8
  99. package/models/trace/insights/DocumentLatency.js.map +1 -1
  100. package/models/trace/insights/FontDisplay.d.ts +8 -2
  101. package/models/trace/insights/FontDisplay.js +10 -4
  102. package/models/trace/insights/FontDisplay.js.map +1 -1
  103. package/models/trace/insights/ForcedReflow.d.ts +30 -0
  104. package/models/trace/insights/ForcedReflow.js +181 -0
  105. package/models/trace/insights/ForcedReflow.js.map +1 -0
  106. package/models/trace/insights/ImageDelivery.d.ts +15 -1
  107. package/models/trace/insights/ImageDelivery.js +21 -1
  108. package/models/trace/insights/ImageDelivery.js.map +1 -1
  109. package/models/trace/insights/InteractionToNextPaint.d.ts +26 -1
  110. package/models/trace/insights/InteractionToNextPaint.js +27 -1
  111. package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
  112. package/models/trace/insights/LCPDiscovery.d.ts +30 -6
  113. package/models/trace/insights/LCPDiscovery.js +36 -8
  114. package/models/trace/insights/LCPDiscovery.js.map +1 -1
  115. package/models/trace/insights/LCPPhases.d.ts +36 -7
  116. package/models/trace/insights/LCPPhases.js +37 -8
  117. package/models/trace/insights/LCPPhases.js.map +1 -1
  118. package/models/trace/insights/LongCriticalNetworkTree.d.ts +22 -0
  119. package/models/trace/insights/LongCriticalNetworkTree.js +40 -0
  120. package/models/trace/insights/LongCriticalNetworkTree.js.map +1 -0
  121. package/models/trace/insights/Models.d.ts +2 -0
  122. package/models/trace/insights/Models.js +2 -0
  123. package/models/trace/insights/Models.js.map +1 -1
  124. package/models/trace/insights/RenderBlocking.d.ts +14 -1
  125. package/models/trace/insights/RenderBlocking.js +14 -1
  126. package/models/trace/insights/RenderBlocking.js.map +1 -1
  127. package/models/trace/insights/SlowCSSSelector.d.ts +27 -2
  128. package/models/trace/insights/SlowCSSSelector.js +27 -2
  129. package/models/trace/insights/SlowCSSSelector.js.map +1 -1
  130. package/models/trace/insights/ThirdParties.d.ts +13 -4
  131. package/models/trace/insights/ThirdParties.js +21 -12
  132. package/models/trace/insights/ThirdParties.js.map +1 -1
  133. package/models/trace/insights/Viewport.d.ts +2 -1
  134. package/models/trace/insights/Viewport.js +2 -1
  135. package/models/trace/insights/Viewport.js.map +1 -1
  136. package/models/trace/insights/insights-tsconfig.json +2 -0
  137. package/models/trace/insights/types.d.ts +27 -8
  138. package/models/trace/insights/types.js.map +1 -1
  139. package/models/trace/lantern/graph/BaseNode.d.ts +1 -1
  140. package/models/trace/lantern/graph/BaseNode.js +1 -1
  141. package/models/trace/lantern/graph/BaseNode.js.map +1 -1
  142. package/models/trace/lantern/graph/CPUNode.d.ts +1 -1
  143. package/models/trace/lantern/graph/CPUNode.js.map +1 -1
  144. package/models/trace/lantern/graph/NetworkNode.d.ts +1 -1
  145. package/models/trace/lantern/graph/NetworkNode.js.map +1 -1
  146. package/models/trace/lantern/metrics/FirstContentfulPaint.d.ts +1 -1
  147. package/models/trace/lantern/metrics/FirstContentfulPaint.js.map +1 -1
  148. package/models/trace/lantern/simulation/ConnectionPool.js +1 -1
  149. package/models/trace/lantern/simulation/ConnectionPool.js.map +1 -1
  150. package/models/trace/lantern/simulation/Simulator.d.ts +2 -2
  151. package/models/trace/lantern/simulation/Simulator.js +3 -3
  152. package/models/trace/lantern/simulation/Simulator.js.map +1 -1
  153. package/models/trace/lantern/types/Lantern.d.ts +2 -2
  154. package/models/trace/lantern/types/Lantern.js.map +1 -1
  155. package/models/trace/root-causes/LayoutShift.d.ts +1 -1
  156. package/models/trace/root-causes/LayoutShift.js +4 -4
  157. package/models/trace/root-causes/LayoutShift.js.map +1 -1
  158. package/models/trace/types/Configuration.d.ts +15 -0
  159. package/models/trace/types/Configuration.js.map +1 -1
  160. package/models/trace/types/File.d.ts +4 -4
  161. package/models/trace/types/File.js.map +1 -1
  162. package/models/trace/types/Timing.d.ts +7 -13
  163. package/models/trace/types/Timing.js +5 -2
  164. package/models/trace/types/Timing.js.map +1 -1
  165. package/models/trace/types/TraceEvents.d.ts +145 -110
  166. package/models/trace/types/TraceEvents.js +9 -7
  167. package/models/trace/types/TraceEvents.js.map +1 -1
  168. package/package.json +1 -1
  169. package/test/test-trace-engine.mjs +18 -14
  170. package/core/platform/PromiseUtilities.d.ts +0 -10
  171. package/core/platform/PromiseUtilities.js +0 -18
  172. package/core/platform/PromiseUtilities.js.map +0 -1
  173. package/core/platform/SetUtilities.d.ts +0 -2
  174. package/core/platform/SetUtilities.js +0 -23
  175. package/core/platform/SetUtilities.js.map +0 -1
  176. package/models/trace/EntriesFilter.d.ts +0 -72
  177. package/models/trace/EntriesFilter.js +0 -296
  178. package/models/trace/EntriesFilter.js.map +0 -1
  179. package/models/trace/LegacyTracingModel.js.map +0 -1
  180. package/models/trace/extras/URLForEntry.d.ts +0 -13
  181. package/models/trace/extras/URLForEntry.js +0 -44
  182. package/models/trace/extras/URLForEntry.js.map +0 -1
  183. package/models/trace/handlers/EnhancedTracesHandler.d.ts +0 -48
  184. package/models/trace/handlers/EnhancedTracesHandler.js +0 -165
  185. package/models/trace/handlers/EnhancedTracesHandler.js.map +0 -1
  186. package/models/trace/insights/CumulativeLayoutShift.d.ts +0 -34
  187. package/models/trace/insights/CumulativeLayoutShift.js +0 -209
  188. package/models/trace/insights/CumulativeLayoutShift.js.map +0 -1
  189. package/models/trace/insights/InsightRunners.d.ts +0 -6
  190. package/models/trace/insights/InsightRunners.js +0 -10
  191. package/models/trace/insights/InsightRunners.js.map +0 -1
  192. package/models/trace/insights/LargestContentfulPaint.d.ts +0 -25
  193. package/models/trace/insights/LargestContentfulPaint.js +0 -93
  194. package/models/trace/insights/LargestContentfulPaint.js.map +0 -1
  195. package/models/trace/lantern/BaseNode.d.ts +0 -91
  196. package/models/trace/lantern/BaseNode.js +0 -268
  197. package/models/trace/lantern/BaseNode.js.map +0 -1
  198. package/models/trace/lantern/CPUNode.d.ts +0 -24
  199. package/models/trace/lantern/CPUNode.js +0 -64
  200. package/models/trace/lantern/CPUNode.js.map +0 -1
  201. package/models/trace/lantern/LanternError.d.ts +0 -3
  202. package/models/trace/lantern/LanternError.js +0 -7
  203. package/models/trace/lantern/LanternError.js.map +0 -1
  204. package/models/trace/lantern/MetricsModule.d.ts +0 -11
  205. package/models/trace/lantern/MetricsModule.js +0 -14
  206. package/models/trace/lantern/MetricsModule.js.map +0 -1
  207. package/models/trace/lantern/NetworkNode.d.ts +0 -22
  208. package/models/trace/lantern/NetworkNode.js +0 -83
  209. package/models/trace/lantern/NetworkNode.js.map +0 -1
  210. package/models/trace/lantern/PageDependencyGraph.d.ts +0 -43
  211. package/models/trace/lantern/PageDependencyGraph.js +0 -509
  212. package/models/trace/lantern/PageDependencyGraph.js.map +0 -1
  213. package/models/trace/lantern/SimulationModule.d.ts +0 -17
  214. package/models/trace/lantern/SimulationModule.js +0 -13
  215. package/models/trace/lantern/SimulationModule.js.map +0 -1
  216. package/models/trace/lantern/simulation/NetworkAnalyzer.d.ts +0 -112
  217. package/models/trace/lantern/simulation/NetworkAnalyzer.js +0 -486
  218. package/models/trace/lantern/simulation/NetworkAnalyzer.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.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.\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as Lantern from './lantern/lantern.js';\nimport * as LanternComputationData from './LanternComputationData.js';\nimport type * as Model from './ModelImpl.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: Model.TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\n\n/**\n * Parsing a trace can take time. On large traces we see a breakdown of time like so:\n * - handleEvent() loop: ~20%\n * - finalize() loop: ~60%\n * - shallowClone calls: ~20%\n * The numbers below are set so we can report a progress percentage of [0...1]\n */\nconst enum ProgressPhase {\n HANDLE_EVENT = 0.2,\n FINALIZE = 0.8,\n CLONE = 1.0,\n}\nfunction calculateProgress(value: number, phase: ProgressPhase): number {\n // Finalize values should be [0.2...0.8]\n if (phase === ProgressPhase.FINALIZE) {\n return (value * (ProgressPhase.FINALIZE - ProgressPhase.HANDLE_EVENT)) + ProgressPhase.HANDLE_EVENT;\n }\n return value * phase;\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport interface ParseOptions {\n /**\n * If the trace was just recorded on the current page, rather than an imported file.\n * TODO(paulirish): Maybe remove. This is currently unused by the Processor and Handlers\n * @default false\n */\n isFreshRecording?: boolean;\n /**\n * If the trace is a CPU Profile rather than a Chrome tracing trace.\n * @default false\n */\n isCPUProfile?: boolean;\n metadata?: Types.File.MetaData;\n}\n\nexport class TraceProcessor extends EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n readonly #traceHandlers: Partial<Handlers.Types.Handlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.defaults();\n #data: Handlers.Types.ParsedTrace|null = null;\n #insights: Insights.Types.TraceInsightSets|null = null;\n\n static createWithAllHandlers(): TraceProcessor {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.defaults());\n }\n\n static getEnabledInsightRunners(parsedTrace: Handlers.Types.ParsedTrace): Partial<Insights.Types.InsightModelsType> {\n const enabledInsights = {} as Insights.Types.InsightModelsType;\n for (const [name, insight] of Object.entries(Insights.Models)) {\n const deps = insight.deps();\n if (deps.some(dep => !parsedTrace[dep])) {\n continue;\n }\n Object.assign(enabledInsights, {[name]: insight});\n }\n return enabledInsights;\n }\n\n constructor(traceHandlers: Partial<Handlers.Types.Handlers>, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: Partial<Handlers.Types.Handlers>): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.HandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.HandlerName);\n const deps = 'deps' in handler ? handler.deps() : [];\n for (const depName of deps) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#data = null;\n this.#insights = null;\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.Events.Event[], options: ParseOptions): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#computeParsedTrace(traceEvents);\n if (this.#data && !options.isCPUProfile) { // We do not calculate insights for CPU Profiles.\n this.#computeInsights(this.#data, traceEvents, options);\n }\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n /**\n * Run all the handlers and set the result to `#data`.\n */\n async #computeParsedTrace(traceEvents: readonly Types.Events.Event[]): Promise<void> {\n /**\n * We want to yield regularly to maintain responsiveness. If we yield too often, we're wasting idle time.\n * We could do this by checking `performance.now()` regularly, but it's an expensive call in such a hot loop.\n * `eventsPerChunk` is an approximated proxy metric.\n * But how big a chunk? We're aiming for long tasks that are no smaller than 100ms and not bigger than 200ms.\n * It's CPU dependent, so it should be calibrated on oldish hardware.\n * Illustration of a previous change to `eventsPerChunk`: https://imgur.com/wzp8BnR\n */\n const eventsPerChunk = 50_000;\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Handle each event.\n for (let i = 0; i < traceEvents.length; ++i) {\n // Every so often we take a break just to render.\n if (i % eventsPerChunk === 0 && i) {\n // Take the opportunity to provide status update events.\n const percent = calculateProgress(i / traceEvents.length, ProgressPhase.HANDLE_EVENT);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n // TODO(paulirish): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n const event = traceEvents[i];\n for (let j = 0; j < sortedHandlers.length; ++j) {\n sortedHandlers[j].handleEvent(event);\n }\n }\n\n // Finalize.\n for (const [i, handler] of sortedHandlers.entries()) {\n if (handler.finalize) {\n // Yield to the UI because finalize() calls can be expensive\n // TODO(jacktfranklin): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n await handler.finalize();\n }\n const percent = calculateProgress(i / sortedHandlers.length, ProgressPhase.FINALIZE);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n }\n\n // Handlers that depend on other handlers do so via .data(), which used to always\n // return a shallow clone of its internal data structures. However, that pattern\n // easily results in egregious amounts of allocation. Now .data() does not do any\n // cloning, and it happens here instead so that users of the trace processor may\n // still assume that the parsed data is theirs.\n // See: crbug/41484172\n const shallowClone = (value: unknown, recurse = true): unknown => {\n if (value instanceof Map) {\n return new Map(value);\n }\n if (value instanceof Set) {\n return new Set(value);\n }\n if (Array.isArray(value)) {\n return [...value];\n }\n if (typeof value === 'object' && value && recurse) {\n const obj: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) {\n obj[key] = shallowClone(v, false);\n }\n return obj;\n }\n return value;\n };\n\n const parsedTrace = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n const data = shallowClone(handler.data());\n Object.assign(parsedTrace, {[name]: data});\n }\n this.dispatchEvent(new TraceParseProgressEvent({percent: ProgressPhase.CLONE}));\n\n this.#data = parsedTrace as Handlers.Types.ParsedTrace;\n }\n\n get parsedTrace(): Handlers.Types.ParsedTrace|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#data;\n }\n\n get insights(): Insights.Types.TraceInsightSets|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#insights;\n }\n\n #createLanternContext(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[], frameId: string,\n navigationId: string): Insights.Types.LanternContext|undefined {\n // Check for required handlers.\n if (!parsedTrace.NetworkRequests || !parsedTrace.Workers || !parsedTrace.PageLoadMetrics) {\n return;\n }\n if (!parsedTrace.NetworkRequests.byTime.length) {\n throw new Lantern.Core.LanternError('No network requests found in trace');\n }\n\n const navStarts = parsedTrace.Meta.navigationsByFrameId.get(frameId);\n const navStartIndex = navStarts?.findIndex(n => n.args.data?.navigationId === navigationId);\n if (!navStarts || navStartIndex === undefined || navStartIndex === -1) {\n throw new Lantern.Core.LanternError('Could not find navigation start');\n }\n\n const startTime = navStarts[navStartIndex].ts;\n const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY;\n const boundedTraceEvents = traceEvents.filter(e => e.ts >= startTime && e.ts < endTime);\n\n // Lantern.Types.TraceEvent and Types.Events.Event represent the same\n // object - a trace event - but one is more flexible than the other. It should be safe to cast between them.\n const trace: Lantern.Types.Trace = {\n traceEvents: boundedTraceEvents as unknown as Lantern.Types.TraceEvent[],\n };\n\n const requests = LanternComputationData.createNetworkRequests(trace, parsedTrace, startTime, endTime);\n const graph = LanternComputationData.createGraph(requests, trace, parsedTrace);\n const processedNavigation = LanternComputationData.createProcessedNavigation(parsedTrace, frameId, navigationId);\n\n const networkAnalysis = Lantern.Core.NetworkAnalyzer.analyze(requests);\n if (!networkAnalysis) {\n return;\n }\n\n const simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest> =\n Lantern.Simulation.Simulator.createSimulator({\n // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture\n // that? Do we need to set 'devtools' throttlingMethod?\n networkAnalysis,\n throttlingMethod: 'provided',\n });\n\n const computeData = {graph, simulator, processedNavigation};\n const fcpResult = Lantern.Metrics.FirstContentfulPaint.compute(computeData);\n const lcpResult = Lantern.Metrics.LargestContentfulPaint.compute(computeData, {fcpResult});\n const interactiveResult = Lantern.Metrics.Interactive.compute(computeData, {lcpResult});\n const tbtResult = Lantern.Metrics.TotalBlockingTime.compute(computeData, {fcpResult, interactiveResult});\n const metrics = {\n firstContentfulPaint: fcpResult,\n interactive: interactiveResult,\n largestContentfulPaint: lcpResult,\n totalBlockingTime: tbtResult,\n };\n\n return {graph, simulator, metrics};\n }\n\n /**\n * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the\n * worst metrics according to field data (if present).\n */\n sortInsightSet(\n insights: Insights.Types.TraceInsightSets, insightSet: Insights.Types.InsightSet,\n metadata: Types.File.MetaData|null): void {\n // The initial order of the insights is alphabetical, based on `front_end/models/trace/insights/Models.ts`.\n // The order here provides a baseline that groups insights in a more logical way.\n const baselineOrder: Record<keyof Insights.Types.InsightModels, null> = {\n InteractionToNextPaint: null,\n LCPPhases: null,\n LCPDiscovery: null,\n CLSCulprits: null,\n RenderBlocking: null,\n ImageDelivery: null,\n DocumentLatency: null,\n FontDisplay: null,\n Viewport: null,\n DOMSize: null,\n ThirdParties: null,\n SlowCSSSelector: null,\n };\n\n // Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.\n const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);\n\n // Normalize the estimated savings to a single number, weighted by its relative impact\n // to the page experience based on the same scoring curve that Lighthouse uses.\n const observedLcp = Insights.Common.getLCP(insights, insightSet.id)?.value;\n const observedCls = Insights.Common.getCLS(insights, insightSet.id).value;\n\n // INP is special - if users did not interact with the page, we'll have no INP, but we should still\n // be able to prioritize insights based on this metric. When we observe no interaction, instead use\n // a default value for the baseline INP.\n const observedInp = Insights.Common.getINP(insights, insightSet.id)?.value ?? 200;\n\n const observedLcpScore =\n observedLcp !== undefined ? Insights.Common.evaluateLCPMetricScore(observedLcp) : undefined;\n const observedInpScore = Insights.Common.evaluateINPMetricScore(observedInp);\n const observedClsScore = Insights.Common.evaluateCLSMetricScore(observedCls);\n\n const insightToSortingRank = new Map<string, number>();\n for (const [name, model] of Object.entries(insightSet.model)) {\n const lcp = model.metricSavings?.LCP ?? 0;\n const inp = model.metricSavings?.INP ?? 0;\n const cls = model.metricSavings?.CLS ?? 0;\n\n const lcpPostSavings = observedLcp !== undefined ? Math.max(0, observedLcp - lcp) : undefined;\n const inpPostSavings = Math.max(0, observedInp - inp);\n const clsPostSavings = Math.max(0, observedCls - cls);\n\n let score = 0;\n if (weights.lcp && lcp && observedLcpScore !== undefined && lcpPostSavings !== undefined) {\n score += weights.lcp * (Insights.Common.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore);\n }\n if (weights.inp && inp && observedInpScore !== undefined) {\n score += weights.inp * (Insights.Common.evaluateINPMetricScore(inpPostSavings) - observedInpScore);\n }\n if (weights.cls && cls && observedClsScore !== undefined) {\n score += weights.cls * (Insights.Common.evaluateCLSMetricScore(clsPostSavings) - observedClsScore);\n }\n\n insightToSortingRank.set(name, score);\n }\n\n // Now perform the actual sorting.\n const baselineOrderKeys = Object.keys(baselineOrder);\n const orderedKeys = Object.keys(insightSet.model);\n orderedKeys.sort((a, b) => {\n const a1 = baselineOrderKeys.indexOf(a);\n const b1 = baselineOrderKeys.indexOf(b);\n if (a1 >= 0 && b1 >= 0) {\n return a1 - b1;\n }\n if (a1 >= 0) {\n return -1;\n }\n if (b1 >= 0) {\n return 1;\n }\n return 0;\n });\n orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0));\n\n const newModel = {} as Insights.Types.InsightModels;\n for (const key of orderedKeys as Array<keyof Insights.Types.InsightModels>) {\n const model = insightSet.model[key];\n // @ts-expect-error Maybe someday typescript will be powerful enough to handle this.\n newModel[key] = model;\n }\n insightSet.model = newModel;\n }\n\n #computeInsightSet(\n insights: Insights.Types.TraceInsightSets, parsedTrace: Handlers.Types.ParsedTrace,\n insightRunners: Partial<typeof Insights.Models>, context: Insights.Types.InsightSetContext,\n options: ParseOptions): void {\n const model = {} as Insights.Types.InsightSet['model'];\n\n for (const [name, insight] of Object.entries(insightRunners)) {\n let insightResult;\n try {\n insightResult = insight.generateInsight(parsedTrace, context);\n } catch (err) {\n insightResult = err;\n }\n Object.assign(model, {[name]: insightResult});\n }\n\n let id, urlString, navigation;\n if (context.navigation) {\n id = context.navigationId;\n urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n navigation = context.navigation;\n } else {\n id = Types.Events.NO_NAVIGATION;\n urlString = parsedTrace.Meta.mainFrameURL;\n }\n\n let url;\n try {\n url = new URL(urlString);\n } catch {\n // We're pretty sure this only happens for our test fixture: missing-url.json.gz. Shouldn't\n // happen for real traces.\n return;\n }\n\n const insightSet: Insights.Types.InsightSet = {\n id,\n url,\n navigation,\n frameId: context.frameId,\n bounds: context.bounds,\n model,\n };\n insights.set(insightSet.id, insightSet);\n this.sortInsightSet(insights, insightSet, options.metadata ?? null);\n }\n\n /**\n * Run all the insights and set the result to `#insights`.\n */\n #computeInsights(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[],\n options: ParseOptions): void {\n this.#insights = new Map();\n\n const enabledInsightRunners = TraceProcessor.getEnabledInsightRunners(parsedTrace);\n\n const navigations = parsedTrace.Meta.mainFrameNavigations.filter(\n navigation => navigation.args.frame && navigation.args.data?.navigationId);\n\n // Check if there is a meaningful chunk of work happening prior to the first navigation.\n // If so, we run the insights on that initial bounds.\n // Otherwise, there are no navigations and we do a no-navigation insights pass on the entire trace.\n if (navigations.length) {\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(parsedTrace.Meta.traceBounds.min, navigations[0].ts);\n // When using \"Record and reload\" option, it typically takes ~5ms. So use 50ms to be safe.\n const threshold = Helpers.Timing.milliToMicro(50 as Types.Timing.MilliSeconds);\n if (bounds.range > threshold) {\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n // If threshold is not met, then the very beginning of the trace is ignored by the insights engine.\n } else {\n const context: Insights.Types.InsightSetContext = {\n bounds: parsedTrace.Meta.traceBounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n\n // Now run the insights for each navigation in isolation.\n for (const [i, navigation] of navigations.entries()) {\n // The above filter guarantees these are present.\n const frameId = navigation.args.frame;\n const navigationId = navigation.args.data?.navigationId as string;\n\n // The lantern sub-context is optional on InsightSetContext, so not setting it is OK.\n // This is also a hedge against an error inside Lantern resulting in breaking the entire performance panel.\n // Additionally, many trace fixtures are too old to be processed by Lantern.\n let lantern;\n try {\n lantern = this.#createLanternContext(parsedTrace, traceEvents, frameId, navigationId);\n } catch (e) {\n // Don't allow an error in constructing the Lantern graphs to break the rest of the trace processor.\n // Log unexpected errors, but suppress anything that occurs from a trace being too old.\n // Otherwise tests using old fixtures become way too noisy.\n const expectedErrors = [\n 'mainDocumentRequest not found',\n 'missing metric scores for main frame',\n 'missing metric: FCP',\n 'missing metric: LCP',\n 'No network requests found in trace',\n 'Trace is too old',\n ];\n if (!(e instanceof Lantern.Core.LanternError)) {\n // If this wasn't a managed LanternError, the stack trace is likely needed for debugging.\n console.error(e);\n } else if (!expectedErrors.some(err => e.message === err)) {\n // To reduce noise from tests, only print errors that are not expected to occur because a trace is\n // too old (for which there is no single check).\n console.error(e);\n }\n }\n\n const min = navigation.ts;\n const max = i + 1 < navigations.length ? navigations[i + 1].ts : parsedTrace.Meta.traceBounds.max;\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId,\n navigation,\n navigationId,\n lantern,\n };\n\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event hander whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):\n Map<Handlers.Types.HandlerName, Handlers.Types.Handler> {\n const sortedMap = new Map<Handlers.Types.HandlerName, Handlers.Types.Handler>();\n const visited = new Set<Handlers.Types.HandlerName>();\n const visitHandler = (handlerName: Handlers.Types.HandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.HandlerName);\n }\n return sortedMap;\n}\n"]}
1
+ {"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.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.\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as Lantern from './lantern/lantern.js';\nimport * as LanternComputationData from './LanternComputationData.js';\nimport type * as Model from './ModelImpl.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: Model.TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\n\n/**\n * Parsing a trace can take time. On large traces we see a breakdown of time like so:\n * - handleEvent() loop: ~20%\n * - finalize() loop: ~60%\n * - shallowClone calls: ~20%\n * The numbers below are set so we can report a progress percentage of [0...1]\n */\nconst enum ProgressPhase {\n HANDLE_EVENT = 0.2,\n FINALIZE = 0.8,\n CLONE = 1.0,\n}\nfunction calculateProgress(value: number, phase: ProgressPhase): number {\n // Finalize values should be [0.2...0.8]\n if (phase === ProgressPhase.FINALIZE) {\n return (value * (ProgressPhase.FINALIZE - ProgressPhase.HANDLE_EVENT)) + ProgressPhase.HANDLE_EVENT;\n }\n return value * phase;\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor extends EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n readonly #traceHandlers: Partial<Handlers.Types.Handlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.defaults();\n #data: Handlers.Types.ParsedTrace|null = null;\n #insights: Insights.Types.TraceInsightSets|null = null;\n\n static createWithAllHandlers(): TraceProcessor {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.defaults());\n }\n\n static getEnabledInsightRunners(parsedTrace: Handlers.Types.ParsedTrace): Partial<Insights.Types.InsightModelsType> {\n const enabledInsights = {} as Insights.Types.InsightModelsType;\n for (const [name, insight] of Object.entries(Insights.Models)) {\n const deps = insight.deps();\n if (deps.some(dep => !parsedTrace[dep])) {\n continue;\n }\n Object.assign(enabledInsights, {[name]: insight});\n }\n return enabledInsights;\n }\n\n constructor(traceHandlers: Partial<Handlers.Types.Handlers>, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: Partial<Handlers.Types.Handlers>): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.HandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.HandlerName);\n const deps = 'deps' in handler ? handler.deps() : [];\n for (const depName of deps) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#data = null;\n this.#insights = null;\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#computeParsedTrace(traceEvents, options);\n if (this.#data && !options.isCPUProfile) { // We do not calculate insights for CPU Profiles.\n this.#computeInsights(this.#data, traceEvents, options);\n }\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n /**\n * Run all the handlers and set the result to `#data`.\n */\n async #computeParsedTrace(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions):\n Promise<void> {\n /**\n * We want to yield regularly to maintain responsiveness. If we yield too often, we're wasting idle time.\n * We could do this by checking `performance.now()` regularly, but it's an expensive call in such a hot loop.\n * `eventsPerChunk` is an approximated proxy metric.\n * But how big a chunk? We're aiming for long tasks that are no smaller than 100ms and not bigger than 200ms.\n * It's CPU dependent, so it should be calibrated on oldish hardware.\n * Illustration of a previous change to `eventsPerChunk`: https://imgur.com/wzp8BnR\n */\n const eventsPerChunk = 50_000;\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Handle each event.\n for (let i = 0; i < traceEvents.length; ++i) {\n // Every so often we take a break just to render.\n if (i % eventsPerChunk === 0 && i) {\n // Take the opportunity to provide status update events.\n const percent = calculateProgress(i / traceEvents.length, ProgressPhase.HANDLE_EVENT);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n // TODO(paulirish): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n const event = traceEvents[i];\n for (let j = 0; j < sortedHandlers.length; ++j) {\n sortedHandlers[j].handleEvent(event);\n }\n }\n\n // Finalize.\n for (const [i, handler] of sortedHandlers.entries()) {\n if (handler.finalize) {\n // Yield to the UI because finalize() calls can be expensive\n // TODO(jacktfranklin): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n await handler.finalize(options);\n }\n const percent = calculateProgress(i / sortedHandlers.length, ProgressPhase.FINALIZE);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n }\n\n // Handlers that depend on other handlers do so via .data(), which used to always\n // return a shallow clone of its internal data structures. However, that pattern\n // easily results in egregious amounts of allocation. Now .data() does not do any\n // cloning, and it happens here instead so that users of the trace processor may\n // still assume that the parsed data is theirs.\n // See: crbug/41484172\n const shallowClone = (value: unknown, recurse = true): unknown => {\n if (value instanceof Map) {\n return new Map(value);\n }\n if (value instanceof Set) {\n return new Set(value);\n }\n if (Array.isArray(value)) {\n return [...value];\n }\n if (typeof value === 'object' && value && recurse) {\n const obj: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) {\n obj[key] = shallowClone(v, false);\n }\n return obj;\n }\n return value;\n };\n\n const parsedTrace = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n const data = shallowClone(handler.data());\n Object.assign(parsedTrace, {[name]: data});\n }\n this.dispatchEvent(new TraceParseProgressEvent({percent: ProgressPhase.CLONE}));\n\n this.#data = parsedTrace as Handlers.Types.ParsedTrace;\n }\n\n get parsedTrace(): Handlers.Types.ParsedTrace|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#data;\n }\n\n get insights(): Insights.Types.TraceInsightSets|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#insights;\n }\n\n #createLanternContext(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[], frameId: string,\n navigationId: string): Insights.Types.LanternContext|undefined {\n // Check for required handlers.\n if (!parsedTrace.NetworkRequests || !parsedTrace.Workers || !parsedTrace.PageLoadMetrics) {\n return;\n }\n if (!parsedTrace.NetworkRequests.byTime.length) {\n throw new Lantern.Core.LanternError('No network requests found in trace');\n }\n\n const navStarts = parsedTrace.Meta.navigationsByFrameId.get(frameId);\n const navStartIndex = navStarts?.findIndex(n => n.args.data?.navigationId === navigationId);\n if (!navStarts || navStartIndex === undefined || navStartIndex === -1) {\n throw new Lantern.Core.LanternError('Could not find navigation start');\n }\n\n const startTime = navStarts[navStartIndex].ts;\n const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY;\n const boundedTraceEvents = traceEvents.filter(e => e.ts >= startTime && e.ts < endTime);\n\n // Lantern.Types.TraceEvent and Types.Events.Event represent the same\n // object - a trace event - but one is more flexible than the other. It should be safe to cast between them.\n const trace: Lantern.Types.Trace = {\n traceEvents: boundedTraceEvents as unknown as Lantern.Types.TraceEvent[],\n };\n\n const requests = LanternComputationData.createNetworkRequests(trace, parsedTrace, startTime, endTime);\n const graph = LanternComputationData.createGraph(requests, trace, parsedTrace);\n const processedNavigation = LanternComputationData.createProcessedNavigation(parsedTrace, frameId, navigationId);\n\n const networkAnalysis = Lantern.Core.NetworkAnalyzer.analyze(requests);\n if (!networkAnalysis) {\n return;\n }\n\n const simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest> =\n Lantern.Simulation.Simulator.createSimulator({\n // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture\n // that? Do we need to set 'devtools' throttlingMethod?\n networkAnalysis,\n throttlingMethod: 'provided',\n });\n\n const computeData = {graph, simulator, processedNavigation};\n const fcpResult = Lantern.Metrics.FirstContentfulPaint.compute(computeData);\n const lcpResult = Lantern.Metrics.LargestContentfulPaint.compute(computeData, {fcpResult});\n const interactiveResult = Lantern.Metrics.Interactive.compute(computeData, {lcpResult});\n const tbtResult = Lantern.Metrics.TotalBlockingTime.compute(computeData, {fcpResult, interactiveResult});\n const metrics = {\n firstContentfulPaint: fcpResult,\n interactive: interactiveResult,\n largestContentfulPaint: lcpResult,\n totalBlockingTime: tbtResult,\n };\n\n return {graph, simulator, metrics};\n }\n\n /**\n * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the\n * worst metrics according to field data (if present).\n */\n sortInsightSet(\n insights: Insights.Types.TraceInsightSets, insightSet: Insights.Types.InsightSet,\n metadata: Types.File.MetaData|null): void {\n // The initial order of the insights is alphabetical, based on `front_end/models/trace/insights/Models.ts`.\n // The order here provides a baseline that groups insights in a more logical way.\n const baselineOrder: Record<keyof Insights.Types.InsightModels, null> = {\n InteractionToNextPaint: null,\n LCPPhases: null,\n LCPDiscovery: null,\n CLSCulprits: null,\n RenderBlocking: null,\n ImageDelivery: null,\n DocumentLatency: null,\n FontDisplay: null,\n Viewport: null,\n DOMSize: null,\n ThirdParties: null,\n SlowCSSSelector: null,\n LongCriticalNetworkTree: null,\n ForcedReflow: null,\n };\n\n // Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.\n const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);\n\n // Normalize the estimated savings to a single number, weighted by its relative impact\n // to the page experience based on the same scoring curve that Lighthouse uses.\n const observedLcp = Insights.Common.getLCP(insights, insightSet.id)?.value;\n const observedCls = Insights.Common.getCLS(insights, insightSet.id).value;\n\n // INP is special - if users did not interact with the page, we'll have no INP, but we should still\n // be able to prioritize insights based on this metric. When we observe no interaction, instead use\n // a default value for the baseline INP.\n const observedInp = Insights.Common.getINP(insights, insightSet.id)?.value ?? 200;\n\n const observedLcpScore =\n observedLcp !== undefined ? Insights.Common.evaluateLCPMetricScore(observedLcp) : undefined;\n const observedInpScore = Insights.Common.evaluateINPMetricScore(observedInp);\n const observedClsScore = Insights.Common.evaluateCLSMetricScore(observedCls);\n\n const insightToSortingRank = new Map<string, number>();\n for (const [name, model] of Object.entries(insightSet.model)) {\n const lcp = model.metricSavings?.LCP ?? 0;\n const inp = model.metricSavings?.INP ?? 0;\n const cls = model.metricSavings?.CLS ?? 0;\n\n const lcpPostSavings = observedLcp !== undefined ? Math.max(0, observedLcp - lcp) : undefined;\n const inpPostSavings = Math.max(0, observedInp - inp);\n const clsPostSavings = Math.max(0, observedCls - cls);\n\n let score = 0;\n if (weights.lcp && lcp && observedLcpScore !== undefined && lcpPostSavings !== undefined) {\n score += weights.lcp * (Insights.Common.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore);\n }\n if (weights.inp && inp && observedInpScore !== undefined) {\n score += weights.inp * (Insights.Common.evaluateINPMetricScore(inpPostSavings) - observedInpScore);\n }\n if (weights.cls && cls && observedClsScore !== undefined) {\n score += weights.cls * (Insights.Common.evaluateCLSMetricScore(clsPostSavings) - observedClsScore);\n }\n\n insightToSortingRank.set(name, score);\n }\n\n // Now perform the actual sorting.\n const baselineOrderKeys = Object.keys(baselineOrder);\n const orderedKeys = Object.keys(insightSet.model);\n orderedKeys.sort((a, b) => {\n const a1 = baselineOrderKeys.indexOf(a);\n const b1 = baselineOrderKeys.indexOf(b);\n if (a1 >= 0 && b1 >= 0) {\n return a1 - b1;\n }\n if (a1 >= 0) {\n return -1;\n }\n if (b1 >= 0) {\n return 1;\n }\n return 0;\n });\n orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0));\n\n const newModel = {} as Insights.Types.InsightModels;\n for (const key of orderedKeys as Array<keyof Insights.Types.InsightModels>) {\n const model = insightSet.model[key];\n // @ts-expect-error Maybe someday typescript will be powerful enough to handle this.\n newModel[key] = model;\n }\n insightSet.model = newModel;\n }\n\n #computeInsightSet(\n insights: Insights.Types.TraceInsightSets, parsedTrace: Handlers.Types.ParsedTrace,\n insightRunners: Partial<typeof Insights.Models>, context: Insights.Types.InsightSetContext,\n options: Types.Configuration.ParseOptions): void {\n const model = {} as Insights.Types.InsightSet['model'];\n\n for (const [name, insight] of Object.entries(insightRunners)) {\n let insightResult;\n try {\n insightResult = insight.generateInsight(parsedTrace, context);\n } catch (err) {\n insightResult = err;\n }\n Object.assign(model, {[name]: insightResult});\n }\n\n let id, urlString, navigation;\n if (context.navigation) {\n id = context.navigationId;\n urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n navigation = context.navigation;\n } else {\n id = Types.Events.NO_NAVIGATION;\n urlString = parsedTrace.Meta.mainFrameURL;\n }\n\n let url;\n try {\n url = new URL(urlString);\n } catch {\n // We're pretty sure this only happens for our test fixture: missing-url.json.gz. Shouldn't\n // happen for real traces.\n return;\n }\n\n const insightSet: Insights.Types.InsightSet = {\n id,\n url,\n navigation,\n frameId: context.frameId,\n bounds: context.bounds,\n model,\n };\n insights.set(insightSet.id, insightSet);\n this.sortInsightSet(insights, insightSet, options.metadata ?? null);\n }\n\n /**\n * Run all the insights and set the result to `#insights`.\n */\n #computeInsights(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[],\n options: Types.Configuration.ParseOptions): void {\n this.#insights = new Map();\n\n const enabledInsightRunners = TraceProcessor.getEnabledInsightRunners(parsedTrace);\n\n const navigations = parsedTrace.Meta.mainFrameNavigations.filter(\n navigation => navigation.args.frame && navigation.args.data?.navigationId);\n\n // Check if there is a meaningful chunk of work happening prior to the first navigation.\n // If so, we run the insights on that initial bounds.\n // Otherwise, there are no navigations and we do a no-navigation insights pass on the entire trace.\n if (navigations.length) {\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(parsedTrace.Meta.traceBounds.min, navigations[0].ts);\n // When using \"Record and reload\" option, it typically takes ~5ms. So use 50ms to be safe.\n const threshold = Helpers.Timing.milliToMicro(50 as Types.Timing.Milli);\n if (bounds.range > threshold) {\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n // If threshold is not met, then the very beginning of the trace is ignored by the insights engine.\n } else {\n const context: Insights.Types.InsightSetContext = {\n bounds: parsedTrace.Meta.traceBounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n\n // Now run the insights for each navigation in isolation.\n for (const [i, navigation] of navigations.entries()) {\n // The above filter guarantees these are present.\n const frameId = navigation.args.frame;\n const navigationId = navigation.args.data?.navigationId as string;\n\n // The lantern sub-context is optional on InsightSetContext, so not setting it is OK.\n // This is also a hedge against an error inside Lantern resulting in breaking the entire performance panel.\n // Additionally, many trace fixtures are too old to be processed by Lantern.\n let lantern;\n try {\n lantern = this.#createLanternContext(parsedTrace, traceEvents, frameId, navigationId);\n } catch (e) {\n // Don't allow an error in constructing the Lantern graphs to break the rest of the trace processor.\n // Log unexpected errors, but suppress anything that occurs from a trace being too old.\n // Otherwise tests using old fixtures become way too noisy.\n const expectedErrors = [\n 'mainDocumentRequest not found',\n 'missing metric scores for main frame',\n 'missing metric: FCP',\n 'missing metric: LCP',\n 'No network requests found in trace',\n 'Trace is too old',\n ];\n if (!(e instanceof Lantern.Core.LanternError)) {\n // If this wasn't a managed LanternError, the stack trace is likely needed for debugging.\n console.error(e);\n } else if (!expectedErrors.some(err => e.message === err)) {\n // To reduce noise from tests, only print errors that are not expected to occur because a trace is\n // too old (for which there is no single check).\n console.error(e);\n }\n }\n\n const min = navigation.ts;\n const max = i + 1 < navigations.length ? navigations[i + 1].ts : parsedTrace.Meta.traceBounds.max;\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId,\n navigation,\n navigationId,\n lantern,\n };\n\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event handler whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):\n Map<Handlers.Types.HandlerName, Handlers.Types.Handler> {\n const sortedMap = new Map<Handlers.Types.HandlerName, Handlers.Types.Handler>();\n const visited = new Set<Handlers.Types.HandlerName>();\n const visitHandler = (handlerName: Handlers.Types.HandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.HandlerName);\n }\n return sortedMap;\n}\n"]}
@@ -1,12 +1,12 @@
1
1
  import type * as Handlers from '../handlers/handlers.js';
2
2
  import type * as Types from '../types/types.js';
3
3
  export interface Data {
4
- zeroTime: Types.Timing.MicroSeconds;
5
- spanTime: Types.Timing.MicroSeconds;
4
+ zeroTime: Types.Timing.Micro;
5
+ spanTime: Types.Timing.Micro;
6
6
  frames: readonly Frame[];
7
7
  }
8
8
  export interface Frame {
9
- screenshotEvent: Types.Events.SyntheticScreenshot;
9
+ screenshotEvent: Types.Events.LegacySyntheticScreenshot | Types.Events.Screenshot;
10
10
  index: number;
11
11
  }
12
12
  export type HandlersWithFilmStrip = Handlers.Types.HandlersWithMeta<{
@@ -15,5 +15,5 @@ export type HandlersWithFilmStrip = Handlers.Types.HandlersWithMeta<{
15
15
  export type HandlerDataWithScreenshots = Handlers.Types.EnabledHandlerDataWithMeta<{
16
16
  Screenshots: typeof Handlers.ModelHandlers.Screenshots;
17
17
  }>;
18
- export declare function fromParsedTrace(parsedTrace: HandlerDataWithScreenshots, customZeroTime?: Types.Timing.MicroSeconds): Data;
19
- export declare function frameClosestToTimestamp(filmStrip: Data, searchTimestamp: Types.Timing.MicroSeconds): Frame | null;
18
+ export declare function fromParsedTrace(parsedTrace: HandlerDataWithScreenshots, customZeroTime?: Types.Timing.Micro): Data;
19
+ export declare function frameClosestToTimestamp(filmStrip: Data, searchTimestamp: Types.Timing.Micro): Frame | null;
@@ -15,7 +15,8 @@ export function fromParsedTrace(parsedTrace, customZeroTime) {
15
15
  if (fromCache) {
16
16
  return fromCache;
17
17
  }
18
- for (const screenshotEvent of parsedTrace.Screenshots.all) {
18
+ const screenshots = parsedTrace.Screenshots.screenshots ?? parsedTrace.Screenshots.legacySyntheticScreenshots ?? [];
19
+ for (const screenshotEvent of screenshots) {
19
20
  if (screenshotEvent.ts < zeroTime) {
20
21
  continue;
21
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FilmStrip.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/FilmStrip.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAC7B,EAAE;AACF,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAyB/D,8BAA8B;AAC9B,kCAAkC;AAClC,qBAAqB;AACrB,MAAM,cAAc,GAAG,IAAI,OAAO,EAAoE,CAAC;AAEvG,MAAM,UAAU,eAAe,CAC3B,WAAuC,EAAE,cAA0C;IACrF,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,OAAO,cAAc,KAAK,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;IAC3G,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,MAAM,eAAe,IAAI,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QAC1D,IAAI,eAAe,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC;YAClC,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAU;YACnB,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,eAAe;SAChB,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,MAAM,GAAS;QACnB,QAAQ;QACR,QAAQ;QACR,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;KAC3B,CAAC;IAEF,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CACtD,cAAc,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAmC,CAAC,CAAC;IACnF,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAe,EAAE,eAA0C;IACjG,MAAM,gCAAgC,GAAG,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAChF,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,gCAAgC,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC;AAC5D,CAAC","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\nimport * as Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport type * as Types from '../types/types.js';\n\nexport interface Data {\n zeroTime: Types.Timing.MicroSeconds;\n spanTime: Types.Timing.MicroSeconds;\n frames: readonly Frame[];\n}\n\nexport interface Frame {\n screenshotEvent: Types.Events.SyntheticScreenshot;\n index: number;\n}\n\nexport type HandlersWithFilmStrip = Handlers.Types.HandlersWithMeta<{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Screenshots: typeof Handlers.ModelHandlers.Screenshots,\n}>;\n\nexport type HandlerDataWithScreenshots = Handlers.Types.EnabledHandlerDataWithMeta<{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Screenshots: typeof Handlers.ModelHandlers.Screenshots,\n}>;\n\n// Cache film strips based on:\n// 1. The trace parsed data object\n// 2. The start time.\nconst filmStripCache = new WeakMap<HandlerDataWithScreenshots, Map<Types.Timing.MicroSeconds, Data>>();\n\nexport function fromParsedTrace(\n parsedTrace: HandlerDataWithScreenshots, customZeroTime?: Types.Timing.MicroSeconds): Data {\n const frames: Frame[] = [];\n\n const zeroTime = typeof customZeroTime !== 'undefined' ? customZeroTime : parsedTrace.Meta.traceBounds.min;\n const spanTime = parsedTrace.Meta.traceBounds.range;\n const fromCache = filmStripCache.get(parsedTrace)?.get(zeroTime);\n if (fromCache) {\n return fromCache;\n }\n\n for (const screenshotEvent of parsedTrace.Screenshots.all) {\n if (screenshotEvent.ts < zeroTime) {\n continue;\n }\n const frame: Frame = {\n index: frames.length,\n screenshotEvent,\n };\n frames.push(frame);\n }\n\n const result: Data = {\n zeroTime,\n spanTime,\n frames: Array.from(frames),\n };\n\n const cachedForData = Platform.MapUtilities.getWithDefault(\n filmStripCache, parsedTrace, () => new Map<Types.Timing.MicroSeconds, Data>());\n cachedForData.set(zeroTime, result);\n\n return result;\n}\n\nexport function frameClosestToTimestamp(filmStrip: Data, searchTimestamp: Types.Timing.MicroSeconds): Frame|null {\n const closestFrameIndexBeforeTimestamp = Platform.ArrayUtilities.nearestIndexFromEnd(\n filmStrip.frames, frame => frame.screenshotEvent.ts < searchTimestamp);\n if (closestFrameIndexBeforeTimestamp === null) {\n return null;\n }\n return filmStrip.frames[closestFrameIndexBeforeTimestamp];\n}\n"]}
1
+ {"version":3,"file":"FilmStrip.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/FilmStrip.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAC7B,EAAE;AACF,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAyB/D,8BAA8B;AAC9B,kCAAkC;AAClC,qBAAqB;AACrB,MAAM,cAAc,GAAG,IAAI,OAAO,EAA6D,CAAC;AAEhG,MAAM,UAAU,eAAe,CAAC,WAAuC,EAAE,cAAmC;IAC1G,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,OAAO,cAAc,KAAK,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;IAC3G,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,0BAA0B,IAAI,EAAE,CAAC;IAEpH,KAAK,MAAM,eAAe,IAAI,WAAW,EAAE,CAAC;QAC1C,IAAI,eAAe,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC;YAClC,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAU;YACnB,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,eAAe;SAChB,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,MAAM,GAAS;QACnB,QAAQ;QACR,QAAQ;QACR,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;KAC3B,CAAC;IAEF,MAAM,aAAa,GACf,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,cAAc,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAA4B,CAAC,CAAC;IACjH,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAe,EAAE,eAAmC;IAC1F,MAAM,gCAAgC,GAAG,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAChF,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,gCAAgC,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC;AAC5D,CAAC","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\nimport * as Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport type * as Types from '../types/types.js';\n\nexport interface Data {\n zeroTime: Types.Timing.Micro;\n spanTime: Types.Timing.Micro;\n frames: readonly Frame[];\n}\n\nexport interface Frame {\n screenshotEvent: Types.Events.LegacySyntheticScreenshot|Types.Events.Screenshot;\n index: number;\n}\n\nexport type HandlersWithFilmStrip = Handlers.Types.HandlersWithMeta<{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Screenshots: typeof Handlers.ModelHandlers.Screenshots,\n}>;\n\nexport type HandlerDataWithScreenshots = Handlers.Types.EnabledHandlerDataWithMeta<{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Screenshots: typeof Handlers.ModelHandlers.Screenshots,\n}>;\n\n// Cache film strips based on:\n// 1. The trace parsed data object\n// 2. The start time.\nconst filmStripCache = new WeakMap<HandlerDataWithScreenshots, Map<Types.Timing.Micro, Data>>();\n\nexport function fromParsedTrace(parsedTrace: HandlerDataWithScreenshots, customZeroTime?: Types.Timing.Micro): Data {\n const frames: Frame[] = [];\n\n const zeroTime = typeof customZeroTime !== 'undefined' ? customZeroTime : parsedTrace.Meta.traceBounds.min;\n const spanTime = parsedTrace.Meta.traceBounds.range;\n const fromCache = filmStripCache.get(parsedTrace)?.get(zeroTime);\n if (fromCache) {\n return fromCache;\n }\n\n const screenshots = parsedTrace.Screenshots.screenshots ?? parsedTrace.Screenshots.legacySyntheticScreenshots ?? [];\n\n for (const screenshotEvent of screenshots) {\n if (screenshotEvent.ts < zeroTime) {\n continue;\n }\n const frame: Frame = {\n index: frames.length,\n screenshotEvent,\n };\n frames.push(frame);\n }\n\n const result: Data = {\n zeroTime,\n spanTime,\n frames: Array.from(frames),\n };\n\n const cachedForData =\n Platform.MapUtilities.getWithDefault(filmStripCache, parsedTrace, () => new Map<Types.Timing.Micro, Data>());\n cachedForData.set(zeroTime, result);\n\n return result;\n}\n\nexport function frameClosestToTimestamp(filmStrip: Data, searchTimestamp: Types.Timing.Micro): Frame|null {\n const closestFrameIndexBeforeTimestamp = Platform.ArrayUtilities.nearestIndexFromEnd(\n filmStrip.frames, frame => frame.screenshotEvent.ts < searchTimestamp);\n if (closestFrameIndexBeforeTimestamp === null) {\n return null;\n }\n return filmStrip.frames[closestFrameIndexBeforeTimestamp];\n}\n"]}
@@ -1,2 +1,2 @@
1
1
  import * as Types from '../types/types.js';
2
- export declare function calculateWindow(traceBounds: Types.Timing.TraceWindowMicroSeconds, mainThreadEntries: readonly Types.Events.Event[]): Types.Timing.TraceWindowMicroSeconds;
2
+ export declare function calculateWindow(traceBounds: Types.Timing.TraceWindowMicro, mainThreadEntries: readonly Types.Events.Event[]): Types.Timing.TraceWindowMicro;
@@ -66,12 +66,12 @@ export function calculateWindow(traceBounds, mainThreadEntries) {
66
66
  // we give the range we want to zoom a bit of breathing space. At the
67
67
  // same time, ensure that we do not stray beyond the bounds of the
68
68
  // min/max time of the entire trace.
69
- leftTime = Types.Timing.MicroSeconds(Math.max(leftTime - 0.05 * zoomedInSpan, traceBounds.min));
70
- rightTime = Types.Timing.MicroSeconds(Math.min(rightTime + 0.05 * zoomedInSpan, traceBounds.max));
69
+ leftTime = Types.Timing.Micro(Math.max(leftTime - 0.05 * zoomedInSpan, traceBounds.min));
70
+ rightTime = Types.Timing.Micro(Math.min(rightTime + 0.05 * zoomedInSpan, traceBounds.max));
71
71
  return {
72
72
  min: leftTime,
73
73
  max: rightTime,
74
- range: Types.Timing.MicroSeconds(rightTime - leftTime),
74
+ range: Types.Timing.Micro(rightTime - leftTime),
75
75
  };
76
76
  }
77
77
  //# sourceMappingURL=MainThreadActivity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MainThreadActivity.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/MainThreadActivity.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.\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nconst IDLE_FUNCTION_CALL_NAMES = new Set([\n '(program)',\n '(idle)',\n '(root)',\n]);\n\nexport function calculateWindow(\n traceBounds: Types.Timing.TraceWindowMicroSeconds,\n mainThreadEntries: readonly Types.Events.Event[]): Types.Timing.TraceWindowMicroSeconds {\n if (!mainThreadEntries.length) {\n return traceBounds;\n }\n const entriesWithIdleRemoved = mainThreadEntries.filter(entry => {\n if (Types.Events.isProfileCall(entry) &&\n (IDLE_FUNCTION_CALL_NAMES.has(entry.callFrame.functionName) || !entry.callFrame.functionName)) {\n return false;\n }\n return true;\n });\n\n if (entriesWithIdleRemoved.length === 0) {\n return traceBounds;\n }\n /**\n * Calculates regions of low utilization and returns the index of the event\n * that is the first event that should be included.\n **/\n function findLowUtilizationRegion(startIndex: number, stopIndex: number): number {\n const threshold = 0.1;\n\n let cutIndex = startIndex;\n const entryAtCut = entriesWithIdleRemoved[cutIndex];\n const timings = Helpers.Timing.eventTimingsMicroSeconds(entryAtCut);\n let cutTime = (timings.startTime + timings.endTime) / 2;\n let usedTime = 0;\n const step = Math.sign(stopIndex - startIndex);\n for (let i = startIndex; i !== stopIndex; i += step) {\n const task = entriesWithIdleRemoved[i];\n const taskTimings = Helpers.Timing.eventTimingsMicroSeconds(task);\n const taskTime = (taskTimings.startTime + taskTimings.endTime) / 2;\n const interval = Math.abs(cutTime - taskTime);\n if (usedTime < threshold * interval) {\n cutIndex = i;\n cutTime = taskTime;\n usedTime = 0;\n }\n usedTime += taskTimings.duration;\n }\n return cutIndex;\n }\n const rightIndex = findLowUtilizationRegion(entriesWithIdleRemoved.length - 1, 0);\n const leftIndex = findLowUtilizationRegion(0, rightIndex);\n const leftTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[leftIndex]);\n const rightTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[rightIndex]);\n\n let leftTime = leftTimings.startTime;\n let rightTime = rightTimings.endTime;\n const zoomedInSpan = rightTime - leftTime;\n\n if (zoomedInSpan < traceBounds.range * 0.1) {\n // If the area we have chosen to zoom into is less than 10% of the entire\n // span, we bail and show the entire trace. It would not be so useful to\n // the user to zoom in on such a small area; we assume they have\n // purposefully recorded a trace that contains empty periods of time.\n return traceBounds;\n }\n\n // Adjust the left time down by 5%, and the right time up by 5%, so that\n // we give the range we want to zoom a bit of breathing space. At the\n // same time, ensure that we do not stray beyond the bounds of the\n // min/max time of the entire trace.\n leftTime = Types.Timing.MicroSeconds(Math.max(leftTime - 0.05 * zoomedInSpan, traceBounds.min));\n rightTime = Types.Timing.MicroSeconds(Math.min(rightTime + 0.05 * zoomedInSpan, traceBounds.max));\n\n return {\n min: leftTime,\n max: rightTime,\n range: Types.Timing.MicroSeconds(rightTime - leftTime),\n };\n}\n"]}
1
+ {"version":3,"file":"MainThreadActivity.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/MainThreadActivity.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.\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nconst IDLE_FUNCTION_CALL_NAMES = new Set([\n '(program)',\n '(idle)',\n '(root)',\n]);\n\nexport function calculateWindow(\n traceBounds: Types.Timing.TraceWindowMicro,\n mainThreadEntries: readonly Types.Events.Event[]): Types.Timing.TraceWindowMicro {\n if (!mainThreadEntries.length) {\n return traceBounds;\n }\n const entriesWithIdleRemoved = mainThreadEntries.filter(entry => {\n if (Types.Events.isProfileCall(entry) &&\n (IDLE_FUNCTION_CALL_NAMES.has(entry.callFrame.functionName) || !entry.callFrame.functionName)) {\n return false;\n }\n return true;\n });\n\n if (entriesWithIdleRemoved.length === 0) {\n return traceBounds;\n }\n /**\n * Calculates regions of low utilization and returns the index of the event\n * that is the first event that should be included.\n **/\n function findLowUtilizationRegion(startIndex: number, stopIndex: number): number {\n const threshold = 0.1;\n\n let cutIndex = startIndex;\n const entryAtCut = entriesWithIdleRemoved[cutIndex];\n const timings = Helpers.Timing.eventTimingsMicroSeconds(entryAtCut);\n let cutTime = (timings.startTime + timings.endTime) / 2;\n let usedTime = 0;\n const step = Math.sign(stopIndex - startIndex);\n for (let i = startIndex; i !== stopIndex; i += step) {\n const task = entriesWithIdleRemoved[i];\n const taskTimings = Helpers.Timing.eventTimingsMicroSeconds(task);\n const taskTime = (taskTimings.startTime + taskTimings.endTime) / 2;\n const interval = Math.abs(cutTime - taskTime);\n if (usedTime < threshold * interval) {\n cutIndex = i;\n cutTime = taskTime;\n usedTime = 0;\n }\n usedTime += taskTimings.duration;\n }\n return cutIndex;\n }\n const rightIndex = findLowUtilizationRegion(entriesWithIdleRemoved.length - 1, 0);\n const leftIndex = findLowUtilizationRegion(0, rightIndex);\n const leftTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[leftIndex]);\n const rightTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[rightIndex]);\n\n let leftTime = leftTimings.startTime;\n let rightTime = rightTimings.endTime;\n const zoomedInSpan = rightTime - leftTime;\n\n if (zoomedInSpan < traceBounds.range * 0.1) {\n // If the area we have chosen to zoom into is less than 10% of the entire\n // span, we bail and show the entire trace. It would not be so useful to\n // the user to zoom in on such a small area; we assume they have\n // purposefully recorded a trace that contains empty periods of time.\n return traceBounds;\n }\n\n // Adjust the left time down by 5%, and the right time up by 5%, so that\n // we give the range we want to zoom a bit of breathing space. At the\n // same time, ensure that we do not stray beyond the bounds of the\n // min/max time of the entire trace.\n leftTime = Types.Timing.Micro(Math.max(leftTime - 0.05 * zoomedInSpan, traceBounds.min));\n rightTime = Types.Timing.Micro(Math.min(rightTime + 0.05 * zoomedInSpan, traceBounds.max));\n\n return {\n min: leftTime,\n max: rightTime,\n range: Types.Timing.Micro(rightTime - leftTime),\n };\n}\n"]}
@@ -4,23 +4,24 @@ import * as Types from '../types/types.js';
4
4
  export type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number];
5
5
  export interface Summary {
6
6
  transferSize: number;
7
- mainThreadTime: Types.Timing.MicroSeconds;
7
+ mainThreadTime: Types.Timing.Micro;
8
8
  }
9
- export interface SummaryMaps {
9
+ export interface ThirdPartySummary {
10
10
  byEntity: Map<Entity, Summary>;
11
11
  byEvent: Map<Types.Events.Event, Summary>;
12
12
  eventsByEntity: Map<Entity, Types.Events.Event[]>;
13
- }
14
- export declare function getEntitiesByRequest(requests: Types.Events.SyntheticNetworkRequest[]): {
15
- entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>;
16
- madeUpEntityCache: Map<string, Entity>;
17
- };
18
- export declare function getSummariesAndEntitiesForTraceBounds(parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicroSeconds, networkRequests: Types.Events.SyntheticNetworkRequest[]): {
19
- summaries: SummaryMaps;
20
- entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>;
21
13
  madeUpEntityCache: Map<string, Entity>;
22
- };
23
- export declare function getSummariesAndEntitiesWithMapping(parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicroSeconds, entityMapping: Handlers.Helpers.EntityMappings): {
24
- summaries: SummaryMaps;
14
+ }
15
+ /**
16
+ * @param networkRequests Won't be filtered by trace bounds, so callers should ensure it is filtered.
17
+ */
18
+ export declare function summarizeThirdParties(parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicro, networkRequests: Types.Events.SyntheticNetworkRequest[]): ThirdPartySummary;
19
+ /**
20
+ * Note: unlike summarizeThirdParties, this does not calculate mainThreadTime. The reason is that it is not
21
+ * needed for its one use case, and when dragging the trace bounds it takes a long time to calculate.
22
+ * If it is ever needed, we need to make getSelfTimeByUrl (see deleted code/blame) much faster (cache + bucket?).
23
+ */
24
+ export declare function getSummariesAndEntitiesWithMapping(parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicro, entityMapping: Handlers.Helpers.EntityMappings): {
25
+ summaries: ThirdPartySummary;
25
26
  entityByEvent: Map<Types.Events.Event, Handlers.Helpers.Entity>;
26
27
  };
@@ -5,8 +5,26 @@ import * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party
5
5
  import * as Handlers from '../handlers/handlers.js';
6
6
  import * as Helpers from '../helpers/helpers.js';
7
7
  import * as Types from '../types/types.js';
8
- function getSelfTimeByUrl(parsedTrace, bounds) {
9
- const selfTimeByUrl = new Map();
8
+ function getOrMakeSummary(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 events = thirdPartySummary.eventsByEntity.get(entity) ?? [];
15
+ events.push(event);
16
+ thirdPartySummary.eventsByEntity.set(entity, events);
17
+ let summary = thirdPartySummary.byEntity.get(entity);
18
+ if (summary) {
19
+ thirdPartySummary.byEvent.set(event, summary);
20
+ return summary;
21
+ }
22
+ summary = { transferSize: 0, mainThreadTime: Types.Timing.Micro(0) };
23
+ thirdPartySummary.byEntity.set(entity, summary);
24
+ thirdPartySummary.byEvent.set(event, summary);
25
+ return summary;
26
+ }
27
+ function collectMainThreadActivity(thirdPartySummary, parsedTrace, bounds) {
10
28
  for (const process of parsedTrace.Renderer.processes.values()) {
11
29
  if (!process.isOnMainFrame) {
12
30
  continue;
@@ -28,77 +46,47 @@ function getSelfTimeByUrl(parsedTrace, bounds) {
28
46
  if (!url) {
29
47
  continue;
30
48
  }
31
- selfTimeByUrl.set(url, node.selfTime + (selfTimeByUrl.get(url) ?? 0));
49
+ const summary = getOrMakeSummary(thirdPartySummary, event, url);
50
+ if (summary) {
51
+ summary.mainThreadTime = (summary.mainThreadTime + node.selfTime);
52
+ }
32
53
  }
33
54
  }
34
55
  }
35
56
  }
36
- return selfTimeByUrl;
37
57
  }
38
- export function getEntitiesByRequest(requests) {
39
- const entityByRequest = new Map();
40
- const madeUpEntityCache = new Map();
58
+ function collectNetworkActivity(thirdPartySummary, requests) {
41
59
  for (const request of requests) {
42
60
  const url = request.args.data.url;
43
- const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? Handlers.Helpers.makeUpEntity(madeUpEntityCache, url);
44
- if (entity) {
45
- entityByRequest.set(request, entity);
46
- }
47
- }
48
- return { entityByRequest, madeUpEntityCache };
49
- }
50
- function getSummaryMap(requests, entityByRequest, selfTimeByUrl) {
51
- const byRequest = new Map();
52
- const byEntity = new Map();
53
- const defaultSummary = { transferSize: 0, mainThreadTime: Types.Timing.MicroSeconds(0) };
54
- for (const request of requests) {
55
- const urlSummary = byRequest.get(request) || { ...defaultSummary };
56
- urlSummary.transferSize += request.args.data.encodedDataLength;
57
- urlSummary.mainThreadTime =
58
- Types.Timing.MicroSeconds(urlSummary.mainThreadTime + (selfTimeByUrl.get(request.args.data.url) ?? 0));
59
- byRequest.set(request, urlSummary);
60
- }
61
- // Map each request's stat to a particular entity.
62
- const requestsByEntity = new Map();
63
- for (const [request, requestSummary] of byRequest.entries()) {
64
- const entity = entityByRequest.get(request);
65
- if (!entity) {
66
- byRequest.delete(request);
67
- continue;
61
+ const summary = getOrMakeSummary(thirdPartySummary, request, url);
62
+ if (summary) {
63
+ summary.transferSize += request.args.data.encodedDataLength;
68
64
  }
69
- const entitySummary = byEntity.get(entity) || { ...defaultSummary };
70
- entitySummary.transferSize += requestSummary.transferSize;
71
- entitySummary.mainThreadTime =
72
- Types.Timing.MicroSeconds(entitySummary.mainThreadTime + requestSummary.mainThreadTime);
73
- byEntity.set(entity, entitySummary);
74
- const entityRequests = requestsByEntity.get(entity) || [];
75
- entityRequests.push(request);
76
- requestsByEntity.set(entity, entityRequests);
77
65
  }
78
- return { byEntity, byEvent: byRequest, eventsByEntity: requestsByEntity };
79
66
  }
80
- export function getSummariesAndEntitiesForTraceBounds(parsedTrace, traceBounds, networkRequests) {
81
- // Ensure we only handle requests that are within the given traceBounds.
82
- const reqs = networkRequests.filter(event => {
83
- return Helpers.Timing.eventIsInBounds(event, traceBounds);
84
- });
85
- const { entityByRequest, madeUpEntityCache } = getEntitiesByRequest(reqs);
86
- const selfTimeByUrl = getSelfTimeByUrl(parsedTrace, traceBounds);
87
- // TODO(crbug.com/352244718): re-work to still collect main thread activity if no request is present
88
- const summaries = getSummaryMap(reqs, entityByRequest, selfTimeByUrl);
89
- return { summaries, entityByRequest, madeUpEntityCache };
67
+ /**
68
+ * @param networkRequests Won't be filtered by trace bounds, so callers should ensure it is filtered.
69
+ */
70
+ export function summarizeThirdParties(parsedTrace, traceBounds, networkRequests) {
71
+ const thirdPartySummary = {
72
+ byEntity: new Map(),
73
+ byEvent: new Map(),
74
+ eventsByEntity: new Map(),
75
+ madeUpEntityCache: new Map(),
76
+ };
77
+ collectMainThreadActivity(thirdPartySummary, parsedTrace, traceBounds);
78
+ collectNetworkActivity(thirdPartySummary, networkRequests);
79
+ return thirdPartySummary;
90
80
  }
91
- function getSummaryMapWithMapping(events, entityByEvent, selfTimeByUrl, eventsByEntity, parsedTrace) {
81
+ function getSummaryMapWithMapping(events, entityByEvent, eventsByEntity) {
92
82
  const byEvent = new Map();
93
83
  const byEntity = new Map();
94
- const defaultSummary = { transferSize: 0, mainThreadTime: Types.Timing.MicroSeconds(0) };
84
+ const defaultSummary = { transferSize: 0, mainThreadTime: Types.Timing.Micro(0) };
95
85
  for (const event of events) {
96
- const url = Handlers.Helpers.getNonResolvedURL(event, parsedTrace) ?? '';
97
86
  const urlSummary = byEvent.get(event) || { ...defaultSummary };
98
87
  if (Types.Events.isSyntheticNetworkRequest(event)) {
99
88
  urlSummary.transferSize += event.args.data.encodedDataLength;
100
89
  }
101
- urlSummary.mainThreadTime = Types.Timing.MicroSeconds(urlSummary.mainThreadTime + (selfTimeByUrl.get(url) ?? 0));
102
90
  byEvent.set(event, urlSummary);
103
91
  }
104
92
  // Map each request's stat to a particular entity.
@@ -110,12 +98,16 @@ function getSummaryMapWithMapping(events, entityByEvent, selfTimeByUrl, eventsBy
110
98
  }
111
99
  const entitySummary = byEntity.get(entity) || { ...defaultSummary };
112
100
  entitySummary.transferSize += requestSummary.transferSize;
113
- entitySummary.mainThreadTime =
114
- Types.Timing.MicroSeconds(entitySummary.mainThreadTime + requestSummary.mainThreadTime);
115
101
  byEntity.set(entity, entitySummary);
116
102
  }
117
- return { byEntity, byEvent, eventsByEntity };
103
+ return { byEntity, byEvent, eventsByEntity, madeUpEntityCache: new Map() };
118
104
  }
105
+ // TODO(crbug.com/352244718): Remove or refactor to use summarizeThirdParties/collectMainThreadActivity/etc.
106
+ /**
107
+ * Note: unlike summarizeThirdParties, this does not calculate mainThreadTime. The reason is that it is not
108
+ * needed for its one use case, and when dragging the trace bounds it takes a long time to calculate.
109
+ * If it is ever needed, we need to make getSelfTimeByUrl (see deleted code/blame) much faster (cache + bucket?).
110
+ */
119
111
  export function getSummariesAndEntitiesWithMapping(parsedTrace, traceBounds, entityMapping) {
120
112
  const entityByEvent = new Map(entityMapping.entityByEvent);
121
113
  const eventsByEntity = new Map(entityMapping.eventsByEntity);
@@ -135,9 +127,7 @@ export function getSummariesAndEntitiesWithMapping(parsedTrace, traceBounds, ent
135
127
  });
136
128
  const eventsByEntityFiltered = new Map(filtered);
137
129
  const allEvents = Array.from(entityByEvent.keys());
138
- const selfTimeByUrl = getSelfTimeByUrl(parsedTrace, traceBounds);
139
- // TODO(crbug.com/352244718): re-work to still collect main thread activity if no request is present
140
- const summaries = getSummaryMapWithMapping(allEvents, entityByEventFiltered, selfTimeByUrl, eventsByEntityFiltered, parsedTrace);
130
+ const summaries = getSummaryMapWithMapping(allEvents, entityByEventFiltered, eventsByEntityFiltered);
141
131
  return { summaries, entityByEvent: entityByEventFiltered };
142
132
  }
143
133
  //# 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.MicroSeconds;\n}\n\nexport interface SummaryMaps {\n byEntity: Map<Entity, Summary>;\n byEvent: Map<Types.Events.Event, Summary>;\n eventsByEntity: Map<Entity, Types.Events.Event[]>;\n}\n\nfunction getSelfTimeByUrl(\n parsedTrace: Handlers.Types.ParsedTrace, bounds: Types.Timing.TraceWindowMicroSeconds): Map<string, number> {\n const selfTimeByUrl = new Map<string, number>();\n\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 as Handlers.Types.ParsedTrace);\n if (!url) {\n continue;\n }\n\n selfTimeByUrl.set(url, node.selfTime + (selfTimeByUrl.get(url) ?? 0));\n }\n }\n }\n }\n\n return selfTimeByUrl;\n}\n\nexport function getEntitiesByRequest(requests: Types.Events.SyntheticNetworkRequest[]):\n {entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>, madeUpEntityCache: Map<string, Entity>} {\n const entityByRequest = new Map<Types.Events.SyntheticNetworkRequest, Entity>();\n const madeUpEntityCache = new Map<string, Entity>();\n for (const request of requests) {\n const url = request.args.data.url;\n const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? Handlers.Helpers.makeUpEntity(madeUpEntityCache, url);\n if (entity) {\n entityByRequest.set(request, entity);\n }\n }\n return {entityByRequest, madeUpEntityCache};\n}\n\nfunction getSummaryMap(\n requests: Types.Events.SyntheticNetworkRequest[],\n entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>,\n selfTimeByUrl: Map<string, number>): SummaryMaps {\n const byRequest = new Map<Types.Events.SyntheticNetworkRequest, Summary>();\n const byEntity = new Map<Entity, Summary>();\n const defaultSummary: Summary = {transferSize: 0, mainThreadTime: Types.Timing.MicroSeconds(0)};\n\n for (const request of requests) {\n const urlSummary = byRequest.get(request) || {...defaultSummary};\n urlSummary.transferSize += request.args.data.encodedDataLength;\n urlSummary.mainThreadTime =\n Types.Timing.MicroSeconds(urlSummary.mainThreadTime + (selfTimeByUrl.get(request.args.data.url) ?? 0));\n byRequest.set(request, urlSummary);\n }\n\n // Map each request's stat to a particular entity.\n const requestsByEntity = new Map<Entity, Types.Events.SyntheticNetworkRequest[]>();\n for (const [request, requestSummary] of byRequest.entries()) {\n const entity = entityByRequest.get(request);\n if (!entity) {\n byRequest.delete(request);\n continue;\n }\n\n const entitySummary = byEntity.get(entity) || {...defaultSummary};\n entitySummary.transferSize += requestSummary.transferSize;\n entitySummary.mainThreadTime =\n Types.Timing.MicroSeconds(entitySummary.mainThreadTime + requestSummary.mainThreadTime);\n byEntity.set(entity, entitySummary);\n\n const entityRequests = requestsByEntity.get(entity) || [];\n entityRequests.push(request);\n requestsByEntity.set(entity, entityRequests);\n }\n\n return {byEntity, byEvent: byRequest, eventsByEntity: requestsByEntity};\n}\n\nexport function getSummariesAndEntitiesForTraceBounds(\n parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicroSeconds,\n networkRequests: Types.Events.SyntheticNetworkRequest[]): {\n summaries: SummaryMaps,\n entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>,\n madeUpEntityCache: Map<string, Entity>,\n} {\n // Ensure we only handle requests that are within the given traceBounds.\n const reqs = networkRequests.filter(event => {\n return Helpers.Timing.eventIsInBounds(event, traceBounds);\n });\n\n const {entityByRequest, madeUpEntityCache} = getEntitiesByRequest(reqs);\n\n const selfTimeByUrl = getSelfTimeByUrl(parsedTrace, traceBounds);\n // TODO(crbug.com/352244718): re-work to still collect main thread activity if no request is present\n const summaries = getSummaryMap(reqs, entityByRequest, selfTimeByUrl);\n\n return {summaries, entityByRequest, madeUpEntityCache};\n}\n\nfunction getSummaryMapWithMapping(\n events: Types.Events.Event[], entityByEvent: Map<Types.Events.Event, Handlers.Helpers.Entity>,\n selfTimeByUrl: Map<string, number>, eventsByEntity: Map<Handlers.Helpers.Entity, Types.Events.Event[]>,\n parsedTrace: Handlers.Types.ParsedTrace): SummaryMaps {\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.MicroSeconds(0)};\n\n for (const event of events) {\n const url = Handlers.Helpers.getNonResolvedURL(event, parsedTrace) ?? '';\n const urlSummary = byEvent.get(event) || {...defaultSummary};\n if (Types.Events.isSyntheticNetworkRequest(event)) {\n urlSummary.transferSize += event.args.data.encodedDataLength;\n }\n urlSummary.mainThreadTime = Types.Timing.MicroSeconds(urlSummary.mainThreadTime + (selfTimeByUrl.get(url) ?? 0));\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 entitySummary.mainThreadTime =\n Types.Timing.MicroSeconds(entitySummary.mainThreadTime + requestSummary.mainThreadTime);\n byEntity.set(entity, entitySummary);\n }\n\n return {byEntity, byEvent, eventsByEntity};\n}\n\nexport function getSummariesAndEntitiesWithMapping(\n parsedTrace: Handlers.Types.ParsedTrace, traceBounds: Types.Timing.TraceWindowMicroSeconds,\n entityMapping: Handlers.Helpers.EntityMappings): {\n summaries: SummaryMaps,\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 selfTimeByUrl = getSelfTimeByUrl(parsedTrace, traceBounds);\n // TODO(crbug.com/352244718): re-work to still collect main thread activity if no request is present\n const summaries =\n getSummaryMapWithMapping(allEvents, entityByEventFiltered, selfTimeByUrl, eventsByEntityFiltered, parsedTrace);\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 * 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 byEvent: Map<Types.Events.Event, Summary>;\n eventsByEntity: Map<Entity, Types.Events.Event[]>;\n madeUpEntityCache: Map<string, Entity>;\n}\n\nfunction getOrMakeSummary(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 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 thirdPartySummary.byEvent.set(event, summary);\n return summary;\n }\n\n summary = {transferSize: 0, mainThreadTime: Types.Timing.Micro(0)};\n thirdPartySummary.byEntity.set(entity, summary);\n thirdPartySummary.byEvent.set(event, summary);\n return summary;\n}\n\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 as Handlers.Types.ParsedTrace);\n if (!url) {\n continue;\n }\n\n const summary = getOrMakeSummary(thirdPartySummary, event, 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 const summary = getOrMakeSummary(thirdPartySummary, request, 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 byEvent: 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, byEvent, eventsByEntity, madeUpEntityCache: 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"]}
@@ -3,7 +3,7 @@ import * as Types from '../types/types.js';
3
3
  export declare class TimelineJSProfileProcessor {
4
4
  static isNativeRuntimeFrame(frame: Protocol.Runtime.CallFrame): boolean;
5
5
  static nativeGroup(nativeName: string): string | null;
6
- static createFakeTraceFromCpuProfile(profile: Protocol.Profiler.Profile, tid: Types.Events.ThreadID): Types.Events.Event[];
6
+ static createFakeTraceFromCpuProfile(profile: Protocol.Profiler.Profile, tid: Types.Events.ThreadID): Types.File.TraceFile;
7
7
  }
8
8
  export declare namespace TimelineJSProfileProcessor {
9
9
  const enum NativeGroups {