@paulirish/trace_engine 0.0.59 → 0.0.61

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 (452) hide show
  1. package/.tmp/tsbuildinfo/analyze-trace.d.mts +2 -3
  2. package/.tmp/tsbuildinfo/analyze-trace.d.mts.map +1 -1
  3. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  4. package/LICENSE +1 -1
  5. package/README.md +28 -1
  6. package/analyze-trace.mjs +5 -3
  7. package/core/platform/ArrayUtilities.d.ts +1 -0
  8. package/core/platform/ArrayUtilities.js +2 -2
  9. package/core/platform/ArrayUtilities.js.map +1 -1
  10. package/core/platform/Brand.js +1 -1
  11. package/core/platform/Brand.js.map +1 -1
  12. package/core/platform/Constructor.js +1 -1
  13. package/core/platform/Constructor.js.map +1 -1
  14. package/core/platform/DOMUtilities.js +1 -1
  15. package/core/platform/DOMUtilities.js.map +1 -1
  16. package/core/platform/DateUtilities.js +1 -1
  17. package/core/platform/DateUtilities.js.map +1 -1
  18. package/core/platform/DevToolsPath.js +1 -1
  19. package/core/platform/DevToolsPath.js.map +1 -1
  20. package/core/platform/KeyboardUtilities.js +1 -1
  21. package/core/platform/KeyboardUtilities.js.map +1 -1
  22. package/core/platform/MapUtilities.js +1 -1
  23. package/core/platform/MapUtilities.js.map +1 -1
  24. package/core/platform/MimeType.js +1 -1
  25. package/core/platform/MimeType.js.map +1 -1
  26. package/core/platform/NumberUtilities.js +1 -1
  27. package/core/platform/NumberUtilities.js.map +1 -1
  28. package/core/platform/StringUtilities.d.ts +2 -1
  29. package/core/platform/StringUtilities.js +34 -32
  30. package/core/platform/StringUtilities.js.map +1 -1
  31. package/core/platform/Timing.js +1 -1
  32. package/core/platform/Timing.js.map +1 -1
  33. package/core/platform/TypedArrayUtilities.js +1 -1
  34. package/core/platform/TypedArrayUtilities.js.map +1 -1
  35. package/core/platform/TypescriptUtilities.js +1 -1
  36. package/core/platform/TypescriptUtilities.js.map +1 -1
  37. package/core/platform/UIString.js +1 -1
  38. package/core/platform/UIString.js.map +1 -1
  39. package/core/platform/UserVisibleError.js +1 -1
  40. package/core/platform/UserVisibleError.js.map +1 -1
  41. package/core/platform/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  42. package/core/platform/platform-tsconfig.json +6 -2
  43. package/core/platform/platform.js +3 -29
  44. package/core/platform/platform.js.map +1 -1
  45. package/generated/protocol.d.ts +188 -15
  46. package/generated/protocol.js +1 -1
  47. package/locales/af.json +3 -3
  48. package/locales/am.json +4 -4
  49. package/locales/ar.json +14 -14
  50. package/locales/as.json +3 -3
  51. package/locales/az.json +4 -4
  52. package/locales/be.json +3 -3
  53. package/locales/bg.json +3 -3
  54. package/locales/bn.json +4 -4
  55. package/locales/bs.json +4 -4
  56. package/locales/ca.json +3 -3
  57. package/locales/cs.json +3 -3
  58. package/locales/cy.json +4 -4
  59. package/locales/da.json +3 -3
  60. package/locales/de.json +3 -3
  61. package/locales/el.json +3 -3
  62. package/locales/en-GB.json +3 -3
  63. package/locales/en-US.json +26 -26
  64. package/locales/en-XL.json +26 -26
  65. package/locales/es-419.json +3 -3
  66. package/locales/es.json +3 -3
  67. package/locales/et.json +3 -3
  68. package/locales/eu.json +4 -4
  69. package/locales/fa.json +5 -5
  70. package/locales/fi.json +3 -3
  71. package/locales/fil.json +3 -3
  72. package/locales/fr-CA.json +4 -4
  73. package/locales/fr.json +3 -3
  74. package/locales/gl.json +3 -3
  75. package/locales/gu.json +3 -3
  76. package/locales/he.json +26 -26
  77. package/locales/hi.json +3 -3
  78. package/locales/hr.json +7 -7
  79. package/locales/hu.json +3 -3
  80. package/locales/hy.json +3 -3
  81. package/locales/id.json +3 -3
  82. package/locales/is.json +3 -3
  83. package/locales/it.json +3 -3
  84. package/locales/ja.json +3 -3
  85. package/locales/ka.json +4 -4
  86. package/locales/kk.json +3 -3
  87. package/locales/km.json +4 -4
  88. package/locales/kn.json +5 -5
  89. package/locales/ko.json +4 -4
  90. package/locales/ky.json +3 -3
  91. package/locales/lo.json +4 -4
  92. package/locales/lt.json +3 -3
  93. package/locales/lv.json +4 -4
  94. package/locales/mk.json +3 -3
  95. package/locales/ml.json +5 -5
  96. package/locales/mn.json +3 -3
  97. package/locales/mr.json +3 -3
  98. package/locales/ms.json +3 -3
  99. package/locales/my.json +6 -6
  100. package/locales/ne.json +25 -25
  101. package/locales/nl.json +3 -3
  102. package/locales/no.json +3 -3
  103. package/locales/or.json +3 -3
  104. package/locales/pa.json +3 -3
  105. package/locales/pl.json +3 -3
  106. package/locales/pt-PT.json +3 -3
  107. package/locales/pt.json +3 -3
  108. package/locales/ro.json +4 -4
  109. package/locales/ru.json +3 -3
  110. package/locales/si.json +4 -4
  111. package/locales/sk.json +3 -3
  112. package/locales/sl.json +3 -3
  113. package/locales/sq.json +4 -4
  114. package/locales/sr-Latn.json +3 -3
  115. package/locales/sr.json +3 -3
  116. package/locales/sv.json +3 -3
  117. package/locales/sw.json +3 -3
  118. package/locales/ta.json +3 -3
  119. package/locales/te.json +4 -4
  120. package/locales/th.json +3 -3
  121. package/locales/tr.json +3 -3
  122. package/locales/uk.json +3 -3
  123. package/locales/ur.json +4 -4
  124. package/locales/uz.json +3 -3
  125. package/locales/vi.json +3 -3
  126. package/locales/zh-HK.json +3 -3
  127. package/locales/zh-TW.json +4 -4
  128. package/locales/zh.json +3 -3
  129. package/locales/zu.json +3 -3
  130. package/models/cpu_profile/CPUProfileDataModel.d.ts +1 -0
  131. package/models/cpu_profile/CPUProfileDataModel.js +1 -1
  132. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
  133. package/models/cpu_profile/ProfileTreeModel.d.ts +1 -1
  134. package/models/cpu_profile/ProfileTreeModel.js +1 -1
  135. package/models/cpu_profile/ProfileTreeModel.js.map +1 -1
  136. package/models/cpu_profile/cpu_profile-tsconfig.json +6 -2
  137. package/models/cpu_profile/cpu_profile.js +1 -1
  138. package/models/cpu_profile/cpu_profile.js.map +1 -1
  139. package/models/cpu_profile/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  140. package/models/trace/EntityMapper.d.ts +33 -0
  141. package/models/trace/EntityMapper.js +123 -0
  142. package/models/trace/EntityMapper.js.map +1 -0
  143. package/models/trace/EventsSerializer.d.ts +11 -0
  144. package/models/trace/EventsSerializer.js +82 -0
  145. package/models/trace/EventsSerializer.js.map +1 -0
  146. package/models/trace/LanternComputationData.d.ts +3 -3
  147. package/models/trace/LanternComputationData.js +11 -10
  148. package/models/trace/LanternComputationData.js.map +1 -1
  149. package/models/trace/ModelImpl.d.ts +7 -14
  150. package/models/trace/ModelImpl.js +25 -52
  151. package/models/trace/ModelImpl.js.map +1 -1
  152. package/models/trace/Name.d.ts +12 -0
  153. package/models/trace/Name.js +115 -0
  154. package/models/trace/Name.js.map +1 -0
  155. package/models/trace/Processor.d.ts +1 -1
  156. package/models/trace/Processor.js +42 -61
  157. package/models/trace/Processor.js.map +1 -1
  158. package/models/trace/Styles.d.ts +50 -0
  159. package/models/trace/Styles.js +816 -0
  160. package/models/trace/Styles.js.map +1 -0
  161. package/models/trace/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  162. package/models/trace/extras/FilmStrip.d.ts +1 -1
  163. package/models/trace/extras/FilmStrip.js +7 -7
  164. package/models/trace/extras/FilmStrip.js.map +1 -1
  165. package/models/trace/extras/MainThreadActivity.js +1 -1
  166. package/models/trace/extras/MainThreadActivity.js.map +1 -1
  167. package/models/trace/extras/ScriptDuplication.js +1 -1
  168. package/models/trace/extras/ScriptDuplication.js.map +1 -1
  169. package/models/trace/extras/StackTraceForEvent.d.ts +2 -2
  170. package/models/trace/extras/StackTraceForEvent.js +21 -21
  171. package/models/trace/extras/StackTraceForEvent.js.map +1 -1
  172. package/models/trace/extras/ThirdParties.d.ts +2 -2
  173. package/models/trace/extras/ThirdParties.js +17 -17
  174. package/models/trace/extras/ThirdParties.js.map +1 -1
  175. package/models/trace/extras/TraceFilter.d.ts +1 -1
  176. package/models/trace/extras/TraceFilter.js +1 -1
  177. package/models/trace/extras/TraceFilter.js.map +1 -1
  178. package/models/trace/extras/TraceTree.d.ts +1 -0
  179. package/models/trace/extras/TraceTree.js +2 -2
  180. package/models/trace/extras/TraceTree.js.map +1 -1
  181. package/models/trace/extras/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  182. package/models/trace/extras/extras-tsconfig.json +6 -2
  183. package/models/trace/extras/extras.d.ts +0 -3978
  184. package/models/trace/extras/extras.js +0 -3978
  185. package/models/trace/extras/extras.js.map +1 -1
  186. package/models/trace/handlers/AnimationFramesHandler.js +11 -11
  187. package/models/trace/handlers/AnimationFramesHandler.js.map +1 -1
  188. package/models/trace/handlers/AnimationHandler.js +5 -5
  189. package/models/trace/handlers/AnimationHandler.js.map +1 -1
  190. package/models/trace/handlers/AsyncJSCallsHandler.d.ts +3 -3
  191. package/models/trace/handlers/AsyncJSCallsHandler.js +9 -9
  192. package/models/trace/handlers/AsyncJSCallsHandler.js.map +1 -1
  193. package/models/trace/handlers/AuctionWorkletsHandler.js +12 -12
  194. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
  195. package/models/trace/handlers/DOMStatsHandler.js +3 -3
  196. package/models/trace/handlers/DOMStatsHandler.js.map +1 -1
  197. package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +15 -2
  198. package/models/trace/handlers/ExtensionTraceDataHandler.js +53 -41
  199. package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
  200. package/models/trace/handlers/FlowsHandler.js +11 -11
  201. package/models/trace/handlers/FlowsHandler.js.map +1 -1
  202. package/models/trace/handlers/FramesHandler.d.ts +7 -0
  203. package/models/trace/handlers/FramesHandler.js +12 -10
  204. package/models/trace/handlers/FramesHandler.js.map +1 -1
  205. package/models/trace/handlers/GPUHandler.js +3 -3
  206. package/models/trace/handlers/GPUHandler.js.map +1 -1
  207. package/models/trace/handlers/ImagePaintingHandler.js +13 -13
  208. package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
  209. package/models/trace/handlers/InitiatorsHandler.js +32 -41
  210. package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
  211. package/models/trace/handlers/InvalidationsHandler.js +63 -44
  212. package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
  213. package/models/trace/handlers/LargestImagePaintHandler.js +5 -4
  214. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -1
  215. package/models/trace/handlers/LargestTextPaintHandler.js +3 -3
  216. package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -1
  217. package/models/trace/handlers/LayerTreeHandler.js +11 -11
  218. package/models/trace/handlers/LayerTreeHandler.js.map +1 -1
  219. package/models/trace/handlers/LayoutShiftsHandler.d.ts +17 -4
  220. package/models/trace/handlers/LayoutShiftsHandler.js +41 -38
  221. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
  222. package/models/trace/handlers/MemoryHandler.js +3 -3
  223. package/models/trace/handlers/MemoryHandler.js.map +1 -1
  224. package/models/trace/handlers/MetaHandler.d.ts +16 -0
  225. package/models/trace/handlers/MetaHandler.js +29 -28
  226. package/models/trace/handlers/MetaHandler.js.map +1 -1
  227. package/models/trace/handlers/ModelHandlers.js +1 -1
  228. package/models/trace/handlers/ModelHandlers.js.map +1 -1
  229. package/models/trace/handlers/NetworkRequestsHandler.d.ts +10 -0
  230. package/models/trace/handlers/NetworkRequestsHandler.js +44 -25
  231. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  232. package/models/trace/handlers/PageFramesHandler.js +3 -3
  233. package/models/trace/handlers/PageFramesHandler.js.map +1 -1
  234. package/models/trace/handlers/PageLoadMetricsHandler.js +5 -5
  235. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
  236. package/models/trace/handlers/RendererHandler.d.ts +1 -1
  237. package/models/trace/handlers/RendererHandler.js +22 -22
  238. package/models/trace/handlers/RendererHandler.js.map +1 -1
  239. package/models/trace/handlers/SamplesHandler.d.ts +2 -2
  240. package/models/trace/handlers/SamplesHandler.js +7 -9
  241. package/models/trace/handlers/SamplesHandler.js.map +1 -1
  242. package/models/trace/handlers/ScreenshotsHandler.js +9 -10
  243. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
  244. package/models/trace/handlers/ScriptsHandler.js +9 -8
  245. package/models/trace/handlers/ScriptsHandler.js.map +1 -1
  246. package/models/trace/handlers/SelectorStatsHandler.d.ts +2 -2
  247. package/models/trace/handlers/SelectorStatsHandler.js +13 -13
  248. package/models/trace/handlers/SelectorStatsHandler.js.map +1 -1
  249. package/models/trace/handlers/Threads.d.ts +2 -2
  250. package/models/trace/handlers/Threads.js +9 -9
  251. package/models/trace/handlers/Threads.js.map +1 -1
  252. package/models/trace/handlers/UserInteractionsHandler.d.ts +10 -3
  253. package/models/trace/handlers/UserInteractionsHandler.js +104 -84
  254. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
  255. package/models/trace/handlers/UserTimingsHandler.d.ts +1 -1
  256. package/models/trace/handlers/UserTimingsHandler.js +16 -17
  257. package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
  258. package/models/trace/handlers/WarningsHandler.js +14 -14
  259. package/models/trace/handlers/WarningsHandler.js.map +1 -1
  260. package/models/trace/handlers/WorkersHandler.js +7 -7
  261. package/models/trace/handlers/WorkersHandler.js.map +1 -1
  262. package/models/trace/handlers/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  263. package/models/trace/handlers/handlers-tsconfig.json +6 -2
  264. package/models/trace/handlers/handlers.js +1 -1
  265. package/models/trace/handlers/handlers.js.map +1 -1
  266. package/models/trace/handlers/helpers.d.ts +3 -2
  267. package/models/trace/handlers/helpers.js +10 -10
  268. package/models/trace/handlers/helpers.js.map +1 -1
  269. package/models/trace/handlers/types.d.ts +25 -2
  270. package/models/trace/handlers/types.js.map +1 -1
  271. package/models/trace/helpers/Extensions.js +8 -8
  272. package/models/trace/helpers/Extensions.js.map +1 -1
  273. package/models/trace/helpers/Network.js.map +1 -1
  274. package/models/trace/helpers/SamplesIntegrator.js +11 -9
  275. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  276. package/models/trace/helpers/SyntheticEvents.js +1 -1
  277. package/models/trace/helpers/SyntheticEvents.js.map +1 -1
  278. package/models/trace/helpers/Timing.d.ts +4 -0
  279. package/models/trace/helpers/Timing.js +6 -4
  280. package/models/trace/helpers/Timing.js.map +1 -1
  281. package/models/trace/helpers/Trace.d.ts +19 -20
  282. package/models/trace/helpers/Trace.js +148 -60
  283. package/models/trace/helpers/Trace.js.map +1 -1
  284. package/models/trace/helpers/TreeHelpers.js +1 -1
  285. package/models/trace/helpers/TreeHelpers.js.map +1 -1
  286. package/models/trace/helpers/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  287. package/models/trace/helpers/helpers-tsconfig.json +6 -2
  288. package/models/trace/helpers/helpers.js +1 -1
  289. package/models/trace/helpers/helpers.js.map +1 -1
  290. package/models/trace/insights/CLSCulprits.d.ts +3 -3
  291. package/models/trace/insights/CLSCulprits.js +16 -15
  292. package/models/trace/insights/CLSCulprits.js.map +1 -1
  293. package/models/trace/insights/Cache.d.ts +3 -2
  294. package/models/trace/insights/Cache.js +10 -6
  295. package/models/trace/insights/Cache.js.map +1 -1
  296. package/models/trace/insights/Common.d.ts +8 -1
  297. package/models/trace/insights/Common.js +16 -1
  298. package/models/trace/insights/Common.js.map +1 -1
  299. package/models/trace/insights/DOMSize.d.ts +4 -3
  300. package/models/trace/insights/DOMSize.js +12 -8
  301. package/models/trace/insights/DOMSize.js.map +1 -1
  302. package/models/trace/insights/DocumentLatency.d.ts +3 -3
  303. package/models/trace/insights/DocumentLatency.js +20 -18
  304. package/models/trace/insights/DocumentLatency.js.map +1 -1
  305. package/models/trace/insights/DuplicatedJavaScript.d.ts +3 -3
  306. package/models/trace/insights/DuplicatedJavaScript.js +7 -6
  307. package/models/trace/insights/DuplicatedJavaScript.js.map +1 -1
  308. package/models/trace/insights/FontDisplay.d.ts +3 -2
  309. package/models/trace/insights/FontDisplay.js +9 -5
  310. package/models/trace/insights/FontDisplay.js.map +1 -1
  311. package/models/trace/insights/ForcedReflow.d.ts +3 -2
  312. package/models/trace/insights/ForcedReflow.js +8 -4
  313. package/models/trace/insights/ForcedReflow.js.map +1 -1
  314. package/models/trace/insights/INPBreakdown.d.ts +4 -4
  315. package/models/trace/insights/INPBreakdown.js +18 -6
  316. package/models/trace/insights/INPBreakdown.js.map +1 -1
  317. package/models/trace/insights/ImageDelivery.d.ts +3 -3
  318. package/models/trace/insights/ImageDelivery.js +15 -14
  319. package/models/trace/insights/ImageDelivery.js.map +1 -1
  320. package/models/trace/insights/LCPBreakdown.d.ts +4 -3
  321. package/models/trace/insights/LCPBreakdown.js +19 -8
  322. package/models/trace/insights/LCPBreakdown.js.map +1 -1
  323. package/models/trace/insights/LCPDiscovery.d.ts +3 -3
  324. package/models/trace/insights/LCPDiscovery.js +8 -7
  325. package/models/trace/insights/LCPDiscovery.js.map +1 -1
  326. package/models/trace/insights/LegacyJavaScript.d.ts +2 -2
  327. package/models/trace/insights/LegacyJavaScript.js +7 -5
  328. package/models/trace/insights/LegacyJavaScript.js.map +1 -1
  329. package/models/trace/insights/Models.js +1 -1
  330. package/models/trace/insights/Models.js.map +1 -1
  331. package/models/trace/insights/ModernHTTP.d.ts +3 -3
  332. package/models/trace/insights/ModernHTTP.js +8 -7
  333. package/models/trace/insights/ModernHTTP.js.map +1 -1
  334. package/models/trace/insights/NetworkDependencyTree.d.ts +7 -4
  335. package/models/trace/insights/NetworkDependencyTree.js +21 -17
  336. package/models/trace/insights/NetworkDependencyTree.js.map +1 -1
  337. package/models/trace/insights/RenderBlocking.d.ts +2 -2
  338. package/models/trace/insights/RenderBlocking.js +13 -12
  339. package/models/trace/insights/RenderBlocking.js.map +1 -1
  340. package/models/trace/insights/SlowCSSSelector.d.ts +4 -3
  341. package/models/trace/insights/SlowCSSSelector.js +11 -7
  342. package/models/trace/insights/SlowCSSSelector.js.map +1 -1
  343. package/models/trace/insights/Statistics.js +1 -1
  344. package/models/trace/insights/Statistics.js.map +1 -1
  345. package/models/trace/insights/ThirdParties.d.ts +2 -1
  346. package/models/trace/insights/ThirdParties.js +10 -6
  347. package/models/trace/insights/ThirdParties.js.map +1 -1
  348. package/models/trace/insights/Viewport.d.ts +3 -2
  349. package/models/trace/insights/Viewport.js +10 -6
  350. package/models/trace/insights/Viewport.js.map +1 -1
  351. package/models/trace/insights/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  352. package/models/trace/insights/insights-tsconfig.json +6 -2
  353. package/models/trace/insights/insights.d.ts +2 -0
  354. package/models/trace/insights/insights.js +3 -1
  355. package/models/trace/insights/insights.js.map +1 -1
  356. package/models/trace/insights/types.d.ts +6 -2
  357. package/models/trace/insights/types.js +2 -1
  358. package/models/trace/insights/types.js.map +1 -1
  359. package/models/trace/lantern/core/LanternError.js +1 -1
  360. package/models/trace/lantern/core/LanternError.js.map +1 -1
  361. package/models/trace/lantern/core/NetworkAnalyzer.js +1 -1
  362. package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
  363. package/models/trace/lantern/core/core-tsconfig.json +6 -2
  364. package/models/trace/lantern/core/core.js +1 -1
  365. package/models/trace/lantern/core/core.js.map +1 -1
  366. package/models/trace/lantern/core/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  367. package/models/trace/lantern/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  368. package/models/trace/lantern/graph/BaseNode.js +1 -1
  369. package/models/trace/lantern/graph/BaseNode.js.map +1 -1
  370. package/models/trace/lantern/graph/CPUNode.js +1 -1
  371. package/models/trace/lantern/graph/CPUNode.js.map +1 -1
  372. package/models/trace/lantern/graph/NetworkNode.js +1 -1
  373. package/models/trace/lantern/graph/NetworkNode.js.map +1 -1
  374. package/models/trace/lantern/graph/PageDependencyGraph.js +1 -1
  375. package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
  376. package/models/trace/lantern/graph/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  377. package/models/trace/lantern/graph/graph-tsconfig.json +6 -2
  378. package/models/trace/lantern/graph/graph.js +1 -1
  379. package/models/trace/lantern/graph/graph.js.map +1 -1
  380. package/models/trace/lantern/lantern-tsconfig.json +6 -2
  381. package/models/trace/lantern/lantern.js +1 -1
  382. package/models/trace/lantern/lantern.js.map +1 -1
  383. package/models/trace/lantern/metrics/FirstContentfulPaint.js +1 -1
  384. package/models/trace/lantern/metrics/FirstContentfulPaint.js.map +1 -1
  385. package/models/trace/lantern/metrics/Interactive.js +1 -1
  386. package/models/trace/lantern/metrics/Interactive.js.map +1 -1
  387. package/models/trace/lantern/metrics/LargestContentfulPaint.js +1 -1
  388. package/models/trace/lantern/metrics/LargestContentfulPaint.js.map +1 -1
  389. package/models/trace/lantern/metrics/MaxPotentialFID.js +1 -1
  390. package/models/trace/lantern/metrics/MaxPotentialFID.js.map +1 -1
  391. package/models/trace/lantern/metrics/Metric.js +1 -1
  392. package/models/trace/lantern/metrics/Metric.js.map +1 -1
  393. package/models/trace/lantern/metrics/SpeedIndex.js +1 -1
  394. package/models/trace/lantern/metrics/SpeedIndex.js.map +1 -1
  395. package/models/trace/lantern/metrics/TBTUtils.js +1 -1
  396. package/models/trace/lantern/metrics/TBTUtils.js.map +1 -1
  397. package/models/trace/lantern/metrics/TotalBlockingTime.js +1 -1
  398. package/models/trace/lantern/metrics/TotalBlockingTime.js.map +1 -1
  399. package/models/trace/lantern/metrics/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  400. package/models/trace/lantern/metrics/metrics-tsconfig.json +6 -2
  401. package/models/trace/lantern/metrics/metrics.js +1 -1
  402. package/models/trace/lantern/metrics/metrics.js.map +1 -1
  403. package/models/trace/lantern/simulation/ConnectionPool.js +1 -1
  404. package/models/trace/lantern/simulation/ConnectionPool.js.map +1 -1
  405. package/models/trace/lantern/simulation/Constants.js +1 -1
  406. package/models/trace/lantern/simulation/Constants.js.map +1 -1
  407. package/models/trace/lantern/simulation/DNSCache.js +1 -1
  408. package/models/trace/lantern/simulation/DNSCache.js.map +1 -1
  409. package/models/trace/lantern/simulation/SimulationTimingMap.js +1 -1
  410. package/models/trace/lantern/simulation/SimulationTimingMap.js.map +1 -1
  411. package/models/trace/lantern/simulation/Simulator.js +1 -1
  412. package/models/trace/lantern/simulation/Simulator.js.map +1 -1
  413. package/models/trace/lantern/simulation/TCPConnection.js +1 -1
  414. package/models/trace/lantern/simulation/TCPConnection.js.map +1 -1
  415. package/models/trace/lantern/simulation/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  416. package/models/trace/lantern/simulation/simulation-tsconfig.json +6 -2
  417. package/models/trace/lantern/simulation/simulation.js +1 -1
  418. package/models/trace/lantern/simulation/simulation.js.map +1 -1
  419. package/models/trace/lantern/types/Lantern.js +1 -1
  420. package/models/trace/lantern/types/Lantern.js.map +1 -1
  421. package/models/trace/lantern/types/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  422. package/models/trace/lantern/types/types-tsconfig.json +6 -2
  423. package/models/trace/lantern/types/types.js +1 -1
  424. package/models/trace/lantern/types/types.js.map +1 -1
  425. package/models/trace/trace-tsconfig.json +10 -2
  426. package/models/trace/trace.d.ts +5 -1
  427. package/models/trace/trace.js +6 -2
  428. package/models/trace/trace.js.map +1 -1
  429. package/models/trace/types/Configuration.d.ts +11 -0
  430. package/models/trace/types/Configuration.js +1 -1
  431. package/models/trace/types/Configuration.js.map +1 -1
  432. package/models/trace/types/Extensions.d.ts +25 -13
  433. package/models/trace/types/Extensions.js +6 -3
  434. package/models/trace/types/Extensions.js.map +1 -1
  435. package/models/trace/types/File.d.ts +12 -0
  436. package/models/trace/types/File.js +1 -1
  437. package/models/trace/types/File.js.map +1 -1
  438. package/models/trace/types/Overlays.d.ts +1 -2
  439. package/models/trace/types/Overlays.js +1 -1
  440. package/models/trace/types/Overlays.js.map +1 -1
  441. package/models/trace/types/Timing.d.ts +1 -0
  442. package/models/trace/types/Timing.js +1 -1
  443. package/models/trace/types/Timing.js.map +1 -1
  444. package/models/trace/types/TraceEvents.d.ts +75 -56
  445. package/models/trace/types/TraceEvents.js +42 -29
  446. package/models/trace/types/TraceEvents.js.map +1 -1
  447. package/models/trace/types/devtools_entrypoint-bundle-typescript-tsconfig.json +6 -2
  448. package/models/trace/types/types-tsconfig.json +6 -2
  449. package/models/trace/types/types.js +1 -1
  450. package/models/trace/types/types.js.map +1 -1
  451. package/package.json +1 -1
  452. package/test/test-trace-engine.mjs +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"SpeedIndex.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/SpeedIndex.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 Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\n\nimport {\n type Extras,\n Metric,\n type MetricCoefficients,\n type MetricComputationDataInput,\n type MetricResult,\n} from './Metric.js';\n\nconst mobileSlow4GRtt = 150;\n\nclass SpeedIndex extends Metric {\n static override get coefficients(): MetricCoefficients {\n return {\n // Note that the optimistic estimate is based on the real observed speed index rather than a\n // real lantern graph (and the final estimate will be Math.max(FCP, Speed Index)).\n intercept: 0,\n optimistic: 1.4,\n pessimistic: 0.4,\n };\n }\n\n static override getScaledCoefficients(rttMs: number): MetricCoefficients {\n // We want to scale our default coefficients based on the speed of the connection.\n // We will linearly interpolate coefficients for the passed-in rttMs based on two pre-determined points:\n // 1. Baseline point of 30 ms RTT where Speed Index should be a ~50/50 blend of optimistic/pessimistic.\n // 30 ms was based on a typical home WiFi connection's actual RTT.\n // Coefficients here follow from the fact that the optimistic estimate should be very close\n // to reality at this connection speed and the pessimistic estimate compensates for minor\n // connection speed differences.\n // 2. Default throttled point of 150 ms RTT where the default coefficients have been determined to be most accurate.\n // Coefficients here were determined through thorough analysis and linear regression on the\n // lantern test data set. See core/scripts/test-lantern.sh for more detail.\n // While the coefficients haven't been analyzed at the interpolated points, it's our current best effort.\n const defaultCoefficients = this.coefficients;\n const defaultRttExcess = mobileSlow4GRtt - 30;\n const multiplier = Math.max((rttMs - 30) / defaultRttExcess, 0);\n\n return {\n intercept: defaultCoefficients.intercept * multiplier,\n optimistic: 0.5 + (defaultCoefficients.optimistic - 0.5) * multiplier,\n pessimistic: 0.5 + (defaultCoefficients.pessimistic - 0.5) * multiplier,\n };\n }\n\n static override getOptimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getEstimateFromSimulation(simulationResult: Simulation.Result, extras: Extras): Simulation.Result {\n if (!extras.fcpResult) {\n throw new Core.LanternError('missing fcpResult');\n }\n if (extras.observedSpeedIndex === undefined) {\n throw new Core.LanternError('missing observedSpeedIndex');\n }\n\n const fcpTimeInMs = extras.fcpResult.pessimisticEstimate.timeInMs;\n const estimate = extras.optimistic ?\n extras.observedSpeedIndex :\n SpeedIndex.computeLayoutBasedSpeedIndex(simulationResult.nodeTimings, fcpTimeInMs);\n return {\n timeInMs: estimate,\n nodeTimings: simulationResult.nodeTimings,\n };\n }\n\n static override compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const fcpResult = extras?.fcpResult;\n if (!fcpResult) {\n throw new Core.LanternError('FCP is required to calculate the SpeedIndex metric');\n }\n\n const metricResult = super.compute(data, extras);\n metricResult.timing = Math.max(metricResult.timing, fcpResult.timing);\n return metricResult;\n }\n\n /**\n * Approximate speed index using layout events from the simulated node timings.\n * The layout-based speed index is the weighted average of the endTime of CPU nodes that contained\n * a 'Layout' task. log(duration) is used as the weight to stand for \"significance\" to the page.\n *\n * If no layout events can be found or the endTime of a CPU task is too early, FCP is used instead.\n *\n * This approach was determined after evaluating the accuracy/complexity tradeoff of many\n * different methods. Read more in the evaluation doc.\n *\n * @see https://docs.google.com/document/d/1qJWXwxoyVLVadezIp_Tgdk867G3tDNkkVRvUJSH3K1E/edit#\n */\n static computeLayoutBasedSpeedIndex(nodeTimings: Simulation.Result['nodeTimings'], fcpTimeInMs: number): number {\n const layoutWeights: Array<{time: number, weight: number}> = [];\n for (const [node, timing] of nodeTimings.entries()) {\n if (node.type !== Graph.BaseNode.types.CPU) {\n continue;\n }\n\n if (node.childEvents.some(x => x.name === 'Layout')) {\n const timingWeight = Math.max(Math.log2(timing.endTime - timing.startTime), 0);\n layoutWeights.push({time: timing.endTime, weight: timingWeight});\n }\n }\n\n const totalWeightedTime =\n layoutWeights.map(evt => evt.weight * Math.max(evt.time, fcpTimeInMs)).reduce((a, b) => a + b, 0);\n const totalWeight = layoutWeights.map(evt => evt.weight).reduce((a, b) => a + b, 0);\n\n if (!totalWeight) {\n return fcpTimeInMs;\n }\n return totalWeightedTime / totalWeight;\n }\n}\n\nexport {SpeedIndex};\n"]}
1
+ {"version":3,"file":"SpeedIndex.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/SpeedIndex.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors\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 Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\n\nimport {\n type Extras,\n Metric,\n type MetricCoefficients,\n type MetricComputationDataInput,\n type MetricResult,\n} from './Metric.js';\n\nconst mobileSlow4GRtt = 150;\n\nclass SpeedIndex extends Metric {\n static override get coefficients(): MetricCoefficients {\n return {\n // Note that the optimistic estimate is based on the real observed speed index rather than a\n // real lantern graph (and the final estimate will be Math.max(FCP, Speed Index)).\n intercept: 0,\n optimistic: 1.4,\n pessimistic: 0.4,\n };\n }\n\n static override getScaledCoefficients(rttMs: number): MetricCoefficients {\n // We want to scale our default coefficients based on the speed of the connection.\n // We will linearly interpolate coefficients for the passed-in rttMs based on two pre-determined points:\n // 1. Baseline point of 30 ms RTT where Speed Index should be a ~50/50 blend of optimistic/pessimistic.\n // 30 ms was based on a typical home WiFi connection's actual RTT.\n // Coefficients here follow from the fact that the optimistic estimate should be very close\n // to reality at this connection speed and the pessimistic estimate compensates for minor\n // connection speed differences.\n // 2. Default throttled point of 150 ms RTT where the default coefficients have been determined to be most accurate.\n // Coefficients here were determined through thorough analysis and linear regression on the\n // lantern test data set. See core/scripts/test-lantern.sh for more detail.\n // While the coefficients haven't been analyzed at the interpolated points, it's our current best effort.\n const defaultCoefficients = this.coefficients;\n const defaultRttExcess = mobileSlow4GRtt - 30;\n const multiplier = Math.max((rttMs - 30) / defaultRttExcess, 0);\n\n return {\n intercept: defaultCoefficients.intercept * multiplier,\n optimistic: 0.5 + (defaultCoefficients.optimistic - 0.5) * multiplier,\n pessimistic: 0.5 + (defaultCoefficients.pessimistic - 0.5) * multiplier,\n };\n }\n\n static override getOptimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getEstimateFromSimulation(simulationResult: Simulation.Result, extras: Extras): Simulation.Result {\n if (!extras.fcpResult) {\n throw new Core.LanternError('missing fcpResult');\n }\n if (extras.observedSpeedIndex === undefined) {\n throw new Core.LanternError('missing observedSpeedIndex');\n }\n\n const fcpTimeInMs = extras.fcpResult.pessimisticEstimate.timeInMs;\n const estimate = extras.optimistic ?\n extras.observedSpeedIndex :\n SpeedIndex.computeLayoutBasedSpeedIndex(simulationResult.nodeTimings, fcpTimeInMs);\n return {\n timeInMs: estimate,\n nodeTimings: simulationResult.nodeTimings,\n };\n }\n\n static override compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const fcpResult = extras?.fcpResult;\n if (!fcpResult) {\n throw new Core.LanternError('FCP is required to calculate the SpeedIndex metric');\n }\n\n const metricResult = super.compute(data, extras);\n metricResult.timing = Math.max(metricResult.timing, fcpResult.timing);\n return metricResult;\n }\n\n /**\n * Approximate speed index using layout events from the simulated node timings.\n * The layout-based speed index is the weighted average of the endTime of CPU nodes that contained\n * a 'Layout' task. log(duration) is used as the weight to stand for \"significance\" to the page.\n *\n * If no layout events can be found or the endTime of a CPU task is too early, FCP is used instead.\n *\n * This approach was determined after evaluating the accuracy/complexity tradeoff of many\n * different methods. Read more in the evaluation doc.\n *\n * @see https://docs.google.com/document/d/1qJWXwxoyVLVadezIp_Tgdk867G3tDNkkVRvUJSH3K1E/edit#\n */\n static computeLayoutBasedSpeedIndex(nodeTimings: Simulation.Result['nodeTimings'], fcpTimeInMs: number): number {\n const layoutWeights: Array<{time: number, weight: number}> = [];\n for (const [node, timing] of nodeTimings.entries()) {\n if (node.type !== Graph.BaseNode.types.CPU) {\n continue;\n }\n\n if (node.childEvents.some(x => x.name === 'Layout')) {\n const timingWeight = Math.max(Math.log2(timing.endTime - timing.startTime), 0);\n layoutWeights.push({time: timing.endTime, weight: timingWeight});\n }\n }\n\n const totalWeightedTime =\n layoutWeights.map(evt => evt.weight * Math.max(evt.time, fcpTimeInMs)).reduce((a, b) => a + b, 0);\n const totalWeight = layoutWeights.map(evt => evt.weight).reduce((a, b) => a + b, 0);\n\n if (!totalWeight) {\n return fcpTimeInMs;\n }\n return totalWeightedTime / totalWeight;\n }\n}\n\nexport {SpeedIndex};\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  const BLOCKING_TIME_THRESHOLD = 50;
@@ -1 +1 @@
1
- {"version":3,"file":"TBTUtils.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/TBTUtils.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,SAAS,0BAA0B,CAC/B,KAAqD,EAAE,WAAmB,EAAE,SAAiB,EAC7F,aAA8D;IAChE,IAAI,SAAS,GAAG,uBAAuB,CAAC;IAExC,gFAAgF;IAChF,qCAAqC;IACrC,EAAE;IACF,mFAAmF;IACnF,0EAA0E;IAC1E,EAAE;IACF,qFAAqF;IACrF,IAAI,aAAa,EAAE,CAAC;QAClB,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,GAAG,WAAW,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,GAAG,SAAS,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sFAAsF;IACtF,uFAAuF;IACvF,yFAAyF;IACzF,uFAAuF;IACvF,4CAA4C;IAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;IAClD,IAAI,eAAe,GAAG,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,eAAe,GAAG,SAAS,CAAC;AACrC,CAAC;AAED,SAAS,0BAA0B,CAC/B,cAAqE,EAAE,WAAmB,EAC1F,SAAiB;IACnB,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,eAAe,IAAI,0BAA0B,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,GAC3B,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nconst BLOCKING_TIME_THRESHOLD = 50;\n\n/**\n * For TBT, We only want to consider tasks that fall in our time range\n * - FCP and TTI for navigation mode\n * - Trace start and trace end for timespan mode\n *\n * FCP is picked as `startTimeMs` because there is little risk of user input happening\n * before FCP so Long Queuing Qelay regions do not harm user experience. Developers should be\n * optimizing to reach FCP as fast as possible without having to worry about task lengths.\n *\n * TTI is picked as `endTimeMs` because we want a well defined end point for page load.\n *\n * @param startTimeMs Should be FCP in navigation mode and the trace start time in timespan mode\n * @param endTimeMs Should be TTI in navigation mode and the trace end time in timespan mode\n * @param topLevelEvent Leave unset if `event` is top level. Has no effect if `event` has the same duration as `topLevelEvent`.\n */\nfunction calculateTbtImpactForEvent(\n event: {start: number, end: number, duration: number}, startTimeMs: number, endTimeMs: number,\n topLevelEvent?: {start: number, end: number, duration: number}): number {\n let threshold = BLOCKING_TIME_THRESHOLD;\n\n // If a task is not top level, it doesn't make sense to subtract the entire 50ms\n // blocking threshold from the event.\n //\n // e.g. A 80ms top level task with two 40ms children should attribute some blocking\n // time to the 40ms tasks even though they do not meet the 50ms threshold.\n //\n // The solution is to scale the threshold for child events to be considered blocking.\n if (topLevelEvent) {\n threshold *= (event.duration / topLevelEvent.duration);\n }\n\n if (event.duration < threshold) {\n return 0;\n }\n if (event.end < startTimeMs) {\n return 0;\n }\n if (event.start > endTimeMs) {\n return 0;\n }\n\n // Perform the clipping and then calculate Blocking Region. So if we have a 150ms task\n // [0, 150] and `startTimeMs` is at 50ms, we first clip the task to [50, 150], and then\n // calculate the Blocking Region to be [100, 150]. The rational here is that tasks before\n // the start time are unimportant, so we care whether the main thread is busy more than\n // 50ms at a time only after the start time.\n const clippedStart = Math.max(event.start, startTimeMs);\n const clippedEnd = Math.min(event.end, endTimeMs);\n const clippedDuration = clippedEnd - clippedStart;\n if (clippedDuration < threshold) {\n return 0;\n }\n\n return clippedDuration - threshold;\n}\n\nfunction calculateSumOfBlockingTime(\n topLevelEvents: Array<{start: number, end: number, duration: number}>, startTimeMs: number,\n endTimeMs: number): number {\n if (endTimeMs <= startTimeMs) {\n return 0;\n }\n\n let sumBlockingTime = 0;\n for (const event of topLevelEvents) {\n sumBlockingTime += calculateTbtImpactForEvent(event, startTimeMs, endTimeMs);\n }\n\n return sumBlockingTime;\n}\n\nexport {\n BLOCKING_TIME_THRESHOLD,\n calculateSumOfBlockingTime,\n calculateTbtImpactForEvent,\n};\n"]}
1
+ {"version":3,"file":"TBTUtils.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/TBTUtils.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,6BAA6B;AAE7B,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,SAAS,0BAA0B,CAC/B,KAAqD,EAAE,WAAmB,EAAE,SAAiB,EAC7F,aAA8D;IAChE,IAAI,SAAS,GAAG,uBAAuB,CAAC;IAExC,gFAAgF;IAChF,qCAAqC;IACrC,EAAE;IACF,mFAAmF;IACnF,0EAA0E;IAC1E,EAAE;IACF,qFAAqF;IACrF,IAAI,aAAa,EAAE,CAAC;QAClB,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,GAAG,WAAW,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,GAAG,SAAS,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sFAAsF;IACtF,uFAAuF;IACvF,yFAAyF;IACzF,uFAAuF;IACvF,4CAA4C;IAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;IAClD,IAAI,eAAe,GAAG,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,eAAe,GAAG,SAAS,CAAC;AACrC,CAAC;AAED,SAAS,0BAA0B,CAC/B,cAAqE,EAAE,WAAmB,EAC1F,SAAiB;IACnB,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,eAAe,IAAI,0BAA0B,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,GAC3B,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nconst BLOCKING_TIME_THRESHOLD = 50;\n\n/**\n * For TBT, We only want to consider tasks that fall in our time range\n * - FCP and TTI for navigation mode\n * - Trace start and trace end for timespan mode\n *\n * FCP is picked as `startTimeMs` because there is little risk of user input happening\n * before FCP so Long Queuing Qelay regions do not harm user experience. Developers should be\n * optimizing to reach FCP as fast as possible without having to worry about task lengths.\n *\n * TTI is picked as `endTimeMs` because we want a well defined end point for page load.\n *\n * @param startTimeMs Should be FCP in navigation mode and the trace start time in timespan mode\n * @param endTimeMs Should be TTI in navigation mode and the trace end time in timespan mode\n * @param topLevelEvent Leave unset if `event` is top level. Has no effect if `event` has the same duration as `topLevelEvent`.\n */\nfunction calculateTbtImpactForEvent(\n event: {start: number, end: number, duration: number}, startTimeMs: number, endTimeMs: number,\n topLevelEvent?: {start: number, end: number, duration: number}): number {\n let threshold = BLOCKING_TIME_THRESHOLD;\n\n // If a task is not top level, it doesn't make sense to subtract the entire 50ms\n // blocking threshold from the event.\n //\n // e.g. A 80ms top level task with two 40ms children should attribute some blocking\n // time to the 40ms tasks even though they do not meet the 50ms threshold.\n //\n // The solution is to scale the threshold for child events to be considered blocking.\n if (topLevelEvent) {\n threshold *= (event.duration / topLevelEvent.duration);\n }\n\n if (event.duration < threshold) {\n return 0;\n }\n if (event.end < startTimeMs) {\n return 0;\n }\n if (event.start > endTimeMs) {\n return 0;\n }\n\n // Perform the clipping and then calculate Blocking Region. So if we have a 150ms task\n // [0, 150] and `startTimeMs` is at 50ms, we first clip the task to [50, 150], and then\n // calculate the Blocking Region to be [100, 150]. The rational here is that tasks before\n // the start time are unimportant, so we care whether the main thread is busy more than\n // 50ms at a time only after the start time.\n const clippedStart = Math.max(event.start, startTimeMs);\n const clippedEnd = Math.min(event.end, endTimeMs);\n const clippedDuration = clippedEnd - clippedStart;\n if (clippedDuration < threshold) {\n return 0;\n }\n\n return clippedDuration - threshold;\n}\n\nfunction calculateSumOfBlockingTime(\n topLevelEvents: Array<{start: number, end: number, duration: number}>, startTimeMs: number,\n endTimeMs: number): number {\n if (endTimeMs <= startTimeMs) {\n return 0;\n }\n\n let sumBlockingTime = 0;\n for (const event of topLevelEvents) {\n sumBlockingTime += calculateTbtImpactForEvent(event, startTimeMs, endTimeMs);\n }\n\n return sumBlockingTime;\n}\n\nexport {\n BLOCKING_TIME_THRESHOLD,\n calculateSumOfBlockingTime,\n calculateTbtImpactForEvent,\n};\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  import * as Core from '../core/core.js';
@@ -1 +1 @@
1
- {"version":3,"file":"TotalBlockingTime.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/TotalBlockingTime.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 Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\n\nimport {\n type Extras,\n Metric,\n type MetricCoefficients,\n type MetricComputationDataInput,\n type MetricResult,\n} from './Metric.js';\nimport {BLOCKING_TIME_THRESHOLD, calculateSumOfBlockingTime} from './TBTUtils.js';\n\nclass TotalBlockingTime extends Metric {\n static override get coefficients(): MetricCoefficients {\n return {\n intercept: 0,\n optimistic: 0.5,\n pessimistic: 0.5,\n };\n }\n\n static override getOptimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getEstimateFromSimulation(simulation: Simulation.Result, extras: Extras): Simulation.Result {\n if (!extras.fcpResult) {\n throw new Core.LanternError('missing fcpResult');\n }\n if (!extras.interactiveResult) {\n throw new Core.LanternError('missing interactiveResult');\n }\n\n // Intentionally use the opposite FCP estimate. A pessimistic FCP is higher than equal to an\n // optimistic FCP, which means potentially more tasks are excluded from the Total Blocking Time\n // computation. So a more pessimistic FCP gives a more optimistic Total Blocking Time for the\n // same work.\n const fcpTimeInMs = extras.optimistic ? extras.fcpResult.pessimisticEstimate.timeInMs :\n extras.fcpResult.optimisticEstimate.timeInMs;\n\n // Similarly, we always have pessimistic TTI >= optimistic TTI. Therefore, picking optimistic\n // TTI means our window of interest is smaller and thus potentially more tasks are excluded from\n // Total Blocking Time computation, yielding a lower (more optimistic) Total Blocking Time value\n // for the same work.\n const interactiveTimeMs = extras.optimistic ? extras.interactiveResult.optimisticEstimate.timeInMs :\n extras.interactiveResult.pessimisticEstimate.timeInMs;\n\n const minDurationMs = BLOCKING_TIME_THRESHOLD;\n\n const events = TotalBlockingTime.getTopLevelEvents(\n simulation.nodeTimings,\n minDurationMs,\n );\n\n return {\n timeInMs: calculateSumOfBlockingTime(\n events,\n fcpTimeInMs,\n interactiveTimeMs,\n ),\n nodeTimings: simulation.nodeTimings,\n };\n }\n\n static override compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const fcpResult = extras?.fcpResult;\n if (!fcpResult) {\n throw new Core.LanternError('FCP is required to calculate the TBT metric');\n }\n\n const interactiveResult = extras?.fcpResult;\n if (!interactiveResult) {\n throw new Core.LanternError('Interactive is required to calculate the TBT metric');\n }\n\n return super.compute(data, extras);\n }\n\n static getTopLevelEvents(nodeTimings: Simulation.Result['nodeTimings'], minDurationMs: number):\n Array<{start: number, end: number, duration: number}> {\n const events: Array<{start: number, end: number, duration: number}> = [];\n\n for (const [node, timing] of nodeTimings.entries()) {\n if (node.type !== Graph.BaseNode.types.CPU) {\n continue;\n }\n // Filtering out events below minimum duration.\n if (timing.duration < minDurationMs) {\n continue;\n }\n\n events.push({\n start: timing.startTime,\n end: timing.endTime,\n duration: timing.duration,\n });\n }\n\n return events;\n }\n}\n\nexport {TotalBlockingTime};\n"]}
1
+ {"version":3,"file":"TotalBlockingTime.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/TotalBlockingTime.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAEL,MAAM,GAIP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,uBAAuB,EAAE,0BAA0B,EAAC,MAAM,eAAe,CAAC;AAElF,MAAM,iBAAkB,SAAQ,MAAM;IACpC,MAAM,KAAc,YAAY;QAC9B,OAAO;YACL,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,GAAG;YACf,WAAW,EAAE,GAAG;SACjB,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,kBAAkB,CAAC,eAA2B;QAC5D,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,CAAU,mBAAmB,CAAC,eAA2B;QAC7D,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,CAAU,yBAAyB,CAAC,UAA6B,EAAE,MAAc;QACrF,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC9B,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC;QAC3D,CAAC;QAED,4FAA4F;QAC5F,+FAA+F;QAC/F,6FAA6F;QAC7F,aAAa;QACb,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC;QAErF,6FAA6F;QAC7F,gGAAgG;QAChG,gGAAgG;QAChG,qBAAqB;QACrB,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACtD,MAAM,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,QAAQ,CAAC;QAEpG,MAAM,aAAa,GAAG,uBAAuB,CAAC;QAE9C,MAAM,MAAM,GAAG,iBAAiB,CAAC,iBAAiB,CAC9C,UAAU,CAAC,WAAW,EACtB,aAAa,CAChB,CAAC;QAEF,OAAO;YACL,QAAQ,EAAE,0BAA0B,CAChC,MAAM,EACN,WAAW,EACX,iBAAiB,CAChB;YACL,WAAW,EAAE,UAAU,CAAC,WAAW;SACpC,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,OAAO,CAAC,IAAgC,EAAE,MAAmC;QAC3F,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,6CAA6C,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,EAAE,SAAS,CAAC;QAC5C,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,qDAAqD,CAAC,CAAC;QACrF,CAAC;QAED,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,WAA6C,EAAE,aAAqB;QAE3F,MAAM,MAAM,GAA0D,EAAE,CAAC;QAEzE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;gBAC3C,SAAS;YACX,CAAC;YACD,+CAA+C;YAC/C,IAAI,MAAM,CAAC,QAAQ,GAAG,aAAa,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,MAAM,CAAC,SAAS;gBACvB,GAAG,EAAE,MAAM,CAAC,OAAO;gBACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,OAAO,EAAC,iBAAiB,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors\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 Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\n\nimport {\n type Extras,\n Metric,\n type MetricCoefficients,\n type MetricComputationDataInput,\n type MetricResult,\n} from './Metric.js';\nimport {BLOCKING_TIME_THRESHOLD, calculateSumOfBlockingTime} from './TBTUtils.js';\n\nclass TotalBlockingTime extends Metric {\n static override get coefficients(): MetricCoefficients {\n return {\n intercept: 0,\n optimistic: 0.5,\n pessimistic: 0.5,\n };\n }\n\n static override getOptimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getEstimateFromSimulation(simulation: Simulation.Result, extras: Extras): Simulation.Result {\n if (!extras.fcpResult) {\n throw new Core.LanternError('missing fcpResult');\n }\n if (!extras.interactiveResult) {\n throw new Core.LanternError('missing interactiveResult');\n }\n\n // Intentionally use the opposite FCP estimate. A pessimistic FCP is higher than equal to an\n // optimistic FCP, which means potentially more tasks are excluded from the Total Blocking Time\n // computation. So a more pessimistic FCP gives a more optimistic Total Blocking Time for the\n // same work.\n const fcpTimeInMs = extras.optimistic ? extras.fcpResult.pessimisticEstimate.timeInMs :\n extras.fcpResult.optimisticEstimate.timeInMs;\n\n // Similarly, we always have pessimistic TTI >= optimistic TTI. Therefore, picking optimistic\n // TTI means our window of interest is smaller and thus potentially more tasks are excluded from\n // Total Blocking Time computation, yielding a lower (more optimistic) Total Blocking Time value\n // for the same work.\n const interactiveTimeMs = extras.optimistic ? extras.interactiveResult.optimisticEstimate.timeInMs :\n extras.interactiveResult.pessimisticEstimate.timeInMs;\n\n const minDurationMs = BLOCKING_TIME_THRESHOLD;\n\n const events = TotalBlockingTime.getTopLevelEvents(\n simulation.nodeTimings,\n minDurationMs,\n );\n\n return {\n timeInMs: calculateSumOfBlockingTime(\n events,\n fcpTimeInMs,\n interactiveTimeMs,\n ),\n nodeTimings: simulation.nodeTimings,\n };\n }\n\n static override compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const fcpResult = extras?.fcpResult;\n if (!fcpResult) {\n throw new Core.LanternError('FCP is required to calculate the TBT metric');\n }\n\n const interactiveResult = extras?.fcpResult;\n if (!interactiveResult) {\n throw new Core.LanternError('Interactive is required to calculate the TBT metric');\n }\n\n return super.compute(data, extras);\n }\n\n static getTopLevelEvents(nodeTimings: Simulation.Result['nodeTimings'], minDurationMs: number):\n Array<{start: number, end: number, duration: number}> {\n const events: Array<{start: number, end: number, duration: number}> = [];\n\n for (const [node, timing] of nodeTimings.entries()) {\n if (node.type !== Graph.BaseNode.types.CPU) {\n continue;\n }\n // Filtering out events below minimum duration.\n if (timing.duration < minDurationMs) {\n continue;\n }\n\n events.push({\n start: timing.startTime,\n end: timing.endTime,\n duration: timing.duration,\n });\n }\n\n return events;\n }\n}\n\nexport {TotalBlockingTime};\n"]}
@@ -8,7 +8,11 @@
8
8
  "forceConsistentCasingInFileNames": true,
9
9
  "inlineSources": true,
10
10
  "lib": [
11
- "esnext",
11
+ "ES2023",
12
+ "ES2024.Promise",
13
+ "ESNext.Iterator",
14
+ "ESNext.Collection",
15
+ "ESNext.Array",
12
16
  "dom",
13
17
  "dom.iterable"
14
18
  ],
@@ -24,7 +28,7 @@
24
28
  "skipLibCheck": true,
25
29
  "sourceMap": true,
26
30
  "strict": true,
27
- "target": "esnext",
31
+ "target": "ES2023",
28
32
  "tsBuildInfoFile": "devtools_entrypoint-bundle-typescript-tsconfig.json.tsbuildinfo",
29
33
  "typeRoots": [],
30
34
  "useUnknownInCatchVariables": false
@@ -8,7 +8,11 @@
8
8
  "forceConsistentCasingInFileNames": true,
9
9
  "inlineSources": true,
10
10
  "lib": [
11
- "esnext",
11
+ "ES2023",
12
+ "ES2024.Promise",
13
+ "ESNext.Iterator",
14
+ "ESNext.Collection",
15
+ "ESNext.Array",
12
16
  "dom",
13
17
  "dom.iterable"
14
18
  ],
@@ -24,7 +28,7 @@
24
28
  "skipLibCheck": true,
25
29
  "sourceMap": true,
26
30
  "strict": true,
27
- "target": "esnext",
31
+ "target": "ES2023",
28
32
  "tsBuildInfoFile": "metrics-tsconfig.json.tsbuildinfo",
29
33
  "typeRoots": [],
30
34
  "useUnknownInCatchVariables": false
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  export * from './FirstContentfulPaint.js';
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/metrics.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * from './FirstContentfulPaint.js';\nexport * from './Interactive.js';\nexport * from './LargestContentfulPaint.js';\nexport * from './MaxPotentialFID.js';\nexport * from './Metric.js';\nexport * from './SpeedIndex.js';\nexport * from './TotalBlockingTime.js';\nexport * as TBTUtils from './TBTUtils.js';\n"]}
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/metrics.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,6BAA6B;AAE7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * from './FirstContentfulPaint.js';\nexport * from './Interactive.js';\nexport * from './LargestContentfulPaint.js';\nexport * from './MaxPotentialFID.js';\nexport * from './Metric.js';\nexport * from './SpeedIndex.js';\nexport * from './TotalBlockingTime.js';\nexport * as TBTUtils from './TBTUtils.js';\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  import * as Core from '../core/core.js';
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionPool.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/ConnectionPool.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 Core from '../core/core.js';\nimport type * as Lantern from '../types/types.js';\n\nimport {TCPConnection} from './TCPConnection.js';\n\nconst DEFAULT_SERVER_RESPONSE_TIME = 30;\nconst TLS_SCHEMES = ['https', 'wss'];\n\n// Each origin can have 6 simultaneous connections open\n// https://cs.chromium.org/chromium/src/net/socket/client_socket_pool_manager.cc?type=cs&q=\"int+g_max_sockets_per_group\"\nconst CONNECTIONS_PER_ORIGIN = 6;\n\nexport class ConnectionPool {\n options: Required<Lantern.Simulation.Options>;\n records: Lantern.NetworkRequest[];\n connectionsByOrigin: Map<string, TCPConnection[]>;\n connectionsByRequest: Map<Lantern.NetworkRequest, TCPConnection>;\n _connectionsInUse: Set<TCPConnection>;\n connectionReusedByRequestId: Map<string, boolean>;\n\n constructor(records: Lantern.NetworkRequest[], options: Required<Lantern.Simulation.Options>) {\n this.options = options;\n\n this.records = records;\n this.connectionsByOrigin = new Map();\n this.connectionsByRequest = new Map();\n this._connectionsInUse = new Set();\n this.connectionReusedByRequestId = Core.NetworkAnalyzer.estimateIfConnectionWasReused(records, {\n forceCoarseEstimates: true,\n });\n\n this.initializeConnections();\n }\n\n connectionsInUse(): TCPConnection[] {\n return Array.from(this._connectionsInUse);\n }\n\n initializeConnections(): void {\n const connectionReused = this.connectionReusedByRequestId;\n const additionalRttByOrigin = this.options.additionalRttByOrigin;\n const serverResponseTimeByOrigin = this.options.serverResponseTimeByOrigin;\n\n const recordsByOrigin = Core.NetworkAnalyzer.groupByOrigin(this.records);\n for (const [origin, requests] of recordsByOrigin.entries()) {\n const connections = [];\n const additionalRtt = additionalRttByOrigin.get(origin) || 0;\n const responseTime = serverResponseTimeByOrigin.get(origin) || DEFAULT_SERVER_RESPONSE_TIME;\n\n for (const request of requests) {\n if (connectionReused.get(request.requestId)) {\n continue;\n }\n\n const isTLS = TLS_SCHEMES.includes(request.parsedURL.scheme);\n const isH2 = request.protocol === 'h2';\n const connection = new TCPConnection(\n this.options.rtt + additionalRtt,\n this.options.throughput,\n responseTime,\n isTLS,\n isH2,\n );\n\n connections.push(connection);\n }\n\n if (!connections.length) {\n throw new Core.LanternError(`Could not find a connection for origin: ${origin}`);\n }\n\n // Make sure each origin has minimum number of connections available for max throughput.\n // But only if it's not over H2 which maximizes throughput already.\n const minConnections = connections[0].isH2() ? 1 : CONNECTIONS_PER_ORIGIN;\n while (connections.length < minConnections) {\n connections.push(connections[0].clone());\n }\n\n this.connectionsByOrigin.set(origin, connections);\n }\n }\n\n findAvailableConnectionWithLargestCongestionWindow(connections: TCPConnection[]): TCPConnection|null {\n let maxConnection: TCPConnection|null = null;\n for (let i = 0; i < connections.length; i++) {\n const connection = connections[i];\n\n // Connections that are in use are never available.\n if (this._connectionsInUse.has(connection)) {\n continue;\n }\n\n // This connection is a match and is available! Update our max if it has a larger congestionWindow\n const currentMax = (maxConnection?.congestionWindow) || -Infinity;\n if (connection.congestionWindow > currentMax) {\n maxConnection = connection;\n }\n }\n\n return maxConnection;\n }\n\n /**\n * This method finds an available connection to the origin specified by the network request or null\n * if no connection was available. If returned, connection will not be available for other network\n * records until release is called.\n */\n acquire(request: Lantern.NetworkRequest): TCPConnection|null {\n if (this.connectionsByRequest.has(request)) {\n throw new Core.LanternError('Record already has a connection');\n }\n\n const origin = request.parsedURL.securityOrigin;\n const connections = this.connectionsByOrigin.get(origin) || [];\n const connectionToUse = this.findAvailableConnectionWithLargestCongestionWindow(connections);\n\n if (!connectionToUse) {\n return null;\n }\n\n this._connectionsInUse.add(connectionToUse);\n this.connectionsByRequest.set(request, connectionToUse);\n return connectionToUse;\n }\n\n /**\n * Return the connection currently being used to fetch a request. If no connection\n * currently being used for this request, an error will be thrown.\n */\n acquireActiveConnectionFromRequest(request: Lantern.NetworkRequest): TCPConnection {\n const activeConnection = this.connectionsByRequest.get(request);\n if (!activeConnection) {\n throw new Core.LanternError('Could not find an active connection for request');\n }\n\n return activeConnection;\n }\n\n release(request: Lantern.NetworkRequest): void {\n const connection = this.connectionsByRequest.get(request);\n this.connectionsByRequest.delete(request);\n if (connection) {\n this._connectionsInUse.delete(connection);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ConnectionPool.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/ConnectionPool.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors\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 Core from '../core/core.js';\nimport type * as Lantern from '../types/types.js';\n\nimport {TCPConnection} from './TCPConnection.js';\n\nconst DEFAULT_SERVER_RESPONSE_TIME = 30;\nconst TLS_SCHEMES = ['https', 'wss'];\n\n// Each origin can have 6 simultaneous connections open\n// https://cs.chromium.org/chromium/src/net/socket/client_socket_pool_manager.cc?type=cs&q=\"int+g_max_sockets_per_group\"\nconst CONNECTIONS_PER_ORIGIN = 6;\n\nexport class ConnectionPool {\n options: Required<Lantern.Simulation.Options>;\n records: Lantern.NetworkRequest[];\n connectionsByOrigin: Map<string, TCPConnection[]>;\n connectionsByRequest: Map<Lantern.NetworkRequest, TCPConnection>;\n _connectionsInUse: Set<TCPConnection>;\n connectionReusedByRequestId: Map<string, boolean>;\n\n constructor(records: Lantern.NetworkRequest[], options: Required<Lantern.Simulation.Options>) {\n this.options = options;\n\n this.records = records;\n this.connectionsByOrigin = new Map();\n this.connectionsByRequest = new Map();\n this._connectionsInUse = new Set();\n this.connectionReusedByRequestId = Core.NetworkAnalyzer.estimateIfConnectionWasReused(records, {\n forceCoarseEstimates: true,\n });\n\n this.initializeConnections();\n }\n\n connectionsInUse(): TCPConnection[] {\n return Array.from(this._connectionsInUse);\n }\n\n initializeConnections(): void {\n const connectionReused = this.connectionReusedByRequestId;\n const additionalRttByOrigin = this.options.additionalRttByOrigin;\n const serverResponseTimeByOrigin = this.options.serverResponseTimeByOrigin;\n\n const recordsByOrigin = Core.NetworkAnalyzer.groupByOrigin(this.records);\n for (const [origin, requests] of recordsByOrigin.entries()) {\n const connections = [];\n const additionalRtt = additionalRttByOrigin.get(origin) || 0;\n const responseTime = serverResponseTimeByOrigin.get(origin) || DEFAULT_SERVER_RESPONSE_TIME;\n\n for (const request of requests) {\n if (connectionReused.get(request.requestId)) {\n continue;\n }\n\n const isTLS = TLS_SCHEMES.includes(request.parsedURL.scheme);\n const isH2 = request.protocol === 'h2';\n const connection = new TCPConnection(\n this.options.rtt + additionalRtt,\n this.options.throughput,\n responseTime,\n isTLS,\n isH2,\n );\n\n connections.push(connection);\n }\n\n if (!connections.length) {\n throw new Core.LanternError(`Could not find a connection for origin: ${origin}`);\n }\n\n // Make sure each origin has minimum number of connections available for max throughput.\n // But only if it's not over H2 which maximizes throughput already.\n const minConnections = connections[0].isH2() ? 1 : CONNECTIONS_PER_ORIGIN;\n while (connections.length < minConnections) {\n connections.push(connections[0].clone());\n }\n\n this.connectionsByOrigin.set(origin, connections);\n }\n }\n\n findAvailableConnectionWithLargestCongestionWindow(connections: TCPConnection[]): TCPConnection|null {\n let maxConnection: TCPConnection|null = null;\n for (let i = 0; i < connections.length; i++) {\n const connection = connections[i];\n\n // Connections that are in use are never available.\n if (this._connectionsInUse.has(connection)) {\n continue;\n }\n\n // This connection is a match and is available! Update our max if it has a larger congestionWindow\n const currentMax = (maxConnection?.congestionWindow) || -Infinity;\n if (connection.congestionWindow > currentMax) {\n maxConnection = connection;\n }\n }\n\n return maxConnection;\n }\n\n /**\n * This method finds an available connection to the origin specified by the network request or null\n * if no connection was available. If returned, connection will not be available for other network\n * records until release is called.\n */\n acquire(request: Lantern.NetworkRequest): TCPConnection|null {\n if (this.connectionsByRequest.has(request)) {\n throw new Core.LanternError('Record already has a connection');\n }\n\n const origin = request.parsedURL.securityOrigin;\n const connections = this.connectionsByOrigin.get(origin) || [];\n const connectionToUse = this.findAvailableConnectionWithLargestCongestionWindow(connections);\n\n if (!connectionToUse) {\n return null;\n }\n\n this._connectionsInUse.add(connectionToUse);\n this.connectionsByRequest.set(request, connectionToUse);\n return connectionToUse;\n }\n\n /**\n * Return the connection currently being used to fetch a request. If no connection\n * currently being used for this request, an error will be thrown.\n */\n acquireActiveConnectionFromRequest(request: Lantern.NetworkRequest): TCPConnection {\n const activeConnection = this.connectionsByRequest.get(request);\n if (!activeConnection) {\n throw new Core.LanternError('Could not find an active connection for request');\n }\n\n return activeConnection;\n }\n\n release(request: Lantern.NetworkRequest): void {\n const connection = this.connectionsByRequest.get(request);\n this.connectionsByRequest.delete(request);\n if (connection) {\n this._connectionsInUse.delete(connection);\n }\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  const DEVTOOLS_RTT_ADJUSTMENT_FACTOR = 3.75;
@@ -1 +1 @@
1
- {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/Constants.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAC5C,MAAM,qCAAqC,GAAG,GAAG,CAAC;AAElD,MAAM,UAAU,GAAG;IACjB,8BAA8B;IAC9B,qCAAqC;IACrC,gEAAgE;IAChE,sFAAsF;IACtF,YAAY,EAAE;QACZ,KAAK,EAAE,GAAG;QACV,cAAc,EAAE,GAAG,GAAG,IAAI;QAC1B,gBAAgB,EAAE,GAAG,GAAG,8BAA8B;QACtD,sBAAsB,EAAE,GAAG,GAAG,IAAI,GAAG,qCAAqC;QAC1E,oBAAoB,EAAE,GAAG,GAAG,qCAAqC;QACjE,qBAAqB,EAAE,CAAC;KACzB;IACD,8EAA8E;IAC9E,gGAAgG;IAChG,iEAAiE;IACjE,eAAe,EAAE;QACf,KAAK,EAAE,GAAG;QACV,cAAc,EAAE,GAAG;QACnB,gBAAgB,EAAE,GAAG,GAAG,8BAA8B;QACtD,sBAAsB,EAAE,GAAG,GAAG,qCAAqC;QACnE,oBAAoB,EAAE,GAAG,GAAG,qCAAqC;QACjE,qBAAqB,EAAE,CAAC;KACzB;IACD,sCAAsC;IACtC,2JAA2J;IAC3J,cAAc,EAAE;QACd,KAAK,EAAE,EAAE;QACT,cAAc,EAAE,EAAE,GAAG,IAAI;QACzB,qBAAqB,EAAE,CAAC;QACxB,gBAAgB,EAAE,CAAC,EAAG,gBAAgB;QACtC,sBAAsB,EAAE,CAAC;QACzB,oBAAoB,EAAE,CAAC;KACxB;CACF,CAAC;AAEF,MAAM,SAAS,GAAG,EAAC,UAAU,EAAC,CAAC;AAE/B,OAAO,EAAC,SAAS,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nconst DEVTOOLS_RTT_ADJUSTMENT_FACTOR = 3.75;\nconst DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR = 0.9;\n\nconst throttling = {\n DEVTOOLS_RTT_ADJUSTMENT_FACTOR,\n DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n // These values align with WebPageTest's definition of \"Fast 3G\"\n // But offer similar characteristics to roughly the 75th percentile of 4G connections.\n mobileSlow4G: {\n rttMs: 150,\n throughputKbps: 1.6 * 1024,\n requestLatencyMs: 150 * DEVTOOLS_RTT_ADJUSTMENT_FACTOR,\n downloadThroughputKbps: 1.6 * 1024 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n uploadThroughputKbps: 750 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n cpuSlowdownMultiplier: 4,\n },\n // These values partially align with WebPageTest's definition of \"Regular 3G\".\n // These values are meant to roughly align with Chrome UX report's 3G definition which are based\n // on HTTP RTT of 300-1400ms and downlink throughput of <700kbps.\n mobileRegular3G: {\n rttMs: 300,\n throughputKbps: 700,\n requestLatencyMs: 300 * DEVTOOLS_RTT_ADJUSTMENT_FACTOR,\n downloadThroughputKbps: 700 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n uploadThroughputKbps: 700 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n cpuSlowdownMultiplier: 4,\n },\n // Using a \"broadband\" connection type\n // Corresponds to \"Dense 4G 25th percentile\" in https://docs.google.com/document/d/1Ft1Bnq9-t4jK5egLSOc28IL4TvR-Tt0se_1faTA4KTY/edit#heading=h.bb7nfy2x9e5v\n desktopDense4G: {\n rttMs: 40,\n throughputKbps: 10 * 1024,\n cpuSlowdownMultiplier: 1,\n requestLatencyMs: 0, // 0 means unset\n downloadThroughputKbps: 0,\n uploadThroughputKbps: 0,\n },\n};\n\nconst Constants = {throttling};\n\nexport {Constants};\n"]}
1
+ {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/Constants.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,6BAA6B;AAE7B,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAC5C,MAAM,qCAAqC,GAAG,GAAG,CAAC;AAElD,MAAM,UAAU,GAAG;IACjB,8BAA8B;IAC9B,qCAAqC;IACrC,gEAAgE;IAChE,sFAAsF;IACtF,YAAY,EAAE;QACZ,KAAK,EAAE,GAAG;QACV,cAAc,EAAE,GAAG,GAAG,IAAI;QAC1B,gBAAgB,EAAE,GAAG,GAAG,8BAA8B;QACtD,sBAAsB,EAAE,GAAG,GAAG,IAAI,GAAG,qCAAqC;QAC1E,oBAAoB,EAAE,GAAG,GAAG,qCAAqC;QACjE,qBAAqB,EAAE,CAAC;KACzB;IACD,8EAA8E;IAC9E,gGAAgG;IAChG,iEAAiE;IACjE,eAAe,EAAE;QACf,KAAK,EAAE,GAAG;QACV,cAAc,EAAE,GAAG;QACnB,gBAAgB,EAAE,GAAG,GAAG,8BAA8B;QACtD,sBAAsB,EAAE,GAAG,GAAG,qCAAqC;QACnE,oBAAoB,EAAE,GAAG,GAAG,qCAAqC;QACjE,qBAAqB,EAAE,CAAC;KACzB;IACD,sCAAsC;IACtC,2JAA2J;IAC3J,cAAc,EAAE;QACd,KAAK,EAAE,EAAE;QACT,cAAc,EAAE,EAAE,GAAG,IAAI;QACzB,qBAAqB,EAAE,CAAC;QACxB,gBAAgB,EAAE,CAAC,EAAG,gBAAgB;QACtC,sBAAsB,EAAE,CAAC;QACzB,oBAAoB,EAAE,CAAC;KACxB;CACF,CAAC;AAEF,MAAM,SAAS,GAAG,EAAC,UAAU,EAAC,CAAC;AAE/B,OAAO,EAAC,SAAS,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nconst DEVTOOLS_RTT_ADJUSTMENT_FACTOR = 3.75;\nconst DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR = 0.9;\n\nconst throttling = {\n DEVTOOLS_RTT_ADJUSTMENT_FACTOR,\n DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n // These values align with WebPageTest's definition of \"Fast 3G\"\n // But offer similar characteristics to roughly the 75th percentile of 4G connections.\n mobileSlow4G: {\n rttMs: 150,\n throughputKbps: 1.6 * 1024,\n requestLatencyMs: 150 * DEVTOOLS_RTT_ADJUSTMENT_FACTOR,\n downloadThroughputKbps: 1.6 * 1024 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n uploadThroughputKbps: 750 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n cpuSlowdownMultiplier: 4,\n },\n // These values partially align with WebPageTest's definition of \"Regular 3G\".\n // These values are meant to roughly align with Chrome UX report's 3G definition which are based\n // on HTTP RTT of 300-1400ms and downlink throughput of <700kbps.\n mobileRegular3G: {\n rttMs: 300,\n throughputKbps: 700,\n requestLatencyMs: 300 * DEVTOOLS_RTT_ADJUSTMENT_FACTOR,\n downloadThroughputKbps: 700 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n uploadThroughputKbps: 700 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR,\n cpuSlowdownMultiplier: 4,\n },\n // Using a \"broadband\" connection type\n // Corresponds to \"Dense 4G 25th percentile\" in https://docs.google.com/document/d/1Ft1Bnq9-t4jK5egLSOc28IL4TvR-Tt0se_1faTA4KTY/edit#heading=h.bb7nfy2x9e5v\n desktopDense4G: {\n rttMs: 40,\n throughputKbps: 10 * 1024,\n cpuSlowdownMultiplier: 1,\n requestLatencyMs: 0, // 0 means unset\n downloadThroughputKbps: 0,\n uploadThroughputKbps: 0,\n },\n};\n\nconst Constants = {throttling};\n\nexport {Constants};\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  // A DNS lookup will usually take ~1-2 roundtrips of connection latency plus the extra DNS routing time.
@@ -1 +1 @@
1
- {"version":3,"file":"DNSCache.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/DNSCache.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,wGAAwG;AACxG,yHAAyH;AACzH,yHAAyH;AACzH,mGAAmG;AACnG,oGAAoG;AACpG,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAExC,MAAM,QAAQ;IACZ,MAAM,CAAC,aAAa,GAAG,6BAA6B,CAAC;IAErD,GAAG,CAAS;IACZ,mBAAmB,CAAoC;IAEvD,YAAY,EAAC,GAAG,EAAgB;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,mBAAmB,GAAG,IAAI,GAAG,EAAE,CAAC;IACvC,CAAC;IAED,sBAAsB,CAClB,OAA+B,EAAE,OAA6D;QAChG,MAAM,EAAC,WAAW,GAAG,CAAC,EAAE,iBAAiB,GAAG,KAAK,EAAC,GAAG,OAAO,IAAI,EAAE,CAAC;QAEnE,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,iBAAiB,GAAG,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC;QAC1D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,yBAAyB,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;YACnF,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,UAAU,GAAG,WAAW,GAAG,iBAAiB,CAAC;QACnD,IAAI,iBAAiB,EAAE,CAAC;YACtB,IAAI,CAAC,6BAA6B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,6BAA6B,CAAC,OAA+B,EAAE,UAAkB;QAC/E,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAC,UAAU,EAAC,CAAC;QACxE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACpE,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,MAAc,EAAE,UAAkB;QAC9C,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,EAAC,UAAU,EAAC,CAAC,CAAC;IACrD,CAAC;;AAGH,OAAO,EAAC,QAAQ,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Lantern from '../types/types.js';\n\n// A DNS lookup will usually take ~1-2 roundtrips of connection latency plus the extra DNS routing time.\n// Example: https://www.webpagetest.org/result/180703_3A_e33ec79747c002ed4d7bcbfc81462203/1/details/#waterfall_view_step1\n// Example: https://www.webpagetest.org/result/180707_1M_89673eb633b5d98386de95dfcf9b33d5/1/details/#waterfall_view_step1\n// DNS is highly variable though, many times it's a little more than 1, but can easily be 4-5x RTT.\n// We'll use 2 since it seems to give the most accurate results on average, but this can be tweaked.\nconst DNS_RESOLUTION_RTT_MULTIPLIER = 2;\n\nclass DNSCache {\n static rttMultiplier = DNS_RESOLUTION_RTT_MULTIPLIER;\n\n rtt: number;\n resolvedDomainNames: Map<string, {resolvedAt: number}>;\n\n constructor({rtt}: {rtt: number}) {\n this.rtt = rtt;\n this.resolvedDomainNames = new Map();\n }\n\n getTimeUntilResolution(\n request: Lantern.NetworkRequest, options?: {requestedAt?: number, shouldUpdateCache?: boolean}): number {\n const {requestedAt = 0, shouldUpdateCache = false} = options || {};\n\n const domain = request.parsedURL.host;\n const cacheEntry = this.resolvedDomainNames.get(domain);\n let timeUntilResolved = this.rtt * DNSCache.rttMultiplier;\n if (cacheEntry) {\n const timeUntilCachedIsResolved = Math.max(cacheEntry.resolvedAt - requestedAt, 0);\n timeUntilResolved = Math.min(timeUntilCachedIsResolved, timeUntilResolved);\n }\n\n const resolvedAt = requestedAt + timeUntilResolved;\n if (shouldUpdateCache) {\n this.updateCacheResolvedAtIfNeeded(request, resolvedAt);\n }\n\n return timeUntilResolved;\n }\n\n updateCacheResolvedAtIfNeeded(request: Lantern.NetworkRequest, resolvedAt: number): void {\n const domain = request.parsedURL.host;\n const cacheEntry = this.resolvedDomainNames.get(domain) || {resolvedAt};\n cacheEntry.resolvedAt = Math.min(cacheEntry.resolvedAt, resolvedAt);\n this.resolvedDomainNames.set(domain, cacheEntry);\n }\n\n /**\n * Forcefully sets the DNS resolution time for a request.\n * Useful for testing and alternate execution simulations.\n */\n setResolvedAt(domain: string, resolvedAt: number): void {\n this.resolvedDomainNames.set(domain, {resolvedAt});\n }\n}\n\nexport {DNSCache};\n"]}
1
+ {"version":3,"file":"DNSCache.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/DNSCache.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,6BAA6B;AAI7B,wGAAwG;AACxG,yHAAyH;AACzH,yHAAyH;AACzH,mGAAmG;AACnG,oGAAoG;AACpG,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAExC,MAAM,QAAQ;IACZ,MAAM,CAAC,aAAa,GAAG,6BAA6B,CAAC;IAErD,GAAG,CAAS;IACZ,mBAAmB,CAAoC;IAEvD,YAAY,EAAC,GAAG,EAAgB;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,mBAAmB,GAAG,IAAI,GAAG,EAAE,CAAC;IACvC,CAAC;IAED,sBAAsB,CAClB,OAA+B,EAAE,OAA6D;QAChG,MAAM,EAAC,WAAW,GAAG,CAAC,EAAE,iBAAiB,GAAG,KAAK,EAAC,GAAG,OAAO,IAAI,EAAE,CAAC;QAEnE,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,iBAAiB,GAAG,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC;QAC1D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,yBAAyB,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;YACnF,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,UAAU,GAAG,WAAW,GAAG,iBAAiB,CAAC;QACnD,IAAI,iBAAiB,EAAE,CAAC;YACtB,IAAI,CAAC,6BAA6B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,6BAA6B,CAAC,OAA+B,EAAE,UAAkB;QAC/E,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAC,UAAU,EAAC,CAAC;QACxE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACpE,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,MAAc,EAAE,UAAkB;QAC9C,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,EAAC,UAAU,EAAC,CAAC,CAAC;IACrD,CAAC;;AAGH,OAAO,EAAC,QAAQ,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Lantern from '../types/types.js';\n\n// A DNS lookup will usually take ~1-2 roundtrips of connection latency plus the extra DNS routing time.\n// Example: https://www.webpagetest.org/result/180703_3A_e33ec79747c002ed4d7bcbfc81462203/1/details/#waterfall_view_step1\n// Example: https://www.webpagetest.org/result/180707_1M_89673eb633b5d98386de95dfcf9b33d5/1/details/#waterfall_view_step1\n// DNS is highly variable though, many times it's a little more than 1, but can easily be 4-5x RTT.\n// We'll use 2 since it seems to give the most accurate results on average, but this can be tweaked.\nconst DNS_RESOLUTION_RTT_MULTIPLIER = 2;\n\nclass DNSCache {\n static rttMultiplier = DNS_RESOLUTION_RTT_MULTIPLIER;\n\n rtt: number;\n resolvedDomainNames: Map<string, {resolvedAt: number}>;\n\n constructor({rtt}: {rtt: number}) {\n this.rtt = rtt;\n this.resolvedDomainNames = new Map();\n }\n\n getTimeUntilResolution(\n request: Lantern.NetworkRequest, options?: {requestedAt?: number, shouldUpdateCache?: boolean}): number {\n const {requestedAt = 0, shouldUpdateCache = false} = options || {};\n\n const domain = request.parsedURL.host;\n const cacheEntry = this.resolvedDomainNames.get(domain);\n let timeUntilResolved = this.rtt * DNSCache.rttMultiplier;\n if (cacheEntry) {\n const timeUntilCachedIsResolved = Math.max(cacheEntry.resolvedAt - requestedAt, 0);\n timeUntilResolved = Math.min(timeUntilCachedIsResolved, timeUntilResolved);\n }\n\n const resolvedAt = requestedAt + timeUntilResolved;\n if (shouldUpdateCache) {\n this.updateCacheResolvedAtIfNeeded(request, resolvedAt);\n }\n\n return timeUntilResolved;\n }\n\n updateCacheResolvedAtIfNeeded(request: Lantern.NetworkRequest, resolvedAt: number): void {\n const domain = request.parsedURL.host;\n const cacheEntry = this.resolvedDomainNames.get(domain) || {resolvedAt};\n cacheEntry.resolvedAt = Math.min(cacheEntry.resolvedAt, resolvedAt);\n this.resolvedDomainNames.set(domain, cacheEntry);\n }\n\n /**\n * Forcefully sets the DNS resolution time for a request.\n * Useful for testing and alternate execution simulations.\n */\n setResolvedAt(domain: string, resolvedAt: number): void {\n this.resolvedDomainNames.set(domain, {resolvedAt});\n }\n}\n\nexport {DNSCache};\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SimulationTimingMap.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/SimulationTimingMap.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\n/**\n * @file\n *\n * This class encapsulates the type-related validation logic for moving timing information for nodes\n * through the different simulation phases. Methods here ensure that the invariants of simulation hold\n * as nodes are queued, partially simulated, and completed.\n */\n\nimport * as Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\n\ninterface NodeTimingComplete {\n startTime: number;\n endTime: number;\n queuedTime: number;\n estimatedTimeElapsed: number;\n timeElapsed: number;\n timeElapsedOvershoot: number;\n bytesDownloaded: number;\n}\n\ntype NodeTimingQueued = Pick<NodeTimingComplete, 'queuedTime'>;\n\ntype CpuNodeTimingStarted = NodeTimingQueued&Pick<NodeTimingComplete, 'startTime'|'timeElapsed'>;\ntype NetworkNodeTimingStarted = CpuNodeTimingStarted&Pick<NodeTimingComplete, 'timeElapsedOvershoot'|'bytesDownloaded'>;\n\ntype CpuNodeTimingInProgress = CpuNodeTimingStarted&Pick<NodeTimingComplete, 'estimatedTimeElapsed'>;\ntype NetworkNodeTimingInProgress = NetworkNodeTimingStarted&Pick<NodeTimingComplete, 'estimatedTimeElapsed'>;\n\nexport type CpuNodeTimingComplete = CpuNodeTimingInProgress&Pick<NodeTimingComplete, 'endTime'>;\nexport type NetworkNodeTimingComplete =\n NetworkNodeTimingInProgress&Pick<NodeTimingComplete, 'endTime'>&{connectionTiming: ConnectionTiming};\nexport type CompleteNodeTiming = CpuNodeTimingComplete|NetworkNodeTimingComplete;\n\ntype NodeTimingData = NodeTimingQueued|CpuNodeTimingStarted|NetworkNodeTimingStarted|CpuNodeTimingInProgress|\n NetworkNodeTimingInProgress|CpuNodeTimingComplete|NetworkNodeTimingComplete;\n\nexport interface ConnectionTiming {\n dnsResolutionTime?: number;\n connectionTime?: number;\n sslTime?: number;\n timeToFirstByte: number;\n}\n\nclass SimulatorTimingMap {\n nodeTimings: Map<Graph.Node, NodeTimingData>;\n\n constructor() {\n this.nodeTimings = new Map<Graph.Node, NodeTimingData>();\n }\n\n getNodes(): Graph.Node[] {\n return Array.from(this.nodeTimings.keys());\n }\n\n setReadyToStart(node: Graph.Node, values: {queuedTime: number}): void {\n this.nodeTimings.set(node, values);\n }\n\n setInProgress(node: Graph.Node, values: {startTime: number}): void {\n const nodeTiming = {\n ...this.getQueued(node),\n startTime: values.startTime,\n timeElapsed: 0,\n };\n\n this.nodeTimings.set(\n node,\n node.type === Graph.BaseNode.types.NETWORK ? {...nodeTiming, timeElapsedOvershoot: 0, bytesDownloaded: 0} :\n nodeTiming,\n );\n }\n\n setCompleted(node: Graph.Node, values: {endTime: number, connectionTiming?: ConnectionTiming}): void {\n const nodeTiming = {\n ...this.getInProgress(node),\n endTime: values.endTime,\n connectionTiming: values.connectionTiming,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setCpu(node: Graph.CPUNode, values: {timeElapsed: number}): void {\n const nodeTiming = {\n ...this.getCpuStarted(node),\n timeElapsed: values.timeElapsed,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setCpuEstimated(node: Graph.CPUNode, values: {estimatedTimeElapsed: number}): void {\n const nodeTiming = {\n ...this.getCpuStarted(node),\n estimatedTimeElapsed: values.estimatedTimeElapsed,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setNetwork(\n node: Graph.NetworkNode,\n values: {timeElapsed: number, timeElapsedOvershoot: number, bytesDownloaded: number}): void {\n const nodeTiming = {\n ...this.getNetworkStarted(node),\n timeElapsed: values.timeElapsed,\n timeElapsedOvershoot: values.timeElapsedOvershoot,\n bytesDownloaded: values.bytesDownloaded,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setNetworkEstimated(node: Graph.NetworkNode, values: {estimatedTimeElapsed: number}): void {\n const nodeTiming = {\n ...this.getNetworkStarted(node),\n estimatedTimeElapsed: values.estimatedTimeElapsed,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n getQueued(node: Graph.Node): NodeTimingData {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n return timing;\n }\n\n getCpuStarted(node: Graph.CPUNode): CpuNodeTimingStarted {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if ('bytesDownloaded' in timing) {\n throw new Core.LanternError(`Node ${node.id} timing not valid`);\n }\n return timing;\n }\n\n getNetworkStarted(node: Graph.NetworkNode): NetworkNodeTimingStarted {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if (!('bytesDownloaded' in timing)) {\n throw new Core.LanternError(`Node ${node.id} timing not valid`);\n }\n return timing;\n }\n\n getInProgress(node: Graph.Node): CpuNodeTimingInProgress|NetworkNodeTimingInProgress {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if (!('estimatedTimeElapsed' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet in progress`);\n }\n return timing;\n }\n\n getCompleted(node: Graph.Node): CpuNodeTimingComplete|NetworkNodeTimingComplete {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if (!('estimatedTimeElapsed' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet in progress`);\n }\n if (!('endTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet completed`);\n }\n return timing;\n }\n}\n\nexport {SimulatorTimingMap};\n"]}
1
+ {"version":3,"file":"SimulationTimingMap.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/SimulationTimingMap.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * @file\n *\n * This class encapsulates the type-related validation logic for moving timing information for nodes\n * through the different simulation phases. Methods here ensure that the invariants of simulation hold\n * as nodes are queued, partially simulated, and completed.\n */\n\nimport * as Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\n\ninterface NodeTimingComplete {\n startTime: number;\n endTime: number;\n queuedTime: number;\n estimatedTimeElapsed: number;\n timeElapsed: number;\n timeElapsedOvershoot: number;\n bytesDownloaded: number;\n}\n\ntype NodeTimingQueued = Pick<NodeTimingComplete, 'queuedTime'>;\n\ntype CpuNodeTimingStarted = NodeTimingQueued&Pick<NodeTimingComplete, 'startTime'|'timeElapsed'>;\ntype NetworkNodeTimingStarted = CpuNodeTimingStarted&Pick<NodeTimingComplete, 'timeElapsedOvershoot'|'bytesDownloaded'>;\n\ntype CpuNodeTimingInProgress = CpuNodeTimingStarted&Pick<NodeTimingComplete, 'estimatedTimeElapsed'>;\ntype NetworkNodeTimingInProgress = NetworkNodeTimingStarted&Pick<NodeTimingComplete, 'estimatedTimeElapsed'>;\n\nexport type CpuNodeTimingComplete = CpuNodeTimingInProgress&Pick<NodeTimingComplete, 'endTime'>;\nexport type NetworkNodeTimingComplete =\n NetworkNodeTimingInProgress&Pick<NodeTimingComplete, 'endTime'>&{connectionTiming: ConnectionTiming};\nexport type CompleteNodeTiming = CpuNodeTimingComplete|NetworkNodeTimingComplete;\n\ntype NodeTimingData = NodeTimingQueued|CpuNodeTimingStarted|NetworkNodeTimingStarted|CpuNodeTimingInProgress|\n NetworkNodeTimingInProgress|CpuNodeTimingComplete|NetworkNodeTimingComplete;\n\nexport interface ConnectionTiming {\n dnsResolutionTime?: number;\n connectionTime?: number;\n sslTime?: number;\n timeToFirstByte: number;\n}\n\nclass SimulatorTimingMap {\n nodeTimings: Map<Graph.Node, NodeTimingData>;\n\n constructor() {\n this.nodeTimings = new Map<Graph.Node, NodeTimingData>();\n }\n\n getNodes(): Graph.Node[] {\n return Array.from(this.nodeTimings.keys());\n }\n\n setReadyToStart(node: Graph.Node, values: {queuedTime: number}): void {\n this.nodeTimings.set(node, values);\n }\n\n setInProgress(node: Graph.Node, values: {startTime: number}): void {\n const nodeTiming = {\n ...this.getQueued(node),\n startTime: values.startTime,\n timeElapsed: 0,\n };\n\n this.nodeTimings.set(\n node,\n node.type === Graph.BaseNode.types.NETWORK ? {...nodeTiming, timeElapsedOvershoot: 0, bytesDownloaded: 0} :\n nodeTiming,\n );\n }\n\n setCompleted(node: Graph.Node, values: {endTime: number, connectionTiming?: ConnectionTiming}): void {\n const nodeTiming = {\n ...this.getInProgress(node),\n endTime: values.endTime,\n connectionTiming: values.connectionTiming,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setCpu(node: Graph.CPUNode, values: {timeElapsed: number}): void {\n const nodeTiming = {\n ...this.getCpuStarted(node),\n timeElapsed: values.timeElapsed,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setCpuEstimated(node: Graph.CPUNode, values: {estimatedTimeElapsed: number}): void {\n const nodeTiming = {\n ...this.getCpuStarted(node),\n estimatedTimeElapsed: values.estimatedTimeElapsed,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setNetwork(\n node: Graph.NetworkNode,\n values: {timeElapsed: number, timeElapsedOvershoot: number, bytesDownloaded: number}): void {\n const nodeTiming = {\n ...this.getNetworkStarted(node),\n timeElapsed: values.timeElapsed,\n timeElapsedOvershoot: values.timeElapsedOvershoot,\n bytesDownloaded: values.bytesDownloaded,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n setNetworkEstimated(node: Graph.NetworkNode, values: {estimatedTimeElapsed: number}): void {\n const nodeTiming = {\n ...this.getNetworkStarted(node),\n estimatedTimeElapsed: values.estimatedTimeElapsed,\n };\n\n this.nodeTimings.set(node, nodeTiming);\n }\n\n getQueued(node: Graph.Node): NodeTimingData {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n return timing;\n }\n\n getCpuStarted(node: Graph.CPUNode): CpuNodeTimingStarted {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if ('bytesDownloaded' in timing) {\n throw new Core.LanternError(`Node ${node.id} timing not valid`);\n }\n return timing;\n }\n\n getNetworkStarted(node: Graph.NetworkNode): NetworkNodeTimingStarted {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if (!('bytesDownloaded' in timing)) {\n throw new Core.LanternError(`Node ${node.id} timing not valid`);\n }\n return timing;\n }\n\n getInProgress(node: Graph.Node): CpuNodeTimingInProgress|NetworkNodeTimingInProgress {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if (!('estimatedTimeElapsed' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet in progress`);\n }\n return timing;\n }\n\n getCompleted(node: Graph.Node): CpuNodeTimingComplete|NetworkNodeTimingComplete {\n const timing = this.nodeTimings.get(node);\n if (!timing) {\n throw new Core.LanternError(`Node ${node.id} not yet queued`);\n }\n if (!('startTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet started`);\n }\n if (!('estimatedTimeElapsed' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet in progress`);\n }\n if (!('endTime' in timing)) {\n throw new Core.LanternError(`Node ${node.id} not yet completed`);\n }\n return timing;\n }\n}\n\nexport {SimulatorTimingMap};\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  import * as Core from '../core/core.js';
@@ -1 +1 @@
1
- {"version":3,"file":"Simulator.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/Simulator.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 Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Lantern from '../types/types.js';\n\nimport {ConnectionPool} from './ConnectionPool.js';\nimport {Constants} from './Constants.js';\nimport {DNSCache} from './DNSCache.js';\nimport {type CompleteNodeTiming, type ConnectionTiming, SimulatorTimingMap} from './SimulationTimingMap.js';\nimport {TCPConnection} from './TCPConnection.js';\n\nexport interface Result<T = Lantern.AnyNetworkObject> {\n timeInMs: number;\n nodeTimings: Map<Graph.Node<T>, Lantern.Simulation.NodeTiming>;\n}\n\nconst defaultThrottling = Constants.throttling.mobileSlow4G;\n\n// see https://cs.chromium.org/search/?q=kDefaultMaxNumDelayableRequestsPerClient&sq=package:chromium&type=cs\nconst DEFAULT_MAXIMUM_CONCURRENT_REQUESTS = 10;\n// layout tasks tend to be less CPU-bound and do not experience the same increase in duration\nconst DEFAULT_LAYOUT_TASK_MULTIPLIER = 0.5;\n// if a task takes more than 10 seconds it's usually a sign it isn't actually CPU bound and we're overestimating\nconst DEFAULT_MAXIMUM_CPU_TASK_DURATION = 10000;\n\nconst NodeState = {\n NotReadyToStart: 0,\n ReadyToStart: 1,\n InProgress: 2,\n Complete: 3,\n};\n\nconst PriorityStartTimePenalty: Record<Lantern.ResourcePriority, number> = {\n VeryHigh: 0,\n High: 0.25,\n Medium: 0.5,\n Low: 1,\n VeryLow: 2,\n};\n\nconst ALL_SIMULATION_NODE_TIMINGS = new Map<string, Map<Graph.Node, CompleteNodeTiming>>();\n\nclass Simulator<T = Lantern.AnyNetworkObject> {\n static createSimulator(settings: Lantern.Simulation.Settings): Simulator {\n const {throttlingMethod, throttling, precomputedLanternData, networkAnalysis} = settings;\n\n const options: Lantern.Simulation.Options = {\n additionalRttByOrigin: networkAnalysis.additionalRttByOrigin,\n serverResponseTimeByOrigin: networkAnalysis.serverResponseTimeByOrigin,\n observedThroughput: networkAnalysis.throughput,\n };\n\n // If we have precomputed lantern data, overwrite our observed estimates and use precomputed instead\n // for increased stability.\n if (precomputedLanternData) {\n options.additionalRttByOrigin = new Map(Object.entries(precomputedLanternData.additionalRttByOrigin));\n options.serverResponseTimeByOrigin = new Map(Object.entries(precomputedLanternData.serverResponseTimeByOrigin));\n }\n\n switch (throttlingMethod) {\n case 'provided':\n options.rtt = networkAnalysis.rtt;\n options.throughput = networkAnalysis.throughput;\n options.cpuSlowdownMultiplier = 1;\n options.layoutTaskMultiplier = 1;\n break;\n case 'devtools':\n if (throttling) {\n options.rtt = throttling.requestLatencyMs / Constants.throttling.DEVTOOLS_RTT_ADJUSTMENT_FACTOR;\n options.throughput =\n throttling.downloadThroughputKbps * 1024 / Constants.throttling.DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR;\n }\n\n options.cpuSlowdownMultiplier = 1;\n options.layoutTaskMultiplier = 1;\n break;\n case 'simulate':\n if (throttling) {\n options.rtt = throttling.rttMs;\n options.throughput = throttling.throughputKbps * 1024;\n options.cpuSlowdownMultiplier = throttling.cpuSlowdownMultiplier;\n }\n break;\n default:\n // intentionally fallback to simulator defaults\n break;\n }\n\n return new Simulator(options);\n }\n\n options: Required<Lantern.Simulation.Options>;\n _rtt: number;\n throughput: number;\n maximumConcurrentRequests: number;\n cpuSlowdownMultiplier: number;\n layoutTaskMultiplier: number;\n cachedNodeListByStartPosition: Graph.Node[];\n nodeTimings: SimulatorTimingMap;\n numberInProgressByType: Map<string, number>;\n nodes: Record<number, Set<Graph.Node>>;\n dns: DNSCache;\n connectionPool: ConnectionPool;\n\n constructor(options?: Lantern.Simulation.Options) {\n this.options = Object.assign(\n {\n rtt: defaultThrottling.rttMs,\n throughput: defaultThrottling.throughputKbps * 1024,\n maximumConcurrentRequests: DEFAULT_MAXIMUM_CONCURRENT_REQUESTS,\n cpuSlowdownMultiplier: defaultThrottling.cpuSlowdownMultiplier,\n layoutTaskMultiplier: DEFAULT_LAYOUT_TASK_MULTIPLIER,\n additionalRttByOrigin: new Map(),\n serverResponseTimeByOrigin: new Map(),\n },\n options,\n );\n\n this._rtt = this.options.rtt;\n this.throughput = this.options.throughput;\n this.maximumConcurrentRequests = Math.max(\n Math.min(\n TCPConnection.maximumSaturatedConnections(this._rtt, this.throughput),\n this.options.maximumConcurrentRequests,\n ),\n 1);\n this.cpuSlowdownMultiplier = this.options.cpuSlowdownMultiplier;\n this.layoutTaskMultiplier = this.cpuSlowdownMultiplier * this.options.layoutTaskMultiplier;\n this.cachedNodeListByStartPosition = [];\n\n // Properties reset on every `.simulate` call but duplicated here for type checking\n this.nodeTimings = new SimulatorTimingMap();\n this.numberInProgressByType = new Map<string, number>();\n this.nodes = {};\n this.dns = new DNSCache({rtt: this._rtt});\n // @ts-expect-error\n this.connectionPool = null;\n\n if (!Number.isFinite(this._rtt)) {\n throw new Core.LanternError(`Invalid rtt ${this._rtt}`);\n }\n if (!Number.isFinite(this.throughput)) {\n throw new Core.LanternError(`Invalid throughput ${this.throughput}`);\n }\n }\n\n get rtt(): number {\n return this._rtt;\n }\n\n initializeConnectionPool(graph: Graph.Node): void {\n const records: Lantern.NetworkRequest[] = [];\n graph.getRootNode().traverse(node => {\n if (node.type === Graph.BaseNode.types.NETWORK) {\n records.push(node.request);\n }\n });\n\n this.connectionPool = new ConnectionPool(records, this.options);\n }\n\n /**\n * Initializes the various state data structures such _nodeTimings and the _node Sets by state.\n */\n initializeAuxiliaryData(): void {\n this.nodeTimings = new SimulatorTimingMap();\n this.numberInProgressByType = new Map();\n\n this.nodes = {};\n this.cachedNodeListByStartPosition = [];\n // NOTE: We don't actually need *all* of these sets, but the clarity that each node progresses\n // through the system is quite nice.\n for (const state of Object.values(NodeState)) {\n this.nodes[state] = new Set();\n }\n }\n\n numberInProgress(type: string): number {\n return this.numberInProgressByType.get(type) || 0;\n }\n\n markNodeAsReadyToStart(node: Graph.Node, queuedTime: number): void {\n const nodeStartPosition = Simulator.computeNodeStartPosition(node);\n const firstNodeIndexWithGreaterStartPosition = this.cachedNodeListByStartPosition.findIndex(\n candidate => Simulator.computeNodeStartPosition(candidate) > nodeStartPosition);\n const insertionIndex = firstNodeIndexWithGreaterStartPosition === -1 ? this.cachedNodeListByStartPosition.length :\n firstNodeIndexWithGreaterStartPosition;\n this.cachedNodeListByStartPosition.splice(insertionIndex, 0, node);\n\n this.nodes[NodeState.ReadyToStart].add(node);\n this.nodes[NodeState.NotReadyToStart].delete(node);\n this.nodeTimings.setReadyToStart(node, {queuedTime});\n }\n\n markNodeAsInProgress(node: Graph.Node, startTime: number): void {\n const indexOfNodeToStart = this.cachedNodeListByStartPosition.indexOf(node);\n this.cachedNodeListByStartPosition.splice(indexOfNodeToStart, 1);\n\n this.nodes[NodeState.InProgress].add(node);\n this.nodes[NodeState.ReadyToStart].delete(node);\n this.numberInProgressByType.set(node.type, this.numberInProgress(node.type) + 1);\n this.nodeTimings.setInProgress(node, {startTime});\n }\n\n markNodeAsComplete(node: Graph.Node, endTime: number, connectionTiming?: ConnectionTiming): void {\n this.nodes[NodeState.Complete].add(node);\n this.nodes[NodeState.InProgress].delete(node);\n this.numberInProgressByType.set(node.type, this.numberInProgress(node.type) - 1);\n this.nodeTimings.setCompleted(node, {endTime, connectionTiming});\n\n // Try to add all its dependents to the queue\n for (const dependent of node.getDependents()) {\n // Skip dependent node if one of its dependencies hasn't finished yet\n const dependencies = dependent.getDependencies();\n if (dependencies.some(dep => !this.nodes[NodeState.Complete].has(dep))) {\n continue;\n }\n\n // Otherwise add it to the queue\n this.markNodeAsReadyToStart(dependent, endTime);\n }\n }\n\n acquireConnection(request: Lantern.NetworkRequest): TCPConnection|null {\n return this.connectionPool.acquire(request);\n }\n\n getNodesSortedByStartPosition(): Graph.Node[] {\n // Make a copy so we don't skip nodes due to concurrent modification\n return Array.from(this.cachedNodeListByStartPosition);\n }\n\n startNodeIfPossible(node: Graph.Node, totalElapsedTime: number): void {\n if (node.type === Graph.BaseNode.types.CPU) {\n // Start a CPU task if there's no other CPU task in process\n if (this.numberInProgress(node.type) === 0) {\n this.markNodeAsInProgress(node, totalElapsedTime);\n }\n\n return;\n }\n\n if (node.type !== Graph.BaseNode.types.NETWORK) {\n throw new Core.LanternError('Unsupported');\n }\n\n // If a network request is connectionless, we can always start it, so skip the connection checks\n if (!node.isConnectionless) {\n // Start a network request if we're not at max requests and a connection is available\n const numberOfActiveRequests = this.numberInProgress(node.type);\n if (numberOfActiveRequests >= this.maximumConcurrentRequests) {\n return;\n }\n const connection = this.acquireConnection(node.request);\n if (!connection) {\n return;\n }\n }\n\n this.markNodeAsInProgress(node, totalElapsedTime);\n }\n\n /**\n * Updates each connection in use with the available throughput based on the number of network requests\n * currently in flight.\n */\n updateNetworkCapacity(): void {\n const inFlight = this.numberInProgress(Graph.BaseNode.types.NETWORK);\n if (inFlight === 0) {\n return;\n }\n\n for (const connection of this.connectionPool.connectionsInUse()) {\n connection.setThroughput(this.throughput / inFlight);\n }\n }\n\n /**\n * Estimates the number of milliseconds remaining given current conditions before the node is complete.\n */\n estimateTimeRemaining(node: Graph.Node): number {\n if (node.type === Graph.BaseNode.types.CPU) {\n return this.estimateCPUTimeRemaining(node);\n }\n if (node.type === Graph.BaseNode.types.NETWORK) {\n return this.estimateNetworkTimeRemaining(node);\n }\n throw new Core.LanternError('Unsupported');\n }\n\n estimateCPUTimeRemaining(cpuNode: Graph.CPUNode): number {\n const timingData = this.nodeTimings.getCpuStarted(cpuNode);\n const multiplier = cpuNode.didPerformLayout() ? this.layoutTaskMultiplier : this.cpuSlowdownMultiplier;\n const totalDuration = Math.min(\n Math.round(cpuNode.duration / 1000 * multiplier),\n DEFAULT_MAXIMUM_CPU_TASK_DURATION,\n );\n const estimatedTimeElapsed = totalDuration - timingData.timeElapsed;\n this.nodeTimings.setCpuEstimated(cpuNode, {estimatedTimeElapsed});\n return estimatedTimeElapsed;\n }\n\n estimateNetworkTimeRemaining(networkNode: Graph.NetworkNode): number {\n const request = networkNode.request;\n const timingData = this.nodeTimings.getNetworkStarted(networkNode);\n\n let timeElapsed = 0;\n if (networkNode.fromDiskCache) {\n // Rough access time for seeking to location on disk and reading sequentially.\n // 8ms per seek + 20ms/MB\n // @see http://norvig.com/21-days.html#answers\n const sizeInMb = (request.resourceSize || 0) / 1024 / 1024;\n timeElapsed = 8 + 20 * sizeInMb - timingData.timeElapsed;\n } else if (networkNode.isNonNetworkProtocol) {\n // Estimates for the overhead of a data URL in Chromium and the decoding time for base64-encoded data.\n // 2ms per request + 10ms/MB\n // @see traces on https://dopiaza.org/tools/datauri/examples/index.php\n const sizeInMb = (request.resourceSize || 0) / 1024 / 1024;\n timeElapsed = 2 + 10 * sizeInMb - timingData.timeElapsed;\n } else {\n const connection = this.connectionPool.acquireActiveConnectionFromRequest(request);\n const dnsResolutionTime = this.dns.getTimeUntilResolution(request, {\n requestedAt: timingData.startTime,\n shouldUpdateCache: true,\n });\n const timeAlreadyElapsed = timingData.timeElapsed;\n const calculation = connection.simulateDownloadUntil(\n request.transferSize - timingData.bytesDownloaded,\n {timeAlreadyElapsed, dnsResolutionTime, maximumTimeToElapse: Infinity},\n );\n\n timeElapsed = calculation.timeElapsed;\n }\n\n const estimatedTimeElapsed = timeElapsed + timingData.timeElapsedOvershoot;\n this.nodeTimings.setNetworkEstimated(networkNode, {estimatedTimeElapsed});\n return estimatedTimeElapsed;\n }\n\n /**\n * Computes and returns the minimum estimated completion time of the nodes currently in progress.\n */\n findNextNodeCompletionTime(): number {\n let minimumTime = Infinity;\n for (const node of this.nodes[NodeState.InProgress]) {\n minimumTime = Math.min(minimumTime, this.estimateTimeRemaining(node));\n }\n\n return minimumTime;\n }\n\n /**\n * Given a time period, computes the progress toward completion that the node made during that time.\n */\n updateProgressMadeInTimePeriod(node: Graph.Node, timePeriodLength: number, totalElapsedTime: number): void {\n const timingData = this.nodeTimings.getInProgress(node);\n const isFinished = timingData.estimatedTimeElapsed === timePeriodLength;\n\n if (node.type === Graph.BaseNode.types.CPU || node.isConnectionless) {\n if (isFinished) {\n this.markNodeAsComplete(node, totalElapsedTime);\n } else {\n timingData.timeElapsed += timePeriodLength;\n }\n return;\n }\n\n if (node.type !== Graph.BaseNode.types.NETWORK) {\n throw new Core.LanternError('Unsupported');\n }\n if (!('bytesDownloaded' in timingData)) {\n throw new Core.LanternError('Invalid timing data');\n }\n\n const request = node.request;\n const connection = this.connectionPool.acquireActiveConnectionFromRequest(request);\n const dnsResolutionTime = this.dns.getTimeUntilResolution(request, {\n requestedAt: timingData.startTime,\n shouldUpdateCache: true,\n });\n const calculation = connection.simulateDownloadUntil(\n request.transferSize - timingData.bytesDownloaded,\n {\n dnsResolutionTime,\n timeAlreadyElapsed: timingData.timeElapsed,\n maximumTimeToElapse: timePeriodLength - timingData.timeElapsedOvershoot,\n },\n );\n\n connection.setCongestionWindow(calculation.congestionWindow);\n connection.setH2OverflowBytesDownloaded(calculation.extraBytesDownloaded);\n\n if (isFinished) {\n connection.setWarmed(true);\n this.connectionPool.release(request);\n this.markNodeAsComplete(node, totalElapsedTime, calculation.connectionTiming);\n } else {\n timingData.timeElapsed += calculation.timeElapsed;\n timingData.timeElapsedOvershoot += calculation.timeElapsed - timePeriodLength;\n timingData.bytesDownloaded += calculation.bytesDownloaded;\n }\n }\n\n computeFinalNodeTimings(): {\n nodeTimings: Map<Graph.Node, Lantern.Simulation.NodeTiming>,\n completeNodeTimings: Map<Graph.Node, CompleteNodeTiming>,\n } {\n const completeNodeTimingEntries: Array<[Graph.Node, CompleteNodeTiming]> = this.nodeTimings.getNodes().map(node => {\n return [node, this.nodeTimings.getCompleted(node)];\n });\n\n // Most consumers will want the entries sorted by startTime, so insert them in that order\n completeNodeTimingEntries.sort((a, b) => a[1].startTime - b[1].startTime);\n\n // Trimmed version of type `Lantern.Simulation.NodeTiming`.\n const nodeTimingEntries: Array<[Graph.Node, Lantern.Simulation.NodeTiming]> =\n completeNodeTimingEntries.map(([node, timing]) => {\n return [\n node,\n {\n startTime: timing.startTime,\n endTime: timing.endTime,\n duration: timing.endTime - timing.startTime,\n },\n ];\n });\n\n return {\n nodeTimings: new Map(nodeTimingEntries),\n completeNodeTimings: new Map(completeNodeTimingEntries),\n };\n }\n\n getOptions(): Required<Lantern.Simulation.Options> {\n return this.options;\n }\n\n /**\n * Estimates the time taken to process all of the graph's nodes, returns the overall time along with\n * each node annotated by start/end times.\n *\n * Simulator/connection pool are allowed to deviate from what was\n * observed in the trace/devtoolsLog and start requests as soon as they are queued (i.e. do not\n * wait around for a warm connection to be available if the original request was fetched on a warm\n * connection).\n */\n simulate(graph: Graph.Node, options?: {label?: string}): Result<T> {\n if (Graph.BaseNode.findCycle(graph)) {\n throw new Core.LanternError('Cannot simulate graph with cycle');\n }\n\n options = Object.assign(\n {\n label: undefined,\n },\n options);\n\n // initialize the necessary data containers\n this.dns = new DNSCache({rtt: this._rtt});\n this.initializeConnectionPool(graph);\n this.initializeAuxiliaryData();\n\n const nodesNotReadyToStart = this.nodes[NodeState.NotReadyToStart];\n const nodesReadyToStart = this.nodes[NodeState.ReadyToStart];\n const nodesInProgress = this.nodes[NodeState.InProgress];\n\n const rootNode = graph.getRootNode();\n rootNode.traverse(node => nodesNotReadyToStart.add(node));\n let totalElapsedTime = 0;\n let iteration = 0;\n\n // root node is always ready to start\n this.markNodeAsReadyToStart(rootNode, totalElapsedTime);\n\n // loop as long as we have nodes in the queue or currently in progress\n while (nodesReadyToStart.size || nodesInProgress.size) {\n // move all possible queued nodes to in progress\n for (const node of this.getNodesSortedByStartPosition()) {\n this.startNodeIfPossible(node, totalElapsedTime);\n }\n\n if (!nodesInProgress.size) {\n // Interplay between fromDiskCache and connectionReused can be incorrect,\n // have to give up.\n throw new Core.LanternError('Failed to start a node');\n }\n\n // set the available throughput for all connections based on # in-flight\n this.updateNetworkCapacity();\n\n // find the time that the next node will finish\n const minimumTime = this.findNextNodeCompletionTime();\n totalElapsedTime += minimumTime;\n\n // While this is no longer strictly necessary, it's always better than hanging\n if (!Number.isFinite(minimumTime) || iteration > 100000) {\n throw new Core.LanternError('Simulation failed, depth exceeded');\n }\n\n iteration++;\n // update how far each node will progress until that point\n for (const node of nodesInProgress) {\n this.updateProgressMadeInTimePeriod(node, minimumTime, totalElapsedTime);\n }\n }\n\n // `nodeTimings` are used for simulator consumers, `completeNodeTimings` kept for debugging.\n const {nodeTimings, completeNodeTimings} = this.computeFinalNodeTimings();\n ALL_SIMULATION_NODE_TIMINGS.set(options.label || 'unlabeled', completeNodeTimings);\n\n return {\n timeInMs: totalElapsedTime,\n nodeTimings,\n };\n }\n\n computeWastedMsFromWastedBytes(wastedBytes: number): number {\n const {throughput, observedThroughput} = this.options;\n\n // https://github.com/GoogleChrome/lighthouse/pull/13323#issuecomment-962031709\n // 0 throughput means the no (additional) throttling is expected.\n // This is common for desktop + devtools throttling where throttling is additive and we don't want any additional.\n const bitsPerSecond = throughput === 0 ? observedThroughput : throughput;\n if (bitsPerSecond === 0) {\n return 0;\n }\n\n const wastedBits = wastedBytes * 8;\n const wastedMs = wastedBits / bitsPerSecond * 1000;\n\n // This is an estimate of wasted time, so we won't be more precise than 10ms.\n return Math.round(wastedMs / 10) * 10;\n }\n\n // Used by Lighthouse asset-saver\n static get allNodeTimings(): Map<string, Map<Graph.Node, CompleteNodeTiming>> {\n return ALL_SIMULATION_NODE_TIMINGS;\n }\n\n /**\n * We attempt to start nodes by their observed start time using the request priority as a tie breaker.\n * When simulating, just because a low priority image started 5ms before a high priority image doesn't mean\n * it would have happened like that when the network was slower.\n */\n static computeNodeStartPosition(node: Graph.Node): number {\n if (node.type === 'cpu') {\n return node.startTime;\n }\n return node.startTime + (PriorityStartTimePenalty[node.request.priority] * 1000 * 1000 || 0);\n }\n}\n\nexport {Simulator};\n"]}
1
+ {"version":3,"file":"Simulator.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/simulation/Simulator.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors\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 Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Lantern from '../types/types.js';\n\nimport {ConnectionPool} from './ConnectionPool.js';\nimport {Constants} from './Constants.js';\nimport {DNSCache} from './DNSCache.js';\nimport {type CompleteNodeTiming, type ConnectionTiming, SimulatorTimingMap} from './SimulationTimingMap.js';\nimport {TCPConnection} from './TCPConnection.js';\n\nexport interface Result<T = Lantern.AnyNetworkObject> {\n timeInMs: number;\n nodeTimings: Map<Graph.Node<T>, Lantern.Simulation.NodeTiming>;\n}\n\nconst defaultThrottling = Constants.throttling.mobileSlow4G;\n\n// see https://cs.chromium.org/search/?q=kDefaultMaxNumDelayableRequestsPerClient&sq=package:chromium&type=cs\nconst DEFAULT_MAXIMUM_CONCURRENT_REQUESTS = 10;\n// layout tasks tend to be less CPU-bound and do not experience the same increase in duration\nconst DEFAULT_LAYOUT_TASK_MULTIPLIER = 0.5;\n// if a task takes more than 10 seconds it's usually a sign it isn't actually CPU bound and we're overestimating\nconst DEFAULT_MAXIMUM_CPU_TASK_DURATION = 10000;\n\nconst NodeState = {\n NotReadyToStart: 0,\n ReadyToStart: 1,\n InProgress: 2,\n Complete: 3,\n};\n\nconst PriorityStartTimePenalty: Record<Lantern.ResourcePriority, number> = {\n VeryHigh: 0,\n High: 0.25,\n Medium: 0.5,\n Low: 1,\n VeryLow: 2,\n};\n\nconst ALL_SIMULATION_NODE_TIMINGS = new Map<string, Map<Graph.Node, CompleteNodeTiming>>();\n\nclass Simulator<T = Lantern.AnyNetworkObject> {\n static createSimulator(settings: Lantern.Simulation.Settings): Simulator {\n const {throttlingMethod, throttling, precomputedLanternData, networkAnalysis} = settings;\n\n const options: Lantern.Simulation.Options = {\n additionalRttByOrigin: networkAnalysis.additionalRttByOrigin,\n serverResponseTimeByOrigin: networkAnalysis.serverResponseTimeByOrigin,\n observedThroughput: networkAnalysis.throughput,\n };\n\n // If we have precomputed lantern data, overwrite our observed estimates and use precomputed instead\n // for increased stability.\n if (precomputedLanternData) {\n options.additionalRttByOrigin = new Map(Object.entries(precomputedLanternData.additionalRttByOrigin));\n options.serverResponseTimeByOrigin = new Map(Object.entries(precomputedLanternData.serverResponseTimeByOrigin));\n }\n\n switch (throttlingMethod) {\n case 'provided':\n options.rtt = networkAnalysis.rtt;\n options.throughput = networkAnalysis.throughput;\n options.cpuSlowdownMultiplier = 1;\n options.layoutTaskMultiplier = 1;\n break;\n case 'devtools':\n if (throttling) {\n options.rtt = throttling.requestLatencyMs / Constants.throttling.DEVTOOLS_RTT_ADJUSTMENT_FACTOR;\n options.throughput =\n throttling.downloadThroughputKbps * 1024 / Constants.throttling.DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR;\n }\n\n options.cpuSlowdownMultiplier = 1;\n options.layoutTaskMultiplier = 1;\n break;\n case 'simulate':\n if (throttling) {\n options.rtt = throttling.rttMs;\n options.throughput = throttling.throughputKbps * 1024;\n options.cpuSlowdownMultiplier = throttling.cpuSlowdownMultiplier;\n }\n break;\n default:\n // intentionally fallback to simulator defaults\n break;\n }\n\n return new Simulator(options);\n }\n\n options: Required<Lantern.Simulation.Options>;\n _rtt: number;\n throughput: number;\n maximumConcurrentRequests: number;\n cpuSlowdownMultiplier: number;\n layoutTaskMultiplier: number;\n cachedNodeListByStartPosition: Graph.Node[];\n nodeTimings: SimulatorTimingMap;\n numberInProgressByType: Map<string, number>;\n nodes: Record<number, Set<Graph.Node>>;\n dns: DNSCache;\n connectionPool: ConnectionPool;\n\n constructor(options?: Lantern.Simulation.Options) {\n this.options = Object.assign(\n {\n rtt: defaultThrottling.rttMs,\n throughput: defaultThrottling.throughputKbps * 1024,\n maximumConcurrentRequests: DEFAULT_MAXIMUM_CONCURRENT_REQUESTS,\n cpuSlowdownMultiplier: defaultThrottling.cpuSlowdownMultiplier,\n layoutTaskMultiplier: DEFAULT_LAYOUT_TASK_MULTIPLIER,\n additionalRttByOrigin: new Map(),\n serverResponseTimeByOrigin: new Map(),\n },\n options,\n );\n\n this._rtt = this.options.rtt;\n this.throughput = this.options.throughput;\n this.maximumConcurrentRequests = Math.max(\n Math.min(\n TCPConnection.maximumSaturatedConnections(this._rtt, this.throughput),\n this.options.maximumConcurrentRequests,\n ),\n 1);\n this.cpuSlowdownMultiplier = this.options.cpuSlowdownMultiplier;\n this.layoutTaskMultiplier = this.cpuSlowdownMultiplier * this.options.layoutTaskMultiplier;\n this.cachedNodeListByStartPosition = [];\n\n // Properties reset on every `.simulate` call but duplicated here for type checking\n this.nodeTimings = new SimulatorTimingMap();\n this.numberInProgressByType = new Map<string, number>();\n this.nodes = {};\n this.dns = new DNSCache({rtt: this._rtt});\n // @ts-expect-error\n this.connectionPool = null;\n\n if (!Number.isFinite(this._rtt)) {\n throw new Core.LanternError(`Invalid rtt ${this._rtt}`);\n }\n if (!Number.isFinite(this.throughput)) {\n throw new Core.LanternError(`Invalid throughput ${this.throughput}`);\n }\n }\n\n get rtt(): number {\n return this._rtt;\n }\n\n initializeConnectionPool(graph: Graph.Node): void {\n const records: Lantern.NetworkRequest[] = [];\n graph.getRootNode().traverse(node => {\n if (node.type === Graph.BaseNode.types.NETWORK) {\n records.push(node.request);\n }\n });\n\n this.connectionPool = new ConnectionPool(records, this.options);\n }\n\n /**\n * Initializes the various state data structures such _nodeTimings and the _node Sets by state.\n */\n initializeAuxiliaryData(): void {\n this.nodeTimings = new SimulatorTimingMap();\n this.numberInProgressByType = new Map();\n\n this.nodes = {};\n this.cachedNodeListByStartPosition = [];\n // NOTE: We don't actually need *all* of these sets, but the clarity that each node progresses\n // through the system is quite nice.\n for (const state of Object.values(NodeState)) {\n this.nodes[state] = new Set();\n }\n }\n\n numberInProgress(type: string): number {\n return this.numberInProgressByType.get(type) || 0;\n }\n\n markNodeAsReadyToStart(node: Graph.Node, queuedTime: number): void {\n const nodeStartPosition = Simulator.computeNodeStartPosition(node);\n const firstNodeIndexWithGreaterStartPosition = this.cachedNodeListByStartPosition.findIndex(\n candidate => Simulator.computeNodeStartPosition(candidate) > nodeStartPosition);\n const insertionIndex = firstNodeIndexWithGreaterStartPosition === -1 ? this.cachedNodeListByStartPosition.length :\n firstNodeIndexWithGreaterStartPosition;\n this.cachedNodeListByStartPosition.splice(insertionIndex, 0, node);\n\n this.nodes[NodeState.ReadyToStart].add(node);\n this.nodes[NodeState.NotReadyToStart].delete(node);\n this.nodeTimings.setReadyToStart(node, {queuedTime});\n }\n\n markNodeAsInProgress(node: Graph.Node, startTime: number): void {\n const indexOfNodeToStart = this.cachedNodeListByStartPosition.indexOf(node);\n this.cachedNodeListByStartPosition.splice(indexOfNodeToStart, 1);\n\n this.nodes[NodeState.InProgress].add(node);\n this.nodes[NodeState.ReadyToStart].delete(node);\n this.numberInProgressByType.set(node.type, this.numberInProgress(node.type) + 1);\n this.nodeTimings.setInProgress(node, {startTime});\n }\n\n markNodeAsComplete(node: Graph.Node, endTime: number, connectionTiming?: ConnectionTiming): void {\n this.nodes[NodeState.Complete].add(node);\n this.nodes[NodeState.InProgress].delete(node);\n this.numberInProgressByType.set(node.type, this.numberInProgress(node.type) - 1);\n this.nodeTimings.setCompleted(node, {endTime, connectionTiming});\n\n // Try to add all its dependents to the queue\n for (const dependent of node.getDependents()) {\n // Skip dependent node if one of its dependencies hasn't finished yet\n const dependencies = dependent.getDependencies();\n if (dependencies.some(dep => !this.nodes[NodeState.Complete].has(dep))) {\n continue;\n }\n\n // Otherwise add it to the queue\n this.markNodeAsReadyToStart(dependent, endTime);\n }\n }\n\n acquireConnection(request: Lantern.NetworkRequest): TCPConnection|null {\n return this.connectionPool.acquire(request);\n }\n\n getNodesSortedByStartPosition(): Graph.Node[] {\n // Make a copy so we don't skip nodes due to concurrent modification\n return Array.from(this.cachedNodeListByStartPosition);\n }\n\n startNodeIfPossible(node: Graph.Node, totalElapsedTime: number): void {\n if (node.type === Graph.BaseNode.types.CPU) {\n // Start a CPU task if there's no other CPU task in process\n if (this.numberInProgress(node.type) === 0) {\n this.markNodeAsInProgress(node, totalElapsedTime);\n }\n\n return;\n }\n\n if (node.type !== Graph.BaseNode.types.NETWORK) {\n throw new Core.LanternError('Unsupported');\n }\n\n // If a network request is connectionless, we can always start it, so skip the connection checks\n if (!node.isConnectionless) {\n // Start a network request if we're not at max requests and a connection is available\n const numberOfActiveRequests = this.numberInProgress(node.type);\n if (numberOfActiveRequests >= this.maximumConcurrentRequests) {\n return;\n }\n const connection = this.acquireConnection(node.request);\n if (!connection) {\n return;\n }\n }\n\n this.markNodeAsInProgress(node, totalElapsedTime);\n }\n\n /**\n * Updates each connection in use with the available throughput based on the number of network requests\n * currently in flight.\n */\n updateNetworkCapacity(): void {\n const inFlight = this.numberInProgress(Graph.BaseNode.types.NETWORK);\n if (inFlight === 0) {\n return;\n }\n\n for (const connection of this.connectionPool.connectionsInUse()) {\n connection.setThroughput(this.throughput / inFlight);\n }\n }\n\n /**\n * Estimates the number of milliseconds remaining given current conditions before the node is complete.\n */\n estimateTimeRemaining(node: Graph.Node): number {\n if (node.type === Graph.BaseNode.types.CPU) {\n return this.estimateCPUTimeRemaining(node);\n }\n if (node.type === Graph.BaseNode.types.NETWORK) {\n return this.estimateNetworkTimeRemaining(node);\n }\n throw new Core.LanternError('Unsupported');\n }\n\n estimateCPUTimeRemaining(cpuNode: Graph.CPUNode): number {\n const timingData = this.nodeTimings.getCpuStarted(cpuNode);\n const multiplier = cpuNode.didPerformLayout() ? this.layoutTaskMultiplier : this.cpuSlowdownMultiplier;\n const totalDuration = Math.min(\n Math.round(cpuNode.duration / 1000 * multiplier),\n DEFAULT_MAXIMUM_CPU_TASK_DURATION,\n );\n const estimatedTimeElapsed = totalDuration - timingData.timeElapsed;\n this.nodeTimings.setCpuEstimated(cpuNode, {estimatedTimeElapsed});\n return estimatedTimeElapsed;\n }\n\n estimateNetworkTimeRemaining(networkNode: Graph.NetworkNode): number {\n const request = networkNode.request;\n const timingData = this.nodeTimings.getNetworkStarted(networkNode);\n\n let timeElapsed = 0;\n if (networkNode.fromDiskCache) {\n // Rough access time for seeking to location on disk and reading sequentially.\n // 8ms per seek + 20ms/MB\n // @see http://norvig.com/21-days.html#answers\n const sizeInMb = (request.resourceSize || 0) / 1024 / 1024;\n timeElapsed = 8 + 20 * sizeInMb - timingData.timeElapsed;\n } else if (networkNode.isNonNetworkProtocol) {\n // Estimates for the overhead of a data URL in Chromium and the decoding time for base64-encoded data.\n // 2ms per request + 10ms/MB\n // @see traces on https://dopiaza.org/tools/datauri/examples/index.php\n const sizeInMb = (request.resourceSize || 0) / 1024 / 1024;\n timeElapsed = 2 + 10 * sizeInMb - timingData.timeElapsed;\n } else {\n const connection = this.connectionPool.acquireActiveConnectionFromRequest(request);\n const dnsResolutionTime = this.dns.getTimeUntilResolution(request, {\n requestedAt: timingData.startTime,\n shouldUpdateCache: true,\n });\n const timeAlreadyElapsed = timingData.timeElapsed;\n const calculation = connection.simulateDownloadUntil(\n request.transferSize - timingData.bytesDownloaded,\n {timeAlreadyElapsed, dnsResolutionTime, maximumTimeToElapse: Infinity},\n );\n\n timeElapsed = calculation.timeElapsed;\n }\n\n const estimatedTimeElapsed = timeElapsed + timingData.timeElapsedOvershoot;\n this.nodeTimings.setNetworkEstimated(networkNode, {estimatedTimeElapsed});\n return estimatedTimeElapsed;\n }\n\n /**\n * Computes and returns the minimum estimated completion time of the nodes currently in progress.\n */\n findNextNodeCompletionTime(): number {\n let minimumTime = Infinity;\n for (const node of this.nodes[NodeState.InProgress]) {\n minimumTime = Math.min(minimumTime, this.estimateTimeRemaining(node));\n }\n\n return minimumTime;\n }\n\n /**\n * Given a time period, computes the progress toward completion that the node made during that time.\n */\n updateProgressMadeInTimePeriod(node: Graph.Node, timePeriodLength: number, totalElapsedTime: number): void {\n const timingData = this.nodeTimings.getInProgress(node);\n const isFinished = timingData.estimatedTimeElapsed === timePeriodLength;\n\n if (node.type === Graph.BaseNode.types.CPU || node.isConnectionless) {\n if (isFinished) {\n this.markNodeAsComplete(node, totalElapsedTime);\n } else {\n timingData.timeElapsed += timePeriodLength;\n }\n return;\n }\n\n if (node.type !== Graph.BaseNode.types.NETWORK) {\n throw new Core.LanternError('Unsupported');\n }\n if (!('bytesDownloaded' in timingData)) {\n throw new Core.LanternError('Invalid timing data');\n }\n\n const request = node.request;\n const connection = this.connectionPool.acquireActiveConnectionFromRequest(request);\n const dnsResolutionTime = this.dns.getTimeUntilResolution(request, {\n requestedAt: timingData.startTime,\n shouldUpdateCache: true,\n });\n const calculation = connection.simulateDownloadUntil(\n request.transferSize - timingData.bytesDownloaded,\n {\n dnsResolutionTime,\n timeAlreadyElapsed: timingData.timeElapsed,\n maximumTimeToElapse: timePeriodLength - timingData.timeElapsedOvershoot,\n },\n );\n\n connection.setCongestionWindow(calculation.congestionWindow);\n connection.setH2OverflowBytesDownloaded(calculation.extraBytesDownloaded);\n\n if (isFinished) {\n connection.setWarmed(true);\n this.connectionPool.release(request);\n this.markNodeAsComplete(node, totalElapsedTime, calculation.connectionTiming);\n } else {\n timingData.timeElapsed += calculation.timeElapsed;\n timingData.timeElapsedOvershoot += calculation.timeElapsed - timePeriodLength;\n timingData.bytesDownloaded += calculation.bytesDownloaded;\n }\n }\n\n computeFinalNodeTimings(): {\n nodeTimings: Map<Graph.Node, Lantern.Simulation.NodeTiming>,\n completeNodeTimings: Map<Graph.Node, CompleteNodeTiming>,\n } {\n const completeNodeTimingEntries: Array<[Graph.Node, CompleteNodeTiming]> = this.nodeTimings.getNodes().map(node => {\n return [node, this.nodeTimings.getCompleted(node)];\n });\n\n // Most consumers will want the entries sorted by startTime, so insert them in that order\n completeNodeTimingEntries.sort((a, b) => a[1].startTime - b[1].startTime);\n\n // Trimmed version of type `Lantern.Simulation.NodeTiming`.\n const nodeTimingEntries: Array<[Graph.Node, Lantern.Simulation.NodeTiming]> =\n completeNodeTimingEntries.map(([node, timing]) => {\n return [\n node,\n {\n startTime: timing.startTime,\n endTime: timing.endTime,\n duration: timing.endTime - timing.startTime,\n },\n ];\n });\n\n return {\n nodeTimings: new Map(nodeTimingEntries),\n completeNodeTimings: new Map(completeNodeTimingEntries),\n };\n }\n\n getOptions(): Required<Lantern.Simulation.Options> {\n return this.options;\n }\n\n /**\n * Estimates the time taken to process all of the graph's nodes, returns the overall time along with\n * each node annotated by start/end times.\n *\n * Simulator/connection pool are allowed to deviate from what was\n * observed in the trace/devtoolsLog and start requests as soon as they are queued (i.e. do not\n * wait around for a warm connection to be available if the original request was fetched on a warm\n * connection).\n */\n simulate(graph: Graph.Node, options?: {label?: string}): Result<T> {\n if (Graph.BaseNode.findCycle(graph)) {\n throw new Core.LanternError('Cannot simulate graph with cycle');\n }\n\n options = Object.assign(\n {\n label: undefined,\n },\n options);\n\n // initialize the necessary data containers\n this.dns = new DNSCache({rtt: this._rtt});\n this.initializeConnectionPool(graph);\n this.initializeAuxiliaryData();\n\n const nodesNotReadyToStart = this.nodes[NodeState.NotReadyToStart];\n const nodesReadyToStart = this.nodes[NodeState.ReadyToStart];\n const nodesInProgress = this.nodes[NodeState.InProgress];\n\n const rootNode = graph.getRootNode();\n rootNode.traverse(node => nodesNotReadyToStart.add(node));\n let totalElapsedTime = 0;\n let iteration = 0;\n\n // root node is always ready to start\n this.markNodeAsReadyToStart(rootNode, totalElapsedTime);\n\n // loop as long as we have nodes in the queue or currently in progress\n while (nodesReadyToStart.size || nodesInProgress.size) {\n // move all possible queued nodes to in progress\n for (const node of this.getNodesSortedByStartPosition()) {\n this.startNodeIfPossible(node, totalElapsedTime);\n }\n\n if (!nodesInProgress.size) {\n // Interplay between fromDiskCache and connectionReused can be incorrect,\n // have to give up.\n throw new Core.LanternError('Failed to start a node');\n }\n\n // set the available throughput for all connections based on # in-flight\n this.updateNetworkCapacity();\n\n // find the time that the next node will finish\n const minimumTime = this.findNextNodeCompletionTime();\n totalElapsedTime += minimumTime;\n\n // While this is no longer strictly necessary, it's always better than hanging\n if (!Number.isFinite(minimumTime) || iteration > 100000) {\n throw new Core.LanternError('Simulation failed, depth exceeded');\n }\n\n iteration++;\n // update how far each node will progress until that point\n for (const node of nodesInProgress) {\n this.updateProgressMadeInTimePeriod(node, minimumTime, totalElapsedTime);\n }\n }\n\n // `nodeTimings` are used for simulator consumers, `completeNodeTimings` kept for debugging.\n const {nodeTimings, completeNodeTimings} = this.computeFinalNodeTimings();\n ALL_SIMULATION_NODE_TIMINGS.set(options.label || 'unlabeled', completeNodeTimings);\n\n return {\n timeInMs: totalElapsedTime,\n nodeTimings,\n };\n }\n\n computeWastedMsFromWastedBytes(wastedBytes: number): number {\n const {throughput, observedThroughput} = this.options;\n\n // https://github.com/GoogleChrome/lighthouse/pull/13323#issuecomment-962031709\n // 0 throughput means the no (additional) throttling is expected.\n // This is common for desktop + devtools throttling where throttling is additive and we don't want any additional.\n const bitsPerSecond = throughput === 0 ? observedThroughput : throughput;\n if (bitsPerSecond === 0) {\n return 0;\n }\n\n const wastedBits = wastedBytes * 8;\n const wastedMs = wastedBits / bitsPerSecond * 1000;\n\n // This is an estimate of wasted time, so we won't be more precise than 10ms.\n return Math.round(wastedMs / 10) * 10;\n }\n\n // Used by Lighthouse asset-saver\n static get allNodeTimings(): Map<string, Map<Graph.Node, CompleteNodeTiming>> {\n return ALL_SIMULATION_NODE_TIMINGS;\n }\n\n /**\n * We attempt to start nodes by their observed start time using the request priority as a tie breaker.\n * When simulating, just because a low priority image started 5ms before a high priority image doesn't mean\n * it would have happened like that when the network was slower.\n */\n static computeNodeStartPosition(node: Graph.Node): number {\n if (node.type === 'cpu') {\n return node.startTime;\n }\n return node.startTime + (PriorityStartTimePenalty[node.request.priority] * 1000 * 1000 || 0);\n }\n}\n\nexport {Simulator};\n"]}
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Chromium Authors. All rights reserved.
1
+ // Copyright 2024 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  const INITIAL_CONGESTION_WINDOW = 10;