chrome-devtools-frontend 1.0.1536371 → 1.0.1537860

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 (231) hide show
  1. package/.env.template +9 -0
  2. package/docs/get_the_code.md +27 -0
  3. package/front_end/core/common/SettingRegistration.ts +10 -7
  4. package/front_end/core/common/Settings.ts +3 -0
  5. package/front_end/core/host/AidaClient.ts +64 -5
  6. package/front_end/core/host/DispatchHttpRequestClient.ts +62 -0
  7. package/front_end/core/host/GdpClient.ts +8 -57
  8. package/front_end/core/host/host.ts +2 -0
  9. package/front_end/core/protocol_client/CDPConnection.ts +10 -8
  10. package/front_end/core/protocol_client/InspectorBackend.ts +36 -42
  11. package/front_end/core/sdk/EnhancedTracesParser.ts +20 -5
  12. package/front_end/core/sdk/RehydratingConnection.ts +112 -4
  13. package/front_end/core/sdk/RehydratingObject.ts +8 -0
  14. package/front_end/core/sdk/TraceObject.ts +5 -1
  15. package/front_end/core/sdk/sdk-meta.ts +8 -2
  16. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +4 -3
  17. package/front_end/generated/SupportedCSSProperties.js +1 -0
  18. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +23 -7
  19. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +110 -5
  20. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +50 -45
  21. package/front_end/models/cpu_profile/ProfileTreeModel.ts +7 -7
  22. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  23. package/front_end/models/trace/types/File.ts +9 -0
  24. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +1 -1
  25. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -9
  26. package/front_end/panels/ai_assistance/components/ChatView.ts +58 -70
  27. package/front_end/panels/application/BackForwardCacheTreeElement.ts +2 -6
  28. package/front_end/panels/application/StorageView.ts +3 -2
  29. package/front_end/panels/application/components/BackForwardCacheView.ts +96 -108
  30. package/front_end/panels/application/components/FrameDetailsView.ts +8 -11
  31. package/front_end/panels/application/components/OriginTrialTreeView.ts +136 -137
  32. package/front_end/panels/application/components/backForwardCacheView.css +8 -0
  33. package/front_end/panels/application/components/badge.css +9 -1
  34. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +2 -2
  35. package/front_end/panels/application/preloading/components/PreloadingString.ts +27 -0
  36. package/front_end/panels/autofill/AutofillView.ts +1 -1
  37. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +44 -53
  38. package/front_end/panels/console/ConsoleView.ts +11 -9
  39. package/front_end/panels/coverage/CoverageView.ts +1 -2
  40. package/front_end/panels/css_overview/CSSOverviewSidebarPanel.ts +1 -1
  41. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +1 -1
  42. package/front_end/panels/elements/ElementStatePaneWidget.ts +1 -1
  43. package/front_end/panels/elements/EventListenersWidget.ts +1 -2
  44. package/front_end/panels/elements/PropertiesWidget.ts +1 -1
  45. package/front_end/panels/network/NetworkConfigView.ts +2 -1
  46. package/front_end/panels/network/NetworkPanel.ts +5 -4
  47. package/front_end/panels/network/RequestCookiesView.ts +2 -1
  48. package/front_end/panels/profiler/HeapSnapshotView.ts +3 -2
  49. package/front_end/panels/recorder/RecorderController.ts +1 -2
  50. package/front_end/panels/recorder/components/CreateRecordingView.ts +153 -129
  51. package/front_end/panels/sensors/SensorsView.ts +4 -3
  52. package/front_end/panels/settings/AISettingsTab.ts +162 -171
  53. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +8 -6
  54. package/front_end/panels/settings/KeybindsSettingsTab.ts +3 -2
  55. package/front_end/panels/settings/SettingsScreen.ts +5 -8
  56. package/front_end/panels/settings/WorkspaceSettingsTab.ts +1 -1
  57. package/front_end/panels/settings/aiSettingsTab.css +151 -148
  58. package/front_end/panels/settings/settings-meta.ts +1 -2
  59. package/front_end/panels/sources/AddSourceMapURLDialog.ts +23 -26
  60. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -1
  61. package/front_end/panels/sources/SourcesPanel.ts +2 -1
  62. package/front_end/panels/sources/sources-meta.ts +8 -1
  63. package/front_end/panels/timeline/TimelinePanel.ts +64 -14
  64. package/front_end/panels/timeline/TimelineUIUtils.ts +4 -20
  65. package/front_end/panels/timeline/components/ExportTraceOptions.ts +33 -34
  66. package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -0
  67. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +2 -0
  68. package/front_end/third_party/chromium/README.chromium +2 -2
  69. package/front_end/third_party/puppeteer/README.chromium +2 -2
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +9 -1
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts +2 -2
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts.map +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.js.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +13 -1
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts +2 -2
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js +5 -2
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js.map +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +2 -2
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -1
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +1 -12
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +6 -0
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -0
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +2 -2
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts +2 -1
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +2 -2
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +2 -2
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -1
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts +2 -2
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js +3 -1
  113. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts +1 -0
  115. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts.map +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js +1 -0
  117. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +28 -3
  121. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21 -10
  122. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +9 -1
  123. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
  124. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts +2 -2
  126. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.js.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +13 -1
  131. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts +2 -2
  134. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js +5 -2
  136. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js.map +1 -1
  137. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +2 -2
  138. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  139. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -1
  140. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts +1 -12
  142. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +6 -0
  144. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -0
  146. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +2 -2
  148. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -1
  150. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts +2 -1
  152. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  153. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +2 -2
  154. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
  155. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +2 -2
  156. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  157. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +3 -1
  158. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  159. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  160. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  161. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts +2 -2
  163. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts.map +1 -1
  164. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js +2 -2
  165. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js.map +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts +1 -0
  167. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts.map +1 -1
  168. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js +1 -0
  169. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js.map +1 -1
  170. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  171. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  172. package/front_end/third_party/puppeteer/package/lib/types.d.ts +28 -3
  173. package/front_end/third_party/puppeteer/package/package.json +2 -2
  174. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +13 -1
  175. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +7 -2
  176. package/front_end/third_party/puppeteer/package/src/api/Page.ts +14 -1
  177. package/front_end/third_party/puppeteer/package/src/bidi/BrowserContext.ts +8 -5
  178. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +5 -2
  179. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +8 -0
  180. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +11 -2
  181. package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +3 -2
  182. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +5 -5
  183. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  184. package/front_end/third_party/puppeteer/package/src/util/disposable.ts +2 -2
  185. package/front_end/third_party/puppeteer/package/src/util/util.ts +1 -0
  186. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  187. package/front_end/ui/components/adorners/Adorner.ts +2 -1
  188. package/front_end/ui/components/buttons/Button.docs.ts +195 -0
  189. package/front_end/ui/components/settings/SettingCheckbox.ts +49 -14
  190. package/front_end/ui/components/settings/settingCheckbox.css +6 -1
  191. package/front_end/ui/components/spinners/Spinners.docs.ts +13 -0
  192. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +280 -0
  193. package/front_end/ui/components/text_editor/text_editor.ts +1 -0
  194. package/front_end/ui/components/tooltips/Tooltip.docs.ts +76 -0
  195. package/front_end/ui/components/tooltips/Tooltip.ts +1 -1
  196. package/front_end/ui/legacy/Dialog.ts +0 -1
  197. package/front_end/ui/legacy/FilterBar.ts +1 -2
  198. package/front_end/ui/legacy/RadioButton.docs.ts +41 -0
  199. package/front_end/ui/legacy/SelectMenu.docs.ts +98 -0
  200. package/front_end/ui/legacy/Toolbar.ts +4 -6
  201. package/front_end/ui/legacy/UIUtils.ts +114 -1
  202. package/front_end/ui/legacy/Widget.ts +62 -34
  203. package/front_end/ui/legacy/XLink.ts +0 -3
  204. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +9 -0
  205. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +125 -0
  206. package/front_end/ui/legacy/components/settings_ui/settings_ui.ts +8 -0
  207. package/front_end/ui/legacy/components/utils/Linkifier.ts +9 -3
  208. package/front_end/ui/legacy/legacy.ts +0 -2
  209. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -1
  210. package/mcp/mcp.ts +5 -0
  211. package/package.json +1 -1
  212. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +0 -4
  213. package/front_end/models/trace/lantern/testing/MetricTestUtils.ts +0 -62
  214. package/front_end/models/trace/lantern/testing/testing.ts +0 -5
  215. package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.html +0 -20
  216. package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.ts +0 -25
  217. package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.html +0 -20
  218. package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.ts +0 -36
  219. package/front_end/ui/components/docs/button/basic.html +0 -44
  220. package/front_end/ui/components/docs/button/basic.ts +0 -175
  221. package/front_end/ui/components/docs/radio_button/basic.html +0 -23
  222. package/front_end/ui/components/docs/radio_button/basic.ts +0 -50
  223. package/front_end/ui/components/docs/select_menu/basic.html +0 -19
  224. package/front_end/ui/components/docs/select_menu/basic.ts +0 -95
  225. package/front_end/ui/components/docs/select_menu/wide-option.html +0 -38
  226. package/front_end/ui/components/docs/select_menu/wide-option.ts +0 -43
  227. package/front_end/ui/components/docs/spinners/basic.html +0 -17
  228. package/front_end/ui/components/docs/spinners/basic.ts +0 -22
  229. package/front_end/ui/components/docs/tooltip/basic.html +0 -20
  230. package/front_end/ui/components/docs/tooltip/basic.ts +0 -82
  231. package/front_end/ui/legacy/SettingsUI.ts +0 -254
@@ -32,8 +32,8 @@ import * as Root from '../root/root.js';
32
32
 
33
33
  import * as EnhancedTraces from './EnhancedTracesParser.js';
34
34
  import type {
35
- ProtocolMessage, RehydratingExecutionContext, RehydratingScript, RehydratingTarget, ServerMessage} from
36
- './RehydratingObject.js';
35
+ ProtocolMessage, RehydratingExecutionContext, RehydratingResource, RehydratingScript, RehydratingTarget,
36
+ ServerMessage} from './RehydratingObject.js';
37
37
  import {TraceObject} from './TraceObject.js';
38
38
 
39
39
  const UIStrings = {
@@ -157,6 +157,7 @@ export class RehydratingConnection implements ProtocolClient.ConnectionTransport
157
157
  const target = hydratingDataPerTarget.target;
158
158
  const executionContexts = hydratingDataPerTarget.executionContexts;
159
159
  const scripts = hydratingDataPerTarget.scripts;
160
+ const resources = hydratingDataPerTarget.resources;
160
161
  this.postToFrontend({
161
162
  method: 'Target.targetCreated',
162
163
  params: {
@@ -172,7 +173,7 @@ export class RehydratingConnection implements ProtocolClient.ConnectionTransport
172
173
  });
173
174
 
174
175
  sessionId += 1;
175
- const session = new RehydratingSession(sessionId, target, executionContexts, scripts, this);
176
+ const session = new RehydratingSession(sessionId, target, executionContexts, scripts, resources, this);
176
177
  this.sessions.set(sessionId, session);
177
178
  session.declareSessionAttachedToTarget();
178
179
  }
@@ -267,15 +268,17 @@ export class RehydratingSession extends RehydratingSessionBase {
267
268
  target: RehydratingTarget;
268
269
  executionContexts: RehydratingExecutionContext[] = [];
269
270
  scripts: RehydratingScript[] = [];
271
+ resources: RehydratingResource[] = [];
270
272
 
271
273
  constructor(
272
274
  sessionId: number, target: RehydratingTarget, executionContexts: RehydratingExecutionContext[],
273
- scripts: RehydratingScript[], connection: RehydratingConnectionInterface) {
275
+ scripts: RehydratingScript[], resources: RehydratingResource[], connection: RehydratingConnectionInterface) {
274
276
  super(connection);
275
277
  this.sessionId = sessionId;
276
278
  this.target = target;
277
279
  this.executionContexts = executionContexts;
278
280
  this.scripts = scripts;
281
+ this.resources = resources;
279
282
  }
280
283
 
281
284
  override sendMessageToFrontend(payload: ServerMessage, attachSessionId = true): void {
@@ -294,12 +297,31 @@ export class RehydratingSession extends RehydratingSessionBase {
294
297
  case 'Debugger.enable':
295
298
  this.handleDebuggerEnable(data.id);
296
299
  break;
300
+ case 'CSS.enable':
301
+ this.sendMessageToFrontend({
302
+ id: data.id,
303
+ result: {},
304
+ });
305
+ break;
297
306
  case 'Debugger.getScriptSource':
298
307
  if (data.params) {
299
308
  const params = data.params as Protocol.Debugger.GetScriptSourceRequest;
300
309
  this.handleDebuggerGetScriptSource(data.id, params.scriptId);
301
310
  }
302
311
  break;
312
+ case 'Page.getResourceTree':
313
+ this.handleGetResourceTree(data.id);
314
+ break;
315
+ case 'Page.getResourceContent': {
316
+ const request = data.params as unknown as Protocol.Page.GetResourceContentRequest;
317
+ this.handleGetResourceContent(request.frameId, request.url, data.id);
318
+ break;
319
+ }
320
+ case 'CSS.getStyleSheetText': {
321
+ const request = data.params as unknown as Protocol.CSS.GetStyleSheetTextRequest;
322
+ this.handleGetStyleSheetText(request.styleSheetId, data.id);
323
+ break;
324
+ }
303
325
  default:
304
326
  this.sendMessageToFrontend({
305
327
  id: data.id,
@@ -368,7 +390,22 @@ export class RehydratingSession extends RehydratingSessionBase {
368
390
  // script parsed event to communicate the current script state and respond with a mock
369
391
  // debugger id.
370
392
  private handleDebuggerEnable(id: number): void {
393
+ const htmlResourceUrls = new Set(this.resources.filter(r => r.mimeType === 'text/html').map(r => r.url));
394
+
371
395
  for (const script of this.scripts) {
396
+ // Handle inline scripts.
397
+ if (htmlResourceUrls.has(script.url)) {
398
+ script.embedderName = script.url;
399
+ // We don't have the actual embedded offset from this trace event. Non-zero
400
+ // values are important though: that is what `Script.isInlineScript()`
401
+ // checks. Otherwise these scripts would try to show individually within the
402
+ // Sources panel.
403
+ script.startColumn = 1;
404
+ script.startLine = 1;
405
+ script.endColumn = 1;
406
+ script.endLine = 1;
407
+ }
408
+
372
409
  this.sendMessageToFrontend({
373
410
  method: 'Debugger.scriptParsed',
374
411
  params: script,
@@ -383,4 +420,75 @@ export class RehydratingSession extends RehydratingSessionBase {
383
420
  },
384
421
  });
385
422
  }
423
+
424
+ private handleGetResourceTree(id: number): void {
425
+ const resources = this.resources.filter(r => r.mimeType === 'text/html' || r.mimeType === 'text/css');
426
+ if (!resources.length) {
427
+ return;
428
+ }
429
+
430
+ const frameTree = {
431
+ frame: {
432
+ id: this.target.targetId,
433
+ url: this.target.url,
434
+ },
435
+ childFrames: [],
436
+ resources: resources.map(r => ({
437
+ url: r.url,
438
+ type: r.mimeType === 'text/html' ? 'Document' : 'Stylesheet',
439
+ mimeType: r.mimeType,
440
+ contentSize: r.content.length,
441
+ })),
442
+ };
443
+
444
+ this.sendMessageToFrontend({
445
+ id,
446
+ result: {
447
+ frameTree,
448
+ },
449
+ });
450
+
451
+ const stylesheets = this.resources.filter(r => r.mimeType === 'text/css');
452
+ for (const stylesheet of stylesheets) {
453
+ this.sendMessageToFrontend({
454
+ method: 'CSS.styleSheetAdded',
455
+ params: {
456
+ header: {
457
+ styleSheetId: `sheet.${stylesheet.frame}.${stylesheet.url}`,
458
+ frameId: stylesheet.frame,
459
+ sourceURL: stylesheet.url,
460
+ },
461
+ },
462
+ });
463
+ }
464
+ }
465
+
466
+ private handleGetResourceContent(frame: string, url: string, id: number): void {
467
+ const resource = this.resources.find(r => r.frame === frame && r.url === url);
468
+ if (!resource) {
469
+ return;
470
+ }
471
+
472
+ this.sendMessageToFrontend({
473
+ id,
474
+ result: {
475
+ content: resource.content,
476
+ base64Encoded: false,
477
+ },
478
+ });
479
+ }
480
+
481
+ private handleGetStyleSheetText(stylesheetId: string, id: number): void {
482
+ const resource = this.resources.find(r => `sheet.${r.frame}.${r.url}` === stylesheetId);
483
+ if (!resource) {
484
+ return;
485
+ }
486
+
487
+ this.sendMessageToFrontend({
488
+ id,
489
+ result: {
490
+ text: resource.content,
491
+ },
492
+ });
493
+ }
386
494
  }
@@ -14,6 +14,13 @@ export interface RehydratingScript extends Protocol.Debugger.ScriptParsedEvent {
14
14
  pid: number;
15
15
  }
16
16
 
17
+ export interface RehydratingResource {
18
+ url: string;
19
+ content: string;
20
+ frame: string;
21
+ mimeType: string;
22
+ }
23
+
17
24
  export interface RehydratingExecutionContextAuxData {
18
25
  frameId?: Protocol.Page.FrameId;
19
26
  isDefault?: boolean;
@@ -39,6 +46,7 @@ export interface HydratingDataPerTarget {
39
46
  target: RehydratingTarget;
40
47
  executionContexts: RehydratingExecutionContext[];
41
48
  scripts: RehydratingScript[];
49
+ resources: RehydratingResource[];
42
50
  }
43
51
 
44
52
  export interface ProtocolMessage {
@@ -7,13 +7,17 @@ import type * as Platform from '../../core/platform/platform.js';
7
7
  import type * as Protocol from '../../generated/protocol.js';
8
8
 
9
9
  import type {NetworkRequest} from './NetworkRequest.js';
10
+ import type {RehydratingResource} from './RehydratingObject.js';
10
11
  import {ResourceTreeModel} from './ResourceTreeModel.js';
11
12
  import type {SourceMapV3} from './SourceMap.js';
12
13
 
13
14
  /** A thin wrapper class, mostly to enable instanceof-based revealing of traces to open in Timeline. **/
14
15
  export class TraceObject {
15
16
  readonly traceEvents: Protocol.Tracing.DataCollectedEvent['value'];
16
- readonly metadata: {sourceMaps?: Array<{sourceMapUrl: string, sourceMap: SourceMapV3, url: string}>};
17
+ readonly metadata: {
18
+ sourceMaps?: Array<{sourceMapUrl: string, sourceMap: SourceMapV3, url: string}>,
19
+ resources?: RehydratingResource[],
20
+ };
17
21
  constructor(payload: Protocol.Tracing.DataCollectedEvent['value']|TraceObject, meta?: Object) {
18
22
  if (Array.isArray(payload)) {
19
23
  this.traceEvents = payload;
@@ -353,8 +353,11 @@ const UIStrings = {
353
353
  /**
354
354
  * @description Label of a checkbox in the DevTools settings UI.
355
355
  */
356
- enableRemoteFileLoading:
357
- 'Allow `DevTools` to load resources, such as source maps, from remote file paths. Disabled by default for security reasons.',
356
+ enableRemoteFileLoading: 'Allow loading remote file path resources in DevTools',
357
+ /**
358
+ * @description Tooltip text for a setting that controls whether external resource can be loaded in DevTools.
359
+ */
360
+ remoteFileLoadingInfo: 'Example resource are source maps. Disabled by default for security reasons.',
358
361
  /**
359
362
  * @description Tooltip text for a setting that controls the network cache. Disabling the network cache can simulate the network connections of users that are visiting a page for the first time.
360
363
  */
@@ -1160,4 +1163,7 @@ Common.Settings.registerSettingExtension({
1160
1163
  settingName: 'network.enable-remote-file-loading',
1161
1164
  settingType: Common.Settings.SettingType.BOOLEAN,
1162
1165
  defaultValue: false,
1166
+ learnMore: {
1167
+ tooltip: i18nLazyString(UIStrings.remoteFileLoadingInfo),
1168
+ }
1163
1169
  });
@@ -7,6 +7,7 @@
7
7
  import * as Common from '../../core/common/common.js';
8
8
  import * as Host from '../../core/host/host.js';
9
9
  import * as i18n from '../../core/i18n/i18n.js';
10
+ import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.js';
10
11
  import * as UI from '../../ui/legacy/legacy.js';
11
12
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
12
13
 
@@ -278,15 +279,15 @@ export class RenderingOptionsView extends UI.Widget.VBox {
278
279
 
279
280
  #appendCheckbox(
280
281
  label: Common.UIString.LocalizedString, subtitle: Common.UIString.LocalizedString,
281
- setting: Common.Settings.Setting<boolean>, metric?: UI.SettingsUI.UserMetricOptions): UI.UIUtils.CheckboxLabel {
282
+ setting: Common.Settings.Setting<boolean>, metric?: UI.UIUtils.UserMetricOptions): UI.UIUtils.CheckboxLabel {
282
283
  const checkbox = UI.UIUtils.CheckboxLabel.create(label, false, subtitle, setting.name);
283
- UI.SettingsUI.bindCheckbox(checkbox, setting, metric);
284
+ UI.UIUtils.bindCheckbox(checkbox, setting, metric);
284
285
  this.contentElement.appendChild(checkbox);
285
286
  return checkbox;
286
287
  }
287
288
 
288
289
  #appendSelect(label: string, setting: Common.Settings.Setting<unknown>): void {
289
- const control = UI.SettingsUI.createControlForSetting(setting, label);
290
+ const control = SettingsUI.SettingsUI.createControlForSetting(setting, label);
290
291
  if (control) {
291
292
  this.contentElement.appendChild(control);
292
293
  }
@@ -519,6 +519,7 @@ export const generatedProperties = [
519
519
  "inset-block-start",
520
520
  "inset-inline-end",
521
521
  "inset-inline-start",
522
+ "interactivity",
522
523
  "interest-delay-end",
523
524
  "interest-delay-start",
524
525
  "interpolate-size",
@@ -627,19 +627,24 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
627
627
  #declareFunctions(context: PerformanceTraceContext): void {
628
628
  const focus = context.getItem();
629
629
  const {parsedTrace} = focus;
630
- const insightSet = focus.primaryInsightSet;
631
630
 
632
- this.declareFunction<{insightName: string}, {details: string}>('getInsightDetails', {
631
+ this.declareFunction<{insightSetId: string, insightName: string}, {details: string}>('getInsightDetails', {
633
632
  description:
634
- 'Returns detailed information about a specific insight. Use this before commenting on any specific issue to get more information.',
633
+ 'Returns detailed information about a specific insight of an insight set. Use this before commenting on any specific issue to get more information.',
635
634
  parameters: {
636
635
  type: Host.AidaClient.ParametersTypes.OBJECT,
637
636
  description: '',
638
637
  nullable: false,
639
638
  properties: {
639
+ insightSetId: {
640
+ type: Host.AidaClient.ParametersTypes.STRING,
641
+ description:
642
+ 'The id for the specific insight set. Only use the ids given in the "Available insight sets" list.',
643
+ nullable: false,
644
+ },
640
645
  insightName: {
641
646
  type: Host.AidaClient.ParametersTypes.STRING,
642
- description: 'The name of the insight. Only use the insight names given in the Available Insights list.',
647
+ description: 'The name of the insight. Only use the insight names given in the "Available insights" list.',
643
648
  nullable: false,
644
649
  }
645
650
  },
@@ -647,19 +652,30 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
647
652
  displayInfoFromArgs: params => {
648
653
  return {
649
654
  title: lockedString(`Investigating insight ${params.insightName}…`),
650
- action: `getInsightDetails('${params.insightName}')`
655
+ action: `getInsightDetails('${params.insightSetId}', '${params.insightName}')`
651
656
  };
652
657
  },
653
658
  handler: async params => {
654
659
  debugLog('Function call: getInsightDetails', params);
660
+ const insightSet = parsedTrace.insights?.get(params.insightSetId);
661
+ if (!insightSet) {
662
+ const valid = ([...parsedTrace.insights?.values() ?? []])
663
+ .map(
664
+ insightSet => `id: ${insightSet.id}, url: ${insightSet.url}, bounds: ${
665
+ this.#formatter?.serializeBounds(insightSet.bounds)}`)
666
+ .join('; ');
667
+ return {error: `Invalid insight set id. Valid insight set ids are: ${valid}`};
668
+ }
669
+
655
670
  const insight = insightSet?.model[params.insightName as keyof Trace.Insights.Types.InsightModels];
656
671
  if (!insight) {
657
- return {error: 'No insight available'};
672
+ const valid = Object.keys(insightSet?.model).join(', ');
673
+ return {error: `No insight available. Valid insight names are: ${valid}`};
658
674
  }
659
675
 
660
676
  const details = new PerformanceInsightFormatter(focus, insight).formatInsight();
661
677
 
662
- const key = `getInsightDetails('${params.insightName}')`;
678
+ const key = `getInsightDetails('${params.insightSetId}', '${params.insightName}')`;
663
679
  this.#cacheFunctionResult(focus, key, details);
664
680
  return {result: {details}};
665
681
  },
@@ -504,9 +504,18 @@ IMPORTANT: Never show eventKey to the user.
504
504
  Title: PerformanceTraceFormatter formatTraceSummary web-dev.json.gz
505
505
  Content:
506
506
  URL: https://web.dev/cls/
507
- Bounds: {min: 1020034823047, max: 1020036087961}
507
+ Trace bounds: {min: 1020034823047, max: 1020036087961}
508
508
  CPU throttling: none
509
509
  Network throttling: none
510
+
511
+ # Available insight sets
512
+
513
+ The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
514
+
515
+ ## insight set id: 86EB5E5C401E3E17ECE461B3FC627867
516
+
517
+ URL: https://web.dev/cls/
518
+ Bounds: {min: 1020034834921, max: 1020036087961}
510
519
  Metrics (lab / observed):
511
520
  - LCP: 118 ms, event: (eventKey: r-1802, ts: 1020034953358), nodeId: 209
512
521
  - LCP breakdown:
@@ -537,9 +546,18 @@ Available insights:
537
546
  Title: PerformanceTraceFormatter formatTraceSummary yahoo-news.json.gz
538
547
  Content:
539
548
  URL: https://news.yahoo.com/
540
- Bounds: {min: 157423484442, max: 157427277166}
549
+ Trace bounds: {min: 157423484442, max: 157427277166}
541
550
  CPU throttling: none
542
551
  Network throttling: none
552
+
553
+ # Available insight sets
554
+
555
+ The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
556
+
557
+ ## insight set id: 513BDA1E9EC088611B53BFF7A859B5DD
558
+
559
+ URL: https://news.yahoo.com/
560
+ Bounds: {min: 157423488682, max: 157427277166}
543
561
  Metrics (lab / observed):
544
562
  - LCP: 464 ms, event: (eventKey: r-33210, ts: 157423953162), nodeId: 8
545
563
  - LCP breakdown:
@@ -596,12 +614,81 @@ Available insights:
596
614
  example question: How can I reduce the amount of legacy JavaScript on my page?
597
615
  === end content
598
616
 
617
+ Title: PerformanceTraceFormatter formatTraceSummary multiple-navigations-render-blocking.json.gz
618
+ Content:
619
+ URL: http://localhost:8080/render-blocking
620
+ Trace bounds: {min: 171605647473, max: 171616667355}
621
+ CPU throttling: 1x
622
+ Network throttling: Fast 3G
623
+
624
+ # Available insight sets
625
+
626
+ The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
627
+
628
+ ## insight set id: 8671F33ECE0C8DBAEFBC2F9A2D1D6107
629
+
630
+ URL: http://localhost:8080/render-blocking
631
+ Bounds: {min: 171607579779, max: 171613750571}
632
+ Metrics (lab / observed):
633
+ - LCP: 1317 ms, event: (eventKey: r-6686, ts: 171608897210), nodeId: 10
634
+ - LCP breakdown:
635
+ - TTFB: 10 ms, bounds: {min: 171607579779, max: 171607589981.99997}
636
+ - Render delay: 1,307 ms, bounds: {min: 171607589981.99997, max: 171608897210}
637
+ - CLS: 0.00
638
+ Metrics (field / real users): n/a – no data for this page in CrUX
639
+ Available insights:
640
+ - insight name: LCPBreakdown
641
+ description: Each [subpart has specific improvement strategies](https://developer.chrome.com/docs/performance/insights/lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
642
+ relevant trace bounds: {min: 171607579779, max: 171608897210}
643
+ example question: Help me optimize my LCP score
644
+ example question: Which LCP phase was most problematic?
645
+ example question: What can I do to reduce the LCP time for this page load?
646
+ - insight name: RenderBlocking
647
+ description: Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.
648
+ relevant trace bounds: {min: 171608170438, max: 171608877165}
649
+ example question: Show me the most impactful render blocking requests that I should focus on
650
+ example question: How can I reduce the number of render blocking requests?
651
+
652
+ ## insight set id: 1AE2016BBCC48AA090FDAE2CBBA01900
653
+
654
+ URL: http://localhost:8080/render-blocking
655
+ Bounds: {min: 171613750571, max: 171616667355}
656
+ Metrics (lab / observed):
657
+ - LCP: 1310 ms, event: (eventKey: r-15639, ts: 171615060776), nodeId: 18
658
+ - LCP breakdown:
659
+ - TTFB: 3 ms, bounds: {min: 171613750571, max: 171613753188}
660
+ - Render delay: 1,308 ms, bounds: {min: 171613753188, max: 171615060776}
661
+ - CLS: 0.00
662
+ Metrics (field / real users): n/a – no data for this page in CrUX
663
+ Available insights:
664
+ - insight name: LCPBreakdown
665
+ description: Each [subpart has specific improvement strategies](https://developer.chrome.com/docs/performance/insights/lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
666
+ relevant trace bounds: {min: 171613750571, max: 171615060776}
667
+ example question: Help me optimize my LCP score
668
+ example question: Which LCP phase was most problematic?
669
+ example question: What can I do to reduce the LCP time for this page load?
670
+ - insight name: RenderBlocking
671
+ description: Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.
672
+ relevant trace bounds: {min: 171614330544, max: 171615043224}
673
+ example question: Show me the most impactful render blocking requests that I should focus on
674
+ example question: How can I reduce the number of render blocking requests?
675
+ === end content
676
+
599
677
  Title: PerformanceTraceFormatter formatTraceSummary deals with CrUX manager errors
600
678
  Content:
601
679
  URL: http://localhost/image-delivery-cases.html
602
- Bounds: {min: 59728641874, max: 59734400108}
680
+ Trace bounds: {min: 59728641874, max: 59734400108}
603
681
  CPU throttling: 1x
604
682
  Network throttling: No throttling
683
+
684
+ # Available insight sets
685
+
686
+ The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
687
+
688
+ ## insight set id: 9094E106056B51D078CE44F3356FE194
689
+
690
+ URL: http://localhost/image-delivery-cases.html
691
+ Bounds: {min: 59728649746, max: 59734400108}
605
692
  Metrics (lab / observed):
606
693
  - LCP: 663 ms, event: (eventKey: r-14753, ts: 59729312744), nodeId: 12
607
694
  - LCP breakdown:
@@ -663,9 +750,18 @@ Available insights:
663
750
  Title: PerformanceTraceFormatter formatTraceSummary image-delivery.json.gz
664
751
  Content:
665
752
  URL: http://localhost/image-delivery-cases.html
666
- Bounds: {min: 59728641874, max: 59734400108}
753
+ Trace bounds: {min: 59728641874, max: 59734400108}
667
754
  CPU throttling: 1x
668
755
  Network throttling: No throttling
756
+
757
+ # Available insight sets
758
+
759
+ The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
760
+
761
+ ## insight set id: 9094E106056B51D078CE44F3356FE194
762
+
763
+ URL: http://localhost/image-delivery-cases.html
764
+ Bounds: {min: 59728649746, max: 59734400108}
669
765
  Metrics (lab / observed):
670
766
  - LCP: 663 ms, event: (eventKey: r-14753, ts: 59729312744), nodeId: 12
671
767
  - LCP breakdown:
@@ -734,9 +830,18 @@ Available insights:
734
830
  Title: PerformanceTraceFormatter formatTraceSummary includes INP insight when there is no navigation
735
831
  Content:
736
832
  URL: https://b2607f8b04800100000289cb1c0a82ba72253000000000000000001.proxy.googlers.com/long-interaction/index.html?x=35
737
- Bounds: {min: 337943614456, max: 337947260898}
833
+ Trace bounds: {min: 337943614456, max: 337947260898}
738
834
  CPU throttling: none
739
835
  Network throttling: none
836
+
837
+ # Available insight sets
838
+
839
+ The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
840
+
841
+ ## insight set id: NO_NAVIGATION
842
+
843
+ URL: https://b2607f8b04800100000289cb1c0a82ba72253000000000000000001.proxy.googlers.com/long-interaction/index.html?x=35
844
+ Bounds: {min: 337943614456, max: 337947260898}
740
845
  Metrics (lab / observed):
741
846
  - INP: 139 ms, event: (eventKey: s-3347, ts: 337944870984)
742
847
  - CLS: 0.00
@@ -116,62 +116,69 @@ export class PerformanceTraceFormatter {
116
116
 
117
117
  formatTraceSummary(): string {
118
118
  const parsedTrace = this.#parsedTrace;
119
- const insightSet = this.#insightSet;
120
119
  const traceMetadata = this.#parsedTrace.metadata;
121
120
  const data = parsedTrace.data;
122
121
 
123
122
  const parts = [];
124
123
 
125
- const lcp = insightSet ? Trace.Insights.Common.getLCP(insightSet) : null;
126
- const cls = insightSet ? Trace.Insights.Common.getCLS(insightSet) : null;
127
- const inp = insightSet ? Trace.Insights.Common.getINP(insightSet) : null;
128
-
129
124
  parts.push(`URL: ${data.Meta.mainFrameURL}`);
130
- parts.push(`Bounds: ${this.serializeBounds(data.Meta.traceBounds)}`);
125
+ parts.push(`Trace bounds: ${this.serializeBounds(data.Meta.traceBounds)}`);
131
126
  parts.push('CPU throttling: ' + (traceMetadata.cpuThrottling ? `${traceMetadata.cpuThrottling}x` : 'none'));
132
127
  parts.push(`Network throttling: ${traceMetadata.networkThrottling ?? 'none'}`);
133
- if (lcp || cls || inp) {
134
- parts.push('Metrics (lab / observed):');
135
- if (lcp) {
136
- const nodeId = insightSet?.model.LCPBreakdown.lcpEvent?.args.data?.nodeId;
137
- const nodeIdText = nodeId !== undefined ? `, nodeId: ${nodeId}` : '';
138
- parts.push(
139
- ` - LCP: ${Math.round(lcp.value / 1000)} ms, event: ${this.serializeEvent(lcp.event)}${nodeIdText}`);
140
- const subparts = insightSet?.model.LCPBreakdown.subparts;
141
- if (subparts) {
142
- const serializeSubpart = (subpart: Trace.Insights.Models.LCPBreakdown.Subpart): string => {
143
- return `${micros(subpart.range)}, bounds: ${this.serializeBounds(subpart)}`;
144
- };
145
- parts.push(' - LCP breakdown:');
146
- parts.push(` - TTFB: ${serializeSubpart(subparts.ttfb)}`);
147
- if (subparts.loadDelay !== undefined) {
148
- parts.push(` - Load delay: ${serializeSubpart(subparts.loadDelay)}`);
149
- }
150
- if (subparts.loadDuration !== undefined) {
151
- parts.push(` - Load duration: ${serializeSubpart(subparts.loadDuration)}`);
128
+
129
+ parts.push('\n# Available insight sets\n');
130
+ parts.push(
131
+ 'The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.');
132
+
133
+ for (const insightSet of parsedTrace.insights?.values() ?? []) {
134
+ const lcp = insightSet ? Trace.Insights.Common.getLCP(insightSet) : null;
135
+ const cls = insightSet ? Trace.Insights.Common.getCLS(insightSet) : null;
136
+ const inp = insightSet ? Trace.Insights.Common.getINP(insightSet) : null;
137
+
138
+ parts.push(`\n## insight set id: ${insightSet.id}\n`);
139
+ parts.push(`URL: ${insightSet.url}`);
140
+ parts.push(`Bounds: ${this.serializeBounds(insightSet.bounds)}`);
141
+ if (lcp || cls || inp) {
142
+ parts.push('Metrics (lab / observed):');
143
+ if (lcp) {
144
+ const nodeId = insightSet?.model.LCPBreakdown.lcpEvent?.args.data?.nodeId;
145
+ const nodeIdText = nodeId !== undefined ? `, nodeId: ${nodeId}` : '';
146
+ parts.push(
147
+ ` - LCP: ${Math.round(lcp.value / 1000)} ms, event: ${this.serializeEvent(lcp.event)}${nodeIdText}`);
148
+ const subparts = insightSet?.model.LCPBreakdown.subparts;
149
+ if (subparts) {
150
+ const serializeSubpart = (subpart: Trace.Insights.Models.LCPBreakdown.Subpart): string => {
151
+ return `${micros(subpart.range)}, bounds: ${this.serializeBounds(subpart)}`;
152
+ };
153
+ parts.push(' - LCP breakdown:');
154
+ parts.push(` - TTFB: ${serializeSubpart(subparts.ttfb)}`);
155
+ if (subparts.loadDelay !== undefined) {
156
+ parts.push(` - Load delay: ${serializeSubpart(subparts.loadDelay)}`);
157
+ }
158
+ if (subparts.loadDuration !== undefined) {
159
+ parts.push(` - Load duration: ${serializeSubpart(subparts.loadDuration)}`);
160
+ }
161
+ parts.push(` - Render delay: ${serializeSubpart(subparts.renderDelay)}`);
152
162
  }
153
- parts.push(` - Render delay: ${serializeSubpart(subparts.renderDelay)}`);
154
163
  }
164
+ if (inp) {
165
+ parts.push(` - INP: ${Math.round(inp.value / 1000)} ms, event: ${this.serializeEvent(inp.event)}`);
166
+ }
167
+ if (cls) {
168
+ const eventText = cls.worstClusterEvent ? `, event: ${this.serializeEvent(cls.worstClusterEvent)}` : '';
169
+ parts.push(` - CLS: ${cls.value.toFixed(2)}${eventText}`);
170
+ }
171
+ } else {
172
+ parts.push('Metrics (lab / observed): n/a');
155
173
  }
156
- if (inp) {
157
- parts.push(` - INP: ${Math.round(inp.value / 1000)} ms, event: ${this.serializeEvent(inp.event)}`);
158
- }
159
- if (cls) {
160
- const eventText = cls.worstClusterEvent ? `, event: ${this.serializeEvent(cls.worstClusterEvent)}` : '';
161
- parts.push(` - CLS: ${cls.value.toFixed(2)}${eventText}`);
162
- }
163
- } else {
164
- parts.push('Metrics (lab / observed): n/a');
165
- }
166
174
 
167
- const cruxParts = insightSet && this.#getCruxTraceSummary(insightSet);
168
- if (cruxParts?.length) {
169
- parts.push(...cruxParts);
170
- } else {
171
- parts.push('Metrics (field / real users): n/a – no data for this page in CrUX');
172
- }
175
+ const cruxParts = insightSet && this.#getCruxTraceSummary(insightSet);
176
+ if (cruxParts?.length) {
177
+ parts.push(...cruxParts);
178
+ } else {
179
+ parts.push('Metrics (field / real users): n/a – no data for this page in CrUX');
180
+ }
173
181
 
174
- if (insightSet) {
175
182
  parts.push('Available insights:');
176
183
  for (const [insightName, model] of Object.entries(insightSet.model)) {
177
184
  if (model.state === 'pass') {
@@ -202,8 +209,6 @@ export class PerformanceTraceFormatter {
202
209
  const insightPartsText = insightParts.join('\n ');
203
210
  parts.push(` - ${insightPartsText}`);
204
211
  }
205
- } else {
206
- parts.push('Available insights: none');
207
212
  }
208
213
 
209
214
  return parts.join('\n');
@@ -13,7 +13,7 @@ export class ProfileNode {
13
13
  id: number;
14
14
  parent: ProfileNode|null;
15
15
  children: this[];
16
- functionName: string;
16
+ originalFunctionName: string|null = null;
17
17
  depth!: number;
18
18
  deoptReason!: string|null;
19
19
  constructor(callFrame: Protocol.Runtime.CallFrame) {
@@ -22,7 +22,6 @@ export class ProfileNode {
22
22
  this.self = 0;
23
23
  this.total = 0;
24
24
  this.id = 0;
25
- this.functionName = callFrame.functionName;
26
25
  this.parent = null;
27
26
  this.children = [];
28
27
  }
@@ -43,11 +42,12 @@ export class ProfileNode {
43
42
  return this.callFrame.columnNumber;
44
43
  }
45
44
 
46
- setFunctionName(name: string|null): void {
47
- if (name === null) {
48
- return;
49
- }
50
- this.functionName = name;
45
+ get functionName(): string {
46
+ return this.originalFunctionName ?? this.callFrame.functionName;
47
+ }
48
+
49
+ setOriginalFunctionName(name: string|null): void {
50
+ this.originalFunctionName = name;
51
51
  }
52
52
  }
53
53