chrome-devtools-frontend 1.0.1664496 → 1.0.1665921

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 (407) hide show
  1. package/.agents/skills/devtools-testing-guidance/SKILL.md +48 -0
  2. package/.agents/skills/devtools-ux-writing-refactor/SKILL.md +3 -3
  3. package/.agents/skills/repro-flaky-tests/SKILL.md +2 -2
  4. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +7 -1
  5. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +2 -0
  6. package/.agents/skills/version-control/SKILL.md +4 -3
  7. package/docs/ui_engineering.md +89 -0
  8. package/eslint.config.mjs +9 -2
  9. package/front_end/Images/rollup.config.mjs +1 -1
  10. package/front_end/Tests.js +15 -16
  11. package/front_end/core/common/Gzip.ts +2 -2
  12. package/front_end/core/common/Settings.ts +4 -20
  13. package/front_end/core/common/Srcset.ts +1 -1
  14. package/front_end/core/common/VersionController.ts +1 -1
  15. package/front_end/core/host/AidaClient.ts +19 -4
  16. package/front_end/core/host/AidaGcaTranslation.ts +2 -2
  17. package/front_end/core/host/GcaClient.ts +2 -2
  18. package/front_end/core/host/GdpClient.ts +3 -3
  19. package/front_end/core/host/InspectorFrontendHostStub.ts +1 -1
  20. package/front_end/core/host/ResourceLoader.ts +15 -15
  21. package/front_end/core/protocol_client/DevToolsCDPConnection.ts +2 -2
  22. package/front_end/core/protocol_client/InspectorBackend.ts +1 -1
  23. package/front_end/core/root/Runtime.ts +0 -1
  24. package/front_end/core/sdk/CSSMatchedStyles.ts +78 -3
  25. package/front_end/core/sdk/CSSMetadata.ts +17 -12
  26. package/front_end/core/sdk/CSSProperty.ts +1 -1
  27. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -2
  28. package/front_end/core/sdk/CSSRule.ts +3 -3
  29. package/front_end/core/sdk/CSSStyleSheetHeader.ts +3 -3
  30. package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +1 -1
  31. package/front_end/core/sdk/Connections.ts +1 -1
  32. package/front_end/core/sdk/DebuggerModel.ts +13 -13
  33. package/front_end/core/sdk/NetworkManager.ts +19 -19
  34. package/front_end/core/sdk/NetworkRequest.ts +57 -57
  35. package/front_end/core/sdk/OverlayModel.ts +1 -1
  36. package/front_end/core/sdk/PageResourceLoader.ts +2 -2
  37. package/front_end/core/sdk/RehydratingConnection.ts +5 -5
  38. package/front_end/core/sdk/ScreenCaptureModel.ts +1 -1
  39. package/front_end/core/sdk/Script.ts +2 -2
  40. package/front_end/core/sdk/ServerTiming.ts +7 -7
  41. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +1 -1
  42. package/front_end/core/sdk/ServiceWorkerManager.ts +11 -11
  43. package/front_end/core/sdk/SourceMapScopeChainEntry.ts +2 -2
  44. package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
  45. package/front_end/core/sdk/StorageKeyManager.ts +1 -1
  46. package/front_end/core/sdk/sdk-meta.ts +98 -98
  47. package/front_end/devtools_compatibility.js +15 -13
  48. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +4 -8
  49. package/front_end/entrypoints/main/MainImpl.ts +2 -3
  50. package/front_end/entrypoints/main/main-meta.ts +1 -16
  51. package/front_end/entrypoints/shell/shell.ts +1 -0
  52. package/front_end/entrypoints/trace_app/trace_app.ts +1 -0
  53. package/front_end/foundation/README.md +1 -1
  54. package/front_end/foundation/Universe.test.api.ts +73 -0
  55. package/front_end/foundation/Universe.ts +22 -0
  56. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  57. package/front_end/generated/SupportedCSSProperties.js +1 -1
  58. package/front_end/generated/protocol.ts +19 -0
  59. package/front_end/models/ai_assistance/AiAgent2.ts +1 -1
  60. package/front_end/models/ai_assistance/AiConversation.ts +1 -1
  61. package/front_end/models/ai_assistance/BuiltInAi.ts +1 -1
  62. package/front_end/models/ai_assistance/ChangeManager.ts +0 -70
  63. package/front_end/models/ai_assistance/ExtensionScope.ts +2 -36
  64. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +9 -9
  65. package/front_end/models/ai_assistance/agents/AiAgent.ts +10 -2
  66. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +4 -4
  67. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -1
  68. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +21 -21
  69. package/front_end/models/ai_assistance/agents/StorageAgent.ts +4 -4
  70. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  71. package/front_end/models/ai_assistance/ai_assistance.ts +0 -5
  72. package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +11 -4
  73. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +8 -2
  74. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +14 -11
  75. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +2 -2
  76. package/front_end/models/ai_assistance/performance/AICallTree.ts +2 -2
  77. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +1 -1
  78. package/front_end/models/ai_assistance/tools/GetNetworkRequestDetails.ts +9 -2
  79. package/front_end/models/ai_assistance/tools/GetStyles.ts +4 -4
  80. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -5
  81. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +2 -2
  82. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +2 -2
  83. package/front_end/models/badges/badges-meta.ts +27 -0
  84. package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -3
  85. package/front_end/models/bindings/ContentProviderBasedProject.ts +1 -1
  86. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +6 -7
  87. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +5 -4
  88. package/front_end/models/bindings/PresentationConsoleMessageHelper.ts +72 -29
  89. package/front_end/models/bindings/ResourceMapping.ts +38 -32
  90. package/front_end/models/bindings/ResourceScriptMapping.ts +5 -7
  91. package/front_end/models/breakpoints/BreakpointManager.ts +2 -1
  92. package/front_end/models/har/Writer.ts +2 -2
  93. package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +1 -1
  94. package/front_end/models/issues_manager/GenericIssue.ts +1 -1
  95. package/front_end/models/issues_manager/IssuesManager.ts +14 -5
  96. package/front_end/models/issues_manager/PartitioningBlobURLIssue.ts +1 -1
  97. package/front_end/models/issues_manager/SRIMessageSignatureIssue.ts +2 -2
  98. package/front_end/models/issues_manager/SourceFrameIssuesManager.ts +13 -2
  99. package/front_end/models/issues_manager/issues_manager.ts +0 -2
  100. package/front_end/models/live-metrics/LiveMetrics.ts +22 -5
  101. package/front_end/models/live-metrics/web-vitals-injected/rollup.config.mjs +1 -1
  102. package/front_end/models/live-metrics/web-vitals-injected/spec/spec.ts +10 -4
  103. package/front_end/models/logs/logs-meta.ts +23 -16
  104. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +2 -2
  105. package/front_end/models/persistence/IsolatedFileSystem.ts +1 -1
  106. package/front_end/models/persistence/IsolatedFileSystemManager.ts +1 -1
  107. package/front_end/models/source_map_scopes/NamesResolver.ts +104 -86
  108. package/front_end/models/source_map_scopes/ScopeChainModel.ts +6 -2
  109. package/front_end/models/stack_trace/StackTraceModel.ts +1 -1
  110. package/front_end/models/trace/handlers/ExtensionTraceDataHandler.ts +1 -1
  111. package/front_end/models/trace/handlers/UserTimingsHandler.ts +17 -6
  112. package/front_end/models/trace/helpers/SamplesIntegrator.ts +1 -1
  113. package/front_end/models/trace/helpers/Timing.ts +1 -1
  114. package/front_end/models/trace/insights/Common.ts +1 -1
  115. package/front_end/models/trace/insights/DocumentLatency.ts +3 -3
  116. package/front_end/models/trace/insights/LCPDiscovery.ts +1 -1
  117. package/front_end/models/trace/insights/ModernHTTP.ts +1 -1
  118. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +2 -2
  119. package/front_end/models/workspace_diff/WorkspaceDiff.ts +14 -9
  120. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -15
  121. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -2
  122. package/front_end/panels/ai_assistance/components/ChatInput.ts +23 -19
  123. package/front_end/panels/ai_assistance/components/ChatMessage.ts +9 -18
  124. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -35
  125. package/front_end/panels/ai_assistance/components/DisabledWidget.ts +1 -1
  126. package/front_end/panels/ai_assistance/components/ExploreWidget.ts +4 -4
  127. package/front_end/panels/ai_assistance/components/ImageResize.ts +74 -0
  128. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +2 -2
  129. package/front_end/panels/animation/AnimationGroupPreviewUI.ts +28 -29
  130. package/front_end/panels/animation/AnimationTimeline.ts +3 -3
  131. package/front_end/panels/animation/animationTimeline.css +0 -2
  132. package/front_end/panels/application/AppManifestView.ts +1 -1
  133. package/front_end/panels/application/ApplicationPanelSidebar.ts +1 -1
  134. package/front_end/panels/application/CookieItemsView.ts +1 -1
  135. package/front_end/panels/application/CrashReportContextView.ts +3 -3
  136. package/front_end/panels/application/DeviceBoundSessionsModel.ts +1 -1
  137. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +1 -1
  138. package/front_end/panels/application/DeviceBoundSessionsView.ts +1 -1
  139. package/front_end/panels/application/IndexedDBViews.ts +1 -1
  140. package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -1
  141. package/front_end/panels/application/OriginTrialTreeView.ts +1 -1
  142. package/front_end/panels/application/ServiceWorkersView.ts +6 -6
  143. package/front_end/panels/application/StorageBucketsTreeElement.ts +1 -1
  144. package/front_end/panels/application/StorageItemsToolbar.ts +3 -3
  145. package/front_end/panels/application/WebMCPView.ts +7 -5
  146. package/front_end/panels/application/components/AdsView.ts +21 -6
  147. package/front_end/panels/application/components/BackForwardCacheView.ts +2 -2
  148. package/front_end/panels/application/components/ProtocolHandlersView.ts +1 -1
  149. package/front_end/panels/application/components/StorageMetadataView.ts +1 -1
  150. package/front_end/panels/application/preloading/components/MismatchedPreloadingGrid.ts +2 -2
  151. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +2 -1
  152. package/front_end/panels/application/preloading/components/PreloadingString.ts +3 -3
  153. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -1
  154. package/front_end/panels/autofill/AutofillView.ts +1 -1
  155. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +1 -1
  156. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +2 -2
  157. package/front_end/panels/changes/ChangesSidebar.ts +2 -2
  158. package/front_end/panels/changes/ChangesView.ts +4 -5
  159. package/front_end/panels/changes/CombinedDiffView.ts +3 -3
  160. package/front_end/panels/changes/changes-meta.ts +2 -2
  161. package/front_end/panels/common/AiCodeCompletionTeaser.ts +1 -1
  162. package/front_end/panels/common/AiCodeGenerationTeaser.ts +3 -3
  163. package/front_end/panels/common/BadgeNotification.ts +8 -8
  164. package/front_end/panels/common/DOMLinkifier.ts +1 -1
  165. package/front_end/panels/common/GdpSignUpDialog.ts +2 -2
  166. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
  167. package/front_end/panels/common/aiCodeCompletionDisclaimer.css +0 -1
  168. package/front_end/panels/console/ConsoleInsightTeaser.ts +1 -1
  169. package/front_end/panels/console/ConsolePinPane.ts +3 -3
  170. package/front_end/panels/console/ConsolePrompt.ts +6 -4
  171. package/front_end/panels/console/ConsoleSidebar.ts +8 -10
  172. package/front_end/panels/console_counters/WarningErrorCounter.ts +10 -11
  173. package/front_end/panels/coverage/CoverageView.ts +2 -2
  174. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +3 -3
  175. package/front_end/panels/css_overview/CSSOverviewSidebarPanel.ts +1 -1
  176. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +1 -1
  177. package/front_end/panels/elements/CSSRuleValidator.ts +1 -1
  178. package/front_end/panels/elements/ComputedStyleWidget.ts +3 -2
  179. package/front_end/panels/elements/ElementsTreeElement.ts +3 -3
  180. package/front_end/panels/elements/EventListenersWidget.ts +1 -3
  181. package/front_end/panels/elements/LayoutPane.ts +23 -13
  182. package/front_end/panels/elements/StandaloneStylesContainer.ts +7 -7
  183. package/front_end/panels/elements/StylePropertiesSection.ts +33 -5
  184. package/front_end/panels/elements/StylePropertyTreeElement.ts +5 -5
  185. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +6 -6
  186. package/front_end/panels/elements/StylesSidebarPane.ts +4 -3
  187. package/front_end/panels/elements/elements-meta.ts +18 -2
  188. package/front_end/panels/emulation/DeviceModeToolbar.ts +100 -40
  189. package/front_end/panels/emulation/DeviceModeView.ts +5 -4
  190. package/front_end/panels/emulation/MediaQueryInspector.ts +35 -19
  191. package/front_end/panels/event_listeners/EventListenersView.ts +4 -4
  192. package/front_end/panels/explain/components/ConsoleInsight.ts +8 -9
  193. package/front_end/panels/explain/explain-meta.ts +3 -3
  194. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +135 -167
  195. package/front_end/panels/layer_viewer/Layers3DView.ts +10 -23
  196. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +27 -0
  197. package/front_end/panels/lighthouse/LighthouseController.ts +44 -55
  198. package/front_end/panels/lighthouse/LighthousePanel.ts +9 -9
  199. package/front_end/panels/lighthouse/LighthouseReportSelector.ts +2 -2
  200. package/front_end/panels/lighthouse/LighthouseStartView.ts +9 -12
  201. package/front_end/panels/lighthouse/LighthouseStatusView.ts +33 -33
  202. package/front_end/panels/lighthouse/RadioSetting.ts +1 -1
  203. package/front_end/panels/lighthouse/lighthouse-meta.ts +131 -1
  204. package/front_end/panels/media/EventDisplayTable.ts +67 -94
  205. package/front_end/panels/media/PlayerListView.ts +1 -1
  206. package/front_end/panels/media/eventDisplayTable.css +9 -4
  207. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +5 -5
  208. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +1 -1
  209. package/front_end/panels/network/EventSourceMessagesView.ts +98 -107
  210. package/front_end/panels/network/NetworkLogViewColumns.ts +1 -1
  211. package/front_end/panels/network/NetworkWaterfallColumn.ts +1 -1
  212. package/front_end/panels/network/RequestConditionsDrawer.ts +2 -2
  213. package/front_end/panels/network/RequestCookiesView.ts +2 -2
  214. package/front_end/panels/network/RequestHeadersView.ts +5 -5
  215. package/front_end/panels/network/RequestPayloadView.ts +4 -4
  216. package/front_end/panels/network/RequestTimingView.ts +2 -2
  217. package/front_end/panels/network/components/DirectSocketConnectionView.ts +1 -1
  218. package/front_end/panels/network/eventSourceMessagesView.css +12 -3
  219. package/front_end/panels/network/networkTimingTable.css +2 -2
  220. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +1 -1
  221. package/front_end/panels/profiler/BottomUpProfileDataGrid.ts +25 -29
  222. package/front_end/panels/profiler/HeapProfileView.ts +308 -247
  223. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +13 -3
  224. package/front_end/panels/profiler/HeapSnapshotView.ts +30 -10
  225. package/front_end/panels/profiler/HeapTimelineOverview.ts +5 -2
  226. package/front_end/panels/profiler/ProfileDataGrid.ts +128 -157
  227. package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +17 -5
  228. package/front_end/panels/profiler/ProfilesPanel.ts +2 -2
  229. package/front_end/panels/profiler/TopDownProfileDataGrid.ts +17 -21
  230. package/front_end/panels/profiler/profilesPanel.css +9 -13
  231. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +2 -2
  232. package/front_end/panels/recorder/CreateRecordingView.ts +4 -4
  233. package/front_end/panels/recorder/RecorderPanel.ts +6 -6
  234. package/front_end/panels/recorder/RecordingView.ts +1 -1
  235. package/front_end/panels/recorder/ReplaySection.ts +1 -1
  236. package/front_end/panels/recorder/StepView.ts +1 -1
  237. package/front_end/panels/recorder/injected/rollup.config.mjs +1 -1
  238. package/front_end/panels/search/SearchView.ts +1 -1
  239. package/front_end/panels/security/SecurityPanel.ts +54 -41
  240. package/front_end/panels/sensors/LocationsSettingsTab.ts +246 -233
  241. package/front_end/panels/sensors/SensorsView.ts +1 -1
  242. package/front_end/panels/settings/AISettingsTab.ts +11 -10
  243. package/front_end/panels/settings/SettingsScreen.ts +29 -24
  244. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +2 -2
  245. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +5 -5
  246. package/front_end/panels/sources/BreakpointEditDialog.ts +2 -2
  247. package/front_end/panels/sources/BreakpointsView.ts +1 -1
  248. package/front_end/panels/sources/CallStackSidebarPane.ts +2 -2
  249. package/front_end/panels/sources/DebuggerPausedMessage.ts +2 -2
  250. package/front_end/panels/sources/DebuggerPlugin.ts +25 -22
  251. package/front_end/panels/sources/ScopeChainSidebarPane.ts +3 -1
  252. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +7 -5
  253. package/front_end/panels/sources/sources-meta.ts +1 -1
  254. package/front_end/panels/timeline/CountersGraph.ts +1 -2
  255. package/front_end/panels/timeline/ExtensionTrackAppender.ts +1 -1
  256. package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
  257. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +2 -2
  258. package/front_end/panels/timeline/TimelineFlameChartView.ts +4 -4
  259. package/front_end/panels/timeline/TimelinePaintProfilerView.ts +1 -1
  260. package/front_end/panels/timeline/TimelinePanel.ts +53 -81
  261. package/front_end/panels/timeline/TimelineSelectorStatsView.ts +10 -3
  262. package/front_end/panels/timeline/TimelineUIUtils.ts +18 -4
  263. package/front_end/panels/timeline/TrackConfigBanner.ts +1 -1
  264. package/front_end/panels/timeline/components/ExportTraceOptions.ts +1 -1
  265. package/front_end/panels/timeline/components/LayoutShiftDetails.ts +8 -9
  266. package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +1 -1
  267. package/front_end/panels/timeline/components/TimelineRangeSummaryView.ts +1 -1
  268. package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +2 -2
  269. package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +1 -1
  270. package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +1 -1
  271. package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +2 -2
  272. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +5 -0
  273. package/front_end/panels/timeline/overlays/components/TimespanBreakdownOverlay.ts +13 -8
  274. package/front_end/panels/timeline/overlays/components/timespanBreakdownOverlay.css +1 -0
  275. package/front_end/panels/timeline/timeline-meta.ts +169 -0
  276. package/front_end/panels/timeline/timelineFlameChartView.css +5 -0
  277. package/front_end/panels/webauthn/WebauthnPane.ts +1 -1
  278. package/front_end/panels/whats_new/ReleaseNoteText.ts +9 -9
  279. package/front_end/panels/whats_new/resources/WNDT.md +7 -8
  280. package/front_end/third_party/chromium/README.chromium +1 -1
  281. package/front_end/third_party/web-vitals/README.chromium +2 -2
  282. package/front_end/third_party/web-vitals/package/README.md +120 -19
  283. package/front_end/third_party/web-vitals/package/attribution.d.ts +16 -0
  284. package/front_end/third_party/web-vitals/package/attribution.js +18 -0
  285. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onCLS.d.ts +1 -1
  286. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.d.ts +1 -7
  287. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.js +53 -32
  288. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.d.ts +2 -2
  289. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +43 -12
  290. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.d.ts +1 -1
  291. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +21 -3
  292. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.d.ts +1 -1
  293. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.js +30 -24
  294. package/front_end/third_party/web-vitals/package/dist/modules/lib/FCPEntryManager.d.ts +3 -0
  295. package/front_end/third_party/web-vitals/package/dist/modules/lib/FCPEntryManager.js +18 -0
  296. package/front_end/third_party/web-vitals/package/dist/modules/lib/InteractionManager.d.ts +2 -1
  297. package/front_end/third_party/web-vitals/package/dist/modules/lib/InteractionManager.js +18 -2
  298. package/front_end/third_party/web-vitals/package/dist/modules/lib/LCPEntryManager.d.ts +1 -0
  299. package/front_end/third_party/web-vitals/package/dist/modules/lib/LCPEntryManager.js +1 -0
  300. package/front_end/third_party/web-vitals/package/dist/modules/lib/bindReporter.d.ts +1 -1
  301. package/front_end/third_party/web-vitals/package/dist/modules/lib/generateUniqueID.js +1 -1
  302. package/front_end/third_party/web-vitals/package/dist/modules/lib/getLoadState.d.ts +1 -1
  303. package/front_end/third_party/web-vitals/package/dist/modules/lib/getLoadState.js +7 -7
  304. package/front_end/third_party/web-vitals/package/dist/modules/lib/getSelector.js +1 -1
  305. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.d.ts +1 -1
  306. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.js +4 -1
  307. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.d.ts +7 -3
  308. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.js +20 -11
  309. package/front_end/third_party/web-vitals/package/dist/modules/lib/initUnique.js +8 -3
  310. package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.d.ts +3 -1
  311. package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.js +19 -4
  312. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.js +1 -1
  313. package/front_end/third_party/web-vitals/package/dist/modules/lib/softNavs.d.ts +3 -0
  314. package/front_end/third_party/web-vitals/package/dist/modules/lib/softNavs.js +38 -0
  315. package/front_end/third_party/web-vitals/package/dist/modules/lib/whenIdleOrHidden.js +5 -1
  316. package/front_end/third_party/web-vitals/package/dist/modules/onCLS.d.ts +1 -1
  317. package/front_end/third_party/web-vitals/package/dist/modules/onCLS.js +30 -11
  318. package/front_end/third_party/web-vitals/package/dist/modules/onFCP.d.ts +1 -1
  319. package/front_end/third_party/web-vitals/package/dist/modules/onFCP.js +36 -4
  320. package/front_end/third_party/web-vitals/package/dist/modules/onINP.d.ts +1 -1
  321. package/front_end/third_party/web-vitals/package/dist/modules/onINP.js +42 -22
  322. package/front_end/third_party/web-vitals/package/dist/modules/onLCP.d.ts +1 -1
  323. package/front_end/third_party/web-vitals/package/dist/modules/onLCP.js +109 -30
  324. package/front_end/third_party/web-vitals/package/dist/modules/onTTFB.d.ts +1 -1
  325. package/front_end/third_party/web-vitals/package/dist/modules/onTTFB.js +25 -7
  326. package/front_end/third_party/web-vitals/package/dist/modules/types/base.d.ts +24 -1
  327. package/front_end/third_party/web-vitals/package/dist/modules/types/fcp.d.ts +1 -1
  328. package/front_end/third_party/web-vitals/package/dist/modules/types/inp.d.ts +14 -6
  329. package/front_end/third_party/web-vitals/package/dist/modules/types/lcp.d.ts +1 -1
  330. package/front_end/third_party/web-vitals/package/dist/modules/types/ttfb.d.ts +2 -2
  331. package/front_end/third_party/web-vitals/package/dist/modules/types.d.ts +26 -4
  332. package/front_end/third_party/web-vitals/package/package.json +21 -22
  333. package/front_end/third_party/web-vitals/package/src/attribution/onCLS.ts +1 -1
  334. package/front_end/third_party/web-vitals/package/src/attribution/onFCP.ts +62 -39
  335. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +52 -15
  336. package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +25 -7
  337. package/front_end/third_party/web-vitals/package/src/attribution/onTTFB.ts +43 -37
  338. package/front_end/third_party/web-vitals/package/src/lib/{polyfills/getFirstHiddenTimePolyfill.ts → FCPEntryManager.ts} +4 -14
  339. package/front_end/third_party/web-vitals/package/src/lib/InteractionManager.ts +22 -2
  340. package/front_end/third_party/web-vitals/package/src/lib/LCPEntryManager.ts +1 -0
  341. package/front_end/third_party/web-vitals/package/src/lib/bindReporter.ts +1 -1
  342. package/front_end/third_party/web-vitals/package/src/lib/generateUniqueID.ts +1 -1
  343. package/front_end/third_party/web-vitals/package/src/lib/getLoadState.ts +11 -12
  344. package/front_end/third_party/web-vitals/package/src/lib/getSelector.ts +1 -1
  345. package/front_end/third_party/web-vitals/package/src/lib/getVisibilityWatcher.ts +4 -1
  346. package/front_end/third_party/web-vitals/package/src/lib/initMetric.ts +24 -11
  347. package/front_end/third_party/web-vitals/package/src/lib/initUnique.ts +12 -4
  348. package/front_end/third_party/web-vitals/package/src/lib/observe.ts +26 -5
  349. package/front_end/third_party/web-vitals/package/src/lib/polyfills/interactionCountPolyfill.ts +1 -1
  350. package/front_end/third_party/web-vitals/package/src/lib/softNavs.ts +48 -0
  351. package/front_end/third_party/web-vitals/package/src/lib/whenIdleOrHidden.ts +12 -4
  352. package/front_end/third_party/web-vitals/package/src/onCLS.ts +75 -18
  353. package/front_end/third_party/web-vitals/package/src/onFCP.ts +66 -7
  354. package/front_end/third_party/web-vitals/package/src/onINP.ts +100 -39
  355. package/front_end/third_party/web-vitals/package/src/onLCP.ts +169 -34
  356. package/front_end/third_party/web-vitals/package/src/onTTFB.ts +50 -13
  357. package/front_end/third_party/web-vitals/package/src/types/base.ts +31 -10
  358. package/front_end/third_party/web-vitals/package/src/types/fcp.ts +1 -1
  359. package/front_end/third_party/web-vitals/package/src/types/inp.ts +14 -6
  360. package/front_end/third_party/web-vitals/package/src/types/lcp.ts +1 -1
  361. package/front_end/third_party/web-vitals/package/src/types/ttfb.ts +2 -2
  362. package/front_end/third_party/web-vitals/package/src/types.ts +32 -9
  363. package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +11 -11
  364. package/front_end/third_party/web-vitals/rebuild.sh +2 -2
  365. package/front_end/third_party/web-vitals/web-vitals-tsconfig.json +2 -0
  366. package/front_end/ui/components/buttons/Button.ts +16 -0
  367. package/front_end/ui/components/dialogs/Dialog.ts +1 -1
  368. package/front_end/ui/components/highlighting/HighlightManager.ts +6 -1
  369. package/front_end/ui/components/highlighting/highlighting.ts +1 -1
  370. package/front_end/ui/components/icon_button/FileSourceIcon.ts +1 -1
  371. package/front_end/ui/components/linkifier/LinkifierImpl.ts +1 -1
  372. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +2 -2
  373. package/front_end/ui/components/settings/SettingCheckbox.ts +12 -7
  374. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +2 -2
  375. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +6 -6
  376. package/front_end/ui/components/text_editor/javascript.ts +3 -1
  377. package/front_end/ui/components/tooltips/Tooltip.ts +1 -1
  378. package/front_end/ui/legacy/ContextMenu.ts +12 -2
  379. package/front_end/ui/legacy/ListControl.ts +1 -1
  380. package/front_end/ui/legacy/SelectMenu.docs.ts +17 -19
  381. package/front_end/ui/legacy/Toolbar.ts +4 -1
  382. package/front_end/ui/legacy/Treeoutline.ts +1 -1
  383. package/front_end/ui/legacy/components/color_picker/spectrum.css +1 -2
  384. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -1
  385. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +50 -4
  386. package/front_end/ui/legacy/components/object_ui/JavaScriptREPL.ts +3 -1
  387. package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +4 -4
  388. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +8 -7
  389. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +14 -11
  390. package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +1 -1
  391. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +15 -5
  392. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -4
  393. package/front_end/ui/legacy/components/utils/Linkifier.ts +5 -1
  394. package/front_end/ui/lit/render.ts +1 -1
  395. package/front_end/ui/settings/SettingUIRegistration.ts +8 -3
  396. package/front_end/ui/visual_logging/KnownContextValues.ts +8 -0
  397. package/front_end/ui/visual_logging/LoggingEvents.ts +1 -1
  398. package/inspector_overlay/main.ts +1 -1
  399. package/mcp/mcp.ts +5 -4
  400. package/package.json +13 -13
  401. package/front_end/models/ai_assistance/AgentProject.ts +0 -261
  402. package/front_end/models/ai_assistance/agents/PatchAgent.ts +0 -306
  403. package/front_end/models/issues_manager/CheckFormsIssuesTrigger.ts +0 -45
  404. package/front_end/models/text_utils/text_utils.ts +0 -5
  405. package/front_end/panels/ai_assistance/PatchWidget.ts +0 -867
  406. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +0 -368
  407. package/front_end/panels/ai_assistance/selectWorkspaceDialog.css +0 -92
@@ -1,4 +1,4 @@
1
- import { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types.js';
1
+ import type { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types.js';
2
2
  /** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */
3
3
  export declare const TTFBThresholds: MetricRatingThresholds;
4
4
  /**
@@ -14,10 +14,12 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { bindReporter } from './lib/bindReporter.js';
17
- import { initMetric } from './lib/initMetric.js';
18
- import { onBFCacheRestore } from './lib/bfcache.js';
17
+ import { checkSoftNavsEnabled } from './lib/softNavs.js';
19
18
  import { getNavigationEntry } from './lib/getNavigationEntry.js';
20
19
  import { getActivationStart } from './lib/getActivationStart.js';
20
+ import { initMetric } from './lib/initMetric.js';
21
+ import { observe } from './lib/observe.js';
22
+ import { getBFCacheRestoreTime, onBFCacheRestore } from './lib/bfcache.js';
21
23
  import { whenActivated } from './lib/whenActivated.js';
22
24
  /** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */
23
25
  export const TTFBThresholds = [800, 1800];
@@ -53,25 +55,41 @@ const whenReady = (callback) => {
53
55
  * and server processing time.
54
56
  */
55
57
  export const onTTFB = (onReport, opts = {}) => {
58
+ const softNavsEnabled = checkSoftNavsEnabled(opts);
56
59
  let metric = initMetric('TTFB');
57
60
  let report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
58
61
  whenReady(() => {
59
- const navigationEntry = getNavigationEntry();
60
- if (navigationEntry) {
62
+ const hardNavEntry = getNavigationEntry();
63
+ if (hardNavEntry) {
64
+ const responseStart = hardNavEntry.responseStart;
61
65
  // The activationStart reference is used because TTFB should be
62
66
  // relative to page activation rather than navigation start if the
63
67
  // page was prerendered. But in cases where `activationStart` occurs
64
68
  // after the first byte is received, this time should be clamped at 0.
65
- metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0);
66
- metric.entries = [navigationEntry];
69
+ metric.value = Math.max(responseStart - getActivationStart(), 0);
70
+ metric.entries = [hardNavEntry];
67
71
  report(true);
68
72
  // Only report TTFB after bfcache restores if a `navigation` entry
69
73
  // was reported for the initial load.
70
74
  onBFCacheRestore(() => {
71
- metric = initMetric('TTFB', 0);
75
+ metric = initMetric('TTFB', 0, 'back-forward-cache', metric.navigationId, metric.navigationInteractionId, metric.navigationURL, getBFCacheRestoreTime());
72
76
  report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
73
77
  report(true);
74
78
  });
79
+ // Listen for soft-navigation entries and emit a dummy 0 TTFB entry
80
+ if (softNavsEnabled) {
81
+ const reportSoftNavTTFBs = (entries) => {
82
+ entries.forEach((entry) => {
83
+ if (entry.navigationId) {
84
+ metric = initMetric('TTFB', 0, 'soft-navigation', entry.navigationId, entry.interactionId, entry.name, entry.startTime);
85
+ metric.entries = [entry];
86
+ report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
87
+ report(true);
88
+ }
89
+ });
90
+ };
91
+ observe(['soft-navigation'], reportSoftNavTTFBs, opts);
92
+ }
75
93
  }
76
94
  });
77
95
  };
@@ -49,8 +49,29 @@ export interface Metric {
49
49
  * - 'prerender': for pages that were prerendered.
50
50
  * - 'restore': for pages that were discarded by the browser and then
51
51
  * restored by the user.
52
+ * - 'soft-navigation': for soft navigations.
52
53
  */
53
- navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore';
54
+ navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore' | 'soft-navigation';
55
+ /**
56
+ * The navigationId the metric happened for. This is particularly relevant for soft navigations where
57
+ * the metric may be reported for a previous URL.
58
+ */
59
+ navigationId: number;
60
+ /**
61
+ * For metrics specific to a soft navigation, the interactionId of the
62
+ * interaction that triggered that soft navigation.
63
+ */
64
+ navigationInteractionId?: number;
65
+ /**
66
+ * The navigation startTime the metric is based from. This is particularly
67
+ * relevant for soft navigations where time origin is not 0.
68
+ */
69
+ navigationStartTime?: number;
70
+ /**
71
+ * The navigation URL the metric happened for. This is particularly relevant for soft navigations where
72
+ * the metric may be reported for a previous URL.
73
+ */
74
+ navigationURL?: string;
54
75
  }
55
76
  /** The union of supported metric types. */
56
77
  export type MetricType = CLSMetric | FCPMetric | INPMetric | LCPMetric | TTFBMetric;
@@ -80,6 +101,8 @@ export interface ReportCallback {
80
101
  }
81
102
  export interface ReportOpts {
82
103
  reportAllChanges?: boolean;
104
+ durationThreshold?: number;
105
+ reportSoftNavs?: boolean;
83
106
  }
84
107
  export interface AttributionReportOpts extends ReportOpts {
85
108
  generateTarget?: (el: Node | null) => string | undefined;
@@ -36,7 +36,7 @@ export interface FCPAttribution {
36
36
  * general page load issues. This can be used to access `serverTiming` for example:
37
37
  * navigationEntry?.serverTiming
38
38
  */
39
- navigationEntry?: PerformanceNavigationTiming;
39
+ navigationEntry?: PerformanceNavigationTiming | PerformanceSoftNavigation;
40
40
  }
41
41
  /**
42
42
  * An FCP-specific version of the Metric object with attribution.
@@ -43,35 +43,43 @@ export interface INPAttribution {
43
43
  * `generateTarget` configuration option was passed, then this will instead
44
44
  * be the return value of that function, falling back to the default if that
45
45
  * returns null or undefined.
46
+ * This value may not be set in cases where the event duration was less than
47
+ * the browser minimum reporting threshold, and thus no entry was dispatched.
46
48
  */
47
- interactionTarget: string;
49
+ interactionTarget?: string;
48
50
  /**
49
51
  * The time when the user first interacted during the frame where the INP
50
52
  * candidate interaction occurred (if more than one interaction occurred
51
53
  * within the frame, only the first time is reported).
54
+ * This value may not be set in cases where the event duration was less than
55
+ * the browser minimum reporting threshold, and thus no entry was dispatched.
52
56
  */
53
- interactionTime: DOMHighResTimeStamp;
57
+ interactionTime?: DOMHighResTimeStamp;
54
58
  /**
55
59
  * The type of interaction, based on the event type of the `event` entry
56
60
  * that corresponds to the interaction (i.e. the first `event` entry
57
61
  * containing an `interactionId` dispatched in a given animation frame).
58
62
  * For "pointerdown", "pointerup", or "click" events this will be "pointer",
59
63
  * and for "keydown" or "keyup" events this will be "keyboard".
64
+ * This value may not be set in cases where the event duration was less than
65
+ * the browser minimum reporting threshold, and thus no entry was dispatched.
60
66
  */
61
- interactionType: 'pointer' | 'keyboard';
67
+ interactionType?: 'pointer' | 'keyboard';
62
68
  /**
63
69
  * The best-guess timestamp of the next paint after the interaction.
64
70
  * In general, this timestamp is the same as the `startTime + duration` of
65
71
  * the event timing entry. However, since duration values are rounded to the
66
72
  * nearest 8ms (and can be rounded down), this value is clamped to always be
67
73
  * reported after the processing times.
74
+ * This value may not be set in cases where the event duration was less than
75
+ * the browser minimum reporting threshold, and thus no entry was dispatched.
68
76
  */
69
- nextPaintTime: DOMHighResTimeStamp;
77
+ nextPaintTime?: DOMHighResTimeStamp;
70
78
  /**
71
79
  * An array of Event Timing entries that were processed within the same
72
80
  * animation frame as the INP candidate interaction.
73
- * This array can be quite large so it will be empty if the
74
- * `includeProcessedEventEntries` configuration option is set to `false` to
81
+ * This array can be quite large so it will be empty unless the
82
+ * `includeProcessedEventEntries` configuration option is set to `true` to
75
83
  * conserve memory if these entries are not required.
76
84
  */
77
85
  processedEventEntries: PerformanceEventTiming[];
@@ -54,7 +54,7 @@ export interface LCPAttribution {
54
54
  * general page load issues. This can be used to access `serverTiming` for example:
55
55
  * navigationEntry?.serverTiming
56
56
  */
57
- navigationEntry?: PerformanceNavigationTiming;
57
+ navigationEntry?: PerformanceNavigationTiming | PerformanceSoftNavigation;
58
58
  /**
59
59
  * The `resource` entry for the LCP resource (if applicable), which is useful
60
60
  * for diagnosing resource load issues.
@@ -4,7 +4,7 @@ import type { Metric } from './base.js';
4
4
  */
5
5
  export interface TTFBMetric extends Metric {
6
6
  name: 'TTFB';
7
- entries: PerformanceNavigationTiming[];
7
+ entries: PerformanceNavigationTiming[] | PerformanceSoftNavigation[];
8
8
  }
9
9
  /**
10
10
  * An object containing potentially-helpful debugging information that
@@ -49,7 +49,7 @@ export interface TTFBAttribution {
49
49
  * general page load issues. This can be used to access `serverTiming` for
50
50
  * example: navigationEntry?.serverTiming
51
51
  */
52
- navigationEntry?: PerformanceNavigationTiming;
52
+ navigationEntry?: PerformanceNavigationTiming | PerformanceSoftNavigation;
53
53
  }
54
54
  /**
55
55
  * A TTFB-specific version of the Metric object with attribution.
@@ -5,9 +5,13 @@ export * from './types/inp.js';
5
5
  export * from './types/lcp.js';
6
6
  export * from './types/ttfb.js';
7
7
  interface PerformanceEntryMap {
8
- navigation: PerformanceNavigationTiming;
9
- resource: PerformanceResourceTiming;
10
- paint: PerformancePaintTiming;
8
+ 'event': PerformanceEventTiming;
9
+ 'interaction-contentful-paint': InteractionContentfulPaint;
10
+ 'layout-shift': LayoutShift;
11
+ 'navigation': PerformanceNavigationTiming;
12
+ 'paint': PerformancePaintTiming;
13
+ 'resource': PerformanceResourceTiming;
14
+ 'soft-navigation': PerformanceSoftNavigation;
11
15
  }
12
16
  declare global {
13
17
  interface Document {
@@ -17,15 +21,19 @@ declare global {
17
21
  interface Performance {
18
22
  getEntriesByType<K extends keyof PerformanceEntryMap>(type: K): PerformanceEntryMap[K][];
19
23
  }
24
+ interface PerformanceEntry {
25
+ navigationId?: number;
26
+ }
20
27
  interface PerformanceObserverInit {
21
28
  durationThreshold?: number;
22
29
  }
23
- interface PerformanceNavigationTiming {
30
+ interface PerformanceNavigationTiming extends PerformanceEntry {
24
31
  activationStart?: number;
25
32
  }
26
33
  interface PerformanceEventTiming extends PerformanceEntry {
27
34
  duration: DOMHighResTimeStamp;
28
35
  readonly interactionId: number;
36
+ readonly targetSelector: string;
29
37
  }
30
38
  interface LayoutShiftAttribution {
31
39
  node: Node | null;
@@ -45,6 +53,20 @@ declare global {
45
53
  readonly url: string;
46
54
  readonly element: Element | null;
47
55
  }
56
+ interface InteractionContentfulPaint extends PerformanceEntry {
57
+ readonly interactionId: number;
58
+ readonly largestContentfulPaint?: LargestContentfulPaint;
59
+ }
60
+ interface PerformanceSoftNavigation extends PerformanceEntry {
61
+ readonly interactionId: number;
62
+ readonly navigationType?: NavigationType;
63
+ readonly paintTime?: number;
64
+ readonly presentationTime?: number;
65
+ readonly getLargestInteractionContentfulPaint?: () => InteractionContentfulPaint | null;
66
+ }
67
+ var PerformanceSoftNavigation: {
68
+ prototype: PerformanceSoftNavigation;
69
+ };
48
70
  export type ScriptInvokerType = 'classic-script' | 'module-script' | 'event-listener' | 'user-callback' | 'resolve-promise' | 'reject-promise';
49
71
  export type ScriptWindowAttribution = 'self' | 'descendant' | 'ancestor' | 'same-page' | 'other';
50
72
  interface PerformanceScriptTiming extends PerformanceEntry {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-vitals",
3
- "version": "5.2.0",
3
+ "version": "6.0.0",
4
4
  "description": "Easily measure performance metrics in JavaScript",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -90,6 +90,7 @@
90
90
  "release:alpha": "npm version prerelease --preid=alpha -m 'Release v%s' && npm publish --tag next",
91
91
  "release:beta": "npm version prerelease --preid=beta -m 'Release v%s' && npm publish --tag next",
92
92
  "release:rc": "npm version prerelease --preid=rc -m 'Release v%s' && npm publish --tag next",
93
+ "release:soft-navs": "npm run build && npm publish --tag soft-navs",
93
94
  "test": "npm-run-all build test:unit -p -r test:e2e test:server",
94
95
  "test:e2e": "wdio",
95
96
  "test:server": "node test/server.js",
@@ -125,11 +126,6 @@
125
126
  "bugs": {
126
127
  "url": "https://github.com/GoogleChrome/web-vitals/issues"
127
128
  },
128
- "husky": {
129
- "hooks": {
130
- "pre-commit": "npm run lint"
131
- }
132
- },
133
129
  "prettier": {
134
130
  "arrowParens": "always",
135
131
  "bracketSpacing": false,
@@ -137,25 +133,28 @@
137
133
  "singleQuote": true
138
134
  },
139
135
  "devDependencies": {
140
- "@babel/core": "^7.28.5",
141
- "@babel/preset-env": "^7.28.5",
142
- "@rollup/plugin-babel": "^6.1.0",
143
- "@rollup/plugin-terser": "^0.4.4",
144
- "@typescript-eslint/eslint-plugin": "^8.52.0",
145
- "@typescript-eslint/parser": "^8.52.0",
146
- "@wdio/cli": "^9.23.0",
147
- "@wdio/local-runner": "^9.25.0",
148
- "@wdio/mocha-framework": "^9.25.0",
149
- "@wdio/spec-reporter": "^9.25.0",
150
- "eslint": "^9.39.2",
151
- "fs-extra": "^11.3.3",
136
+ "@babel/core": "^7.29.7",
137
+ "@babel/preset-env": "^7.29.7",
138
+ "@eslint/eslintrc": "^3.3.6",
139
+ "@eslint/js": "^10.0.1",
140
+ "@rollup/plugin-babel": "^7.1.0",
141
+ "@rollup/plugin-terser": "^1.0.0",
142
+ "@typescript-eslint/eslint-plugin": "^8.64.0",
143
+ "@typescript-eslint/parser": "^8.64.0",
144
+ "@wdio/cli": "^9.29.1",
145
+ "@wdio/local-runner": "^9.29.1",
146
+ "@wdio/mocha-framework": "^9.29.1",
147
+ "@wdio/spec-reporter": "^9.29.1",
148
+ "eslint": "^10.7.0",
149
+ "fs-extra": "^11.3.6",
150
+ "globals": "^17.7.0",
152
151
  "husky": "^9.1.7",
153
- "lint-staged": "^16.2.7",
152
+ "lint-staged": "^17.0.8",
154
153
  "npm-run-all": "^4.1.5",
155
154
  "nunjucks": "^3.2.4",
156
- "prettier": "^3.7.4",
157
- "rollup": "^4.55.1",
158
- "typescript": "^5.9.3",
155
+ "prettier": "^3.9.5",
156
+ "rollup": "^4.62.2",
157
+ "typescript": "^6.0.3",
159
158
  "yargs": "^18.0.0"
160
159
  },
161
160
  "lint-staged": {
@@ -19,7 +19,7 @@ import {getLoadState} from '../lib/getLoadState.js';
19
19
  import {getSelector} from '../lib/getSelector.js';
20
20
  import {initUnique} from '../lib/initUnique.js';
21
21
  import {onCLS as unattributedOnCLS} from '../onCLS.js';
22
- import {
22
+ import type {
23
23
  CLSAttribution,
24
24
  CLSMetric,
25
25
  CLSMetricWithAttribution,
@@ -17,58 +17,81 @@
17
17
  import {getBFCacheRestoreTime} from '../lib/bfcache.js';
18
18
  import {getLoadState} from '../lib/getLoadState.js';
19
19
  import {getNavigationEntry} from '../lib/getNavigationEntry.js';
20
+ import {initUnique} from '../lib/initUnique.js';
21
+ import {FCPEntryManager} from '../lib/FCPEntryManager.js';
22
+ import {checkSoftNavsEnabled} from '../lib/softNavs.js';
20
23
  import {onFCP as unattributedOnFCP} from '../onFCP.js';
21
- import {
24
+ import type {
22
25
  FCPAttribution,
23
26
  FCPMetric,
24
27
  FCPMetricWithAttribution,
25
28
  AttributionReportOpts,
26
29
  } from '../types.js';
27
30
 
28
- const attributeFCP = (metric: FCPMetric): FCPMetricWithAttribution => {
29
- // Use a default object if no other attribution has been set.
30
- let attribution: FCPAttribution = {
31
- timeToFirstByte: 0,
32
- firstByteToFCP: metric.value,
33
- loadState: getLoadState(getBFCacheRestoreTime()),
34
- };
31
+ export const onFCP = (
32
+ onReport: (metric: FCPMetricWithAttribution) => void,
33
+ opts: AttributionReportOpts = {},
34
+ ) => {
35
+ opts = Object.assign({}, opts);
36
+
37
+ // Init the fcpEntryManager (which will already be initialised in the
38
+ // unattributed onFCP method if soft navigation reporting is enabled
39
+ // and so will return that fcpEntryManager, rather than a new one)
40
+ const fcpEntryManager = initUnique(opts, FCPEntryManager);
41
+ if (checkSoftNavsEnabled(opts)) {
42
+ fcpEntryManager._softNavigationEntryMap = new Map();
43
+ }
35
44
 
36
- if (metric.entries.length) {
37
- const navigationEntry = getNavigationEntry();
38
- const fcpEntry = metric.entries.at(-1);
45
+ const attributeFCP = (metric: FCPMetric): FCPMetricWithAttribution => {
46
+ // Use a default object if no other attribution has been set.
47
+ let attribution: FCPAttribution = {
48
+ timeToFirstByte: 0,
49
+ firstByteToFCP: metric.value,
50
+ loadState: getLoadState(getBFCacheRestoreTime()),
51
+ };
39
52
 
40
- if (navigationEntry) {
41
- const activationStart = navigationEntry.activationStart || 0;
42
- const ttfb = Math.max(0, navigationEntry.responseStart - activationStart);
53
+ if (metric.navigationType !== 'soft-navigation') {
54
+ if (metric.entries.length) {
55
+ const navigationEntry = getNavigationEntry();
56
+ const fcpEntry = metric.entries.at(-1);
57
+ if (navigationEntry) {
58
+ const responseStart = navigationEntry.responseStart;
59
+ const activationStart = navigationEntry.activationStart || 0;
60
+ const ttfb = Math.max(0, responseStart - activationStart);
43
61
 
44
- attribution = {
45
- timeToFirstByte: ttfb,
46
- firstByteToFCP: metric.value - ttfb,
47
- loadState: getLoadState(metric.entries[0].startTime),
48
- navigationEntry,
49
- fcpEntry,
50
- };
62
+ attribution = {
63
+ timeToFirstByte: ttfb,
64
+ firstByteToFCP: metric.value - ttfb,
65
+ loadState: getLoadState(metric.entries[0].startTime),
66
+ navigationEntry,
67
+ fcpEntry,
68
+ };
69
+ }
70
+ }
71
+ } else {
72
+ // Lookup the soft navigation entry. Do not use getEntriesByType since
73
+ // that is limited to the first 50 navigation entries due to buffer size.
74
+ const navigationEntry = fcpEntryManager._softNavigationEntryMap?.get(
75
+ metric.navigationId,
76
+ );
77
+ if (navigationEntry) {
78
+ attribution = {
79
+ timeToFirstByte: 0,
80
+ firstByteToFCP: metric.value,
81
+ loadState: 'complete',
82
+ navigationEntry,
83
+ };
84
+ }
51
85
  }
52
- }
53
86
 
54
- // Use `Object.assign()` to ensure the original metric object is returned.
55
- const metricWithAttribution: FCPMetricWithAttribution = Object.assign(
56
- metric,
57
- {attribution},
58
- );
59
- return metricWithAttribution;
60
- };
87
+ // Use `Object.assign()` to ensure the original metric object is returned.
88
+ const metricWithAttribution: FCPMetricWithAttribution = Object.assign(
89
+ metric,
90
+ {attribution},
91
+ );
92
+ return metricWithAttribution;
93
+ };
61
94
 
62
- /**
63
- * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
64
- * calls the `callback` function once the value is ready, along with the
65
- * relevant `paint` performance entry used to determine the value. The reported
66
- * value is a `DOMHighResTimeStamp`.
67
- */
68
- export const onFCP = (
69
- onReport: (metric: FCPMetricWithAttribution) => void,
70
- opts: AttributionReportOpts = {},
71
- ) => {
72
95
  unattributedOnFCP((metric: FCPMetric) => {
73
96
  onReport(attributeFCP(metric));
74
97
  }, opts);
@@ -17,11 +17,14 @@
17
17
  import {getLoadState} from '../lib/getLoadState.js';
18
18
  import {getSelector} from '../lib/getSelector.js';
19
19
  import {initUnique} from '../lib/initUnique.js';
20
- import {InteractionManager, Interaction} from '../lib/InteractionManager.js';
20
+ import {
21
+ InteractionManager,
22
+ type Interaction,
23
+ } from '../lib/InteractionManager.js';
21
24
  import {observe} from '../lib/observe.js';
22
25
  import {whenIdleOrHidden} from '../lib/whenIdleOrHidden.js';
23
26
  import {onINP as unattributedOnINP} from '../onINP.js';
24
- import {
27
+ import type {
25
28
  INPAttribution,
26
29
  INPAttributionReportOpts,
27
30
  INPMetric,
@@ -63,7 +66,7 @@ const MAX_PENDING_FRAMES = 10;
63
66
  *
64
67
  * A custom `includeProcessedEventEntries` configuration option can optionally
65
68
  * be passed to control whether the `processedEventEntries` array in the
66
- * attribution object is populated. The default value is `true`.
69
+ * attribution object is populated. The default value is `false`.
67
70
  *
68
71
  * If the `reportAllChanges` configuration option is set to `true`, the
69
72
  * `callback` function will be called as soon as the value is initially
@@ -130,10 +133,19 @@ export const onINP = (
130
133
 
131
134
  const saveInteractionTarget = (interaction: Interaction) => {
132
135
  if (!interactionTargetMap.get(interaction)) {
133
- const node = interaction.entries[0].target;
136
+ // Use find to get first selector
137
+ const node = interaction.entries.find((e) => e.target)?.target;
134
138
  if (node) {
135
139
  const customTarget = opts.generateTarget?.(node) ?? getSelector(node);
136
140
  interactionTargetMap.set(interaction, customTarget);
141
+ } else {
142
+ // Fall back to targetSelector
143
+ const selector = interaction.entries.find(
144
+ (e) => e.targetSelector,
145
+ )?.targetSelector;
146
+ if (selector) {
147
+ interactionTargetMap.set(interaction, selector);
148
+ }
137
149
  }
138
150
  }
139
151
  };
@@ -174,7 +186,7 @@ export const onINP = (
174
186
  );
175
187
  // processedEventEntries can be quite large, so only include them if
176
188
  // the user explicitly requests them (default is to include).
177
- if (opts.includeProcessedEventEntries !== false) {
189
+ if (opts.includeProcessedEventEntries) {
178
190
  group.entries.push(entry);
179
191
  }
180
192
 
@@ -191,7 +203,7 @@ export const onINP = (
191
203
  renderTime,
192
204
  // processedEventEntries can be quite large, so only include them if
193
205
  // the user explicitly requests them (default is to include).
194
- entries: opts.includeProcessedEventEntries !== false ? [entry] : [],
206
+ entries: opts.includeProcessedEventEntries ? [entry] : [],
195
207
  };
196
208
 
197
209
  pendingEntriesGroups.push(group);
@@ -282,6 +294,7 @@ export const onINP = (
282
294
  rating: 'good',
283
295
  value: entry.duration,
284
296
  delta: entry.duration,
297
+ navigationId: (entry as any).navigationId,
285
298
  navigationType: 'navigate',
286
299
  id: 'N/A',
287
300
  });
@@ -317,12 +330,18 @@ export const onINP = (
317
330
  };
318
331
 
319
332
  const attributeLoAFDetails = (attribution: INPAttribution) => {
320
- // If there is no LoAF data then nothing further to attribute
321
- if (!attribution.longAnimationFrameEntries?.length) {
333
+ const interactionTime = attribution.interactionTime;
334
+ const nextPaintTime = attribution.nextPaintTime;
335
+
336
+ // If there is no LoAF data, interactionTime or paintTime
337
+ // then nothing further to attribute here.
338
+ if (
339
+ !attribution.longAnimationFrameEntries?.length ||
340
+ !interactionTime ||
341
+ !nextPaintTime
342
+ ) {
322
343
  return;
323
344
  }
324
-
325
- const interactionTime = attribution.interactionTime;
326
345
  const inputDelay = attribution.inputDelay;
327
346
  const processingDuration = attribution.processingDuration;
328
347
 
@@ -385,7 +404,7 @@ export const onINP = (
385
404
  ? lastLoAF.startTime + lastLoAF.duration
386
405
  : 0;
387
406
  if (lastLoAFEndTime >= interactionTime + inputDelay + processingDuration) {
388
- totalPaintDuration = attribution.nextPaintTime - lastLoAFEndTime;
407
+ totalPaintDuration = nextPaintTime - lastLoAFEndTime;
389
408
  }
390
409
 
391
410
  if (longestScriptEntry && longestScriptSubpart) {
@@ -399,7 +418,7 @@ export const onINP = (
399
418
  attribution.totalStyleAndLayoutDuration = totalStyleAndLayoutDuration;
400
419
  attribution.totalPaintDuration = totalPaintDuration;
401
420
  attribution.totalUnattributedDuration =
402
- attribution.nextPaintTime -
421
+ nextPaintTime -
403
422
  interactionTime -
404
423
  totalScriptDuration -
405
424
  totalStyleAndLayoutDuration -
@@ -407,10 +426,29 @@ export const onINP = (
407
426
  };
408
427
 
409
428
  const attributeINP = (metric: INPMetric): INPMetricWithAttribution => {
429
+ // Soft navs and bfcache can have a dummy INP as no first-input entry to
430
+ // fall back on so we report dummy values when the interactionCount has
431
+ // gone up, even if no entry was emitted.
432
+ // See https://github.com/GoogleChrome/web-vitals/issues/724
433
+ // All other INPs should have at least one entry, but we'll do same dummy
434
+ // processing if they don't for some reason.
435
+ if (metric.entries.length === 0) {
436
+ const navStartTime = metric.navigationStartTime || 0;
437
+ const attribution: INPAttribution = {
438
+ processedEventEntries: [],
439
+ longAnimationFrameEntries: [],
440
+ inputDelay: 0,
441
+ processingDuration: 0,
442
+ presentationDelay: metric.value,
443
+ loadState: getLoadState(navStartTime),
444
+ };
445
+ return Object.assign(metric, {attribution});
446
+ }
447
+
410
448
  const firstEntry = metric.entries[0];
411
449
  const group = entryToEntriesGroupMap.get(firstEntry)!;
412
450
 
413
- const processingStart = firstEntry.processingStart;
451
+ const processingStart = group.processingStart;
414
452
 
415
453
  // Due to the fact that durations can be rounded down to the nearest 8ms,
416
454
  // we have to clamp `nextPaintTime` so it doesn't appear to occur before
@@ -420,7 +458,6 @@ export const onINP = (
420
458
  firstEntry.startTime + firstEntry.duration,
421
459
  processingStart,
422
460
  );
423
-
424
461
  // For the purposes of attribution, clamp `processingEnd` to `nextPaintTime`,
425
462
  // so processing is never reported as taking longer than INP (which can
426
463
  // happen via the web APIs in the case of sync modals, e.g. `alert()`).
@@ -469,7 +506,7 @@ export const onINP = (
469
506
  };
470
507
 
471
508
  // Start observing LoAF entries for attribution.
472
- observe('long-animation-frame', handleLoAFEntries);
509
+ observe(['long-animation-frame'], handleLoAFEntries, opts);
473
510
 
474
511
  unattributedOnINP((metric: INPMetric) => {
475
512
  onReport(attributeINP(metric));