chrome-devtools-frontend 1.0.1616061 → 1.0.1621064
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.
- package/AUTHORS +1 -0
- package/docs/checklist/README.md +8 -7
- package/eslint.config.mjs +7 -0
- package/front_end/core/common/Object.ts +11 -2
- package/front_end/core/dom_extension/DOMExtension.ts +11 -8
- package/front_end/core/host/AidaClient.ts +8 -0
- package/front_end/core/host/AidaGcaTranslation.ts +1 -0
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/platform/api/HostRuntime.ts +2 -2
- package/front_end/core/platform/browser/HostRuntime.ts +4 -2
- package/front_end/core/platform/node/HostRuntime.ts +2 -2
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/NetworkManager.ts +30 -4
- package/front_end/core/sdk/NetworkRequest.ts +2 -10
- package/front_end/core/sdk/Resource.ts +2 -1
- package/front_end/core/sdk/ServerSentEventsProtocol.ts +1 -1
- package/front_end/core/sdk/TraceObject.ts +7 -2
- package/front_end/entrypoint_template.html +1 -2
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +119 -15
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +43 -33
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +2 -1
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +9 -6
- package/front_end/entrypoints/main/MainImpl.ts +0 -2
- package/front_end/generated/InspectorBackendCommands.ts +8 -7
- package/front_end/generated/SupportedCSSProperties.js +119 -100
- package/front_end/generated/protocol-mapping.d.ts +1 -9
- package/front_end/generated/protocol-proxy-api.d.ts +1 -9
- package/front_end/generated/protocol.ts +24 -1
- package/front_end/legacy/legacy-defs.d.ts +1 -1
- package/front_end/models/ai_assistance/AiConversation.ts +1 -0
- package/front_end/models/ai_assistance/AiHistoryStorage.ts +39 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -0
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +28 -16
- package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +512 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +112 -145
- package/front_end/models/ai_assistance/agents/README.md +0 -5
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +9 -16
- package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +19 -1
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +48 -13
- package/front_end/models/bindings/SymbolizedError.ts +95 -8
- package/front_end/models/emulation/DeviceModeModel.ts +42 -13
- package/front_end/models/emulation/EmulatedDevices.ts +1 -1
- package/front_end/models/issues_manager/IssuesManager.ts +13 -6
- package/front_end/models/issues_manager/IssuesManagerEvents.ts +1 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +2 -2
- package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +1 -0
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +49 -10
- package/front_end/models/stack_trace/ErrorStackParser.ts +18 -0
- package/front_end/models/stack_trace/StackTraceModel.ts +5 -1
- package/front_end/models/text_utils/ContentData.ts +71 -10
- package/front_end/models/trace/types/File.ts +8 -1
- package/front_end/models/web_mcp/WebMCPModel.ts +22 -0
- package/front_end/models/workspace/UISourceCode.ts +4 -4
- package/front_end/panels/accessibility/ARIAAttributesView.ts +4 -4
- package/front_end/panels/accessibility/AccessibilitySubPane.ts +3 -2
- package/front_end/panels/accessibility/SourceOrderView.ts +4 -4
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +66 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +144 -21
- package/front_end/panels/ai_assistance/components/ChatView.ts +43 -8
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +1 -0
- package/front_end/panels/ai_assistance/components/WalkthroughUtils.ts +74 -0
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +34 -5
- package/front_end/panels/ai_assistance/components/chatMessage.css +11 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +7 -0
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +1 -1
- package/front_end/panels/application/CookieItemsView.ts +8 -9
- package/front_end/panels/application/DOMStorageItemsView.ts +3 -3
- package/front_end/panels/application/DeviceBoundSessionsModel.ts +7 -0
- package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +21 -0
- package/front_end/panels/application/DeviceBoundSessionsView.ts +2 -2
- package/front_end/panels/application/ExtensionStorageItemsView.ts +1 -1
- package/front_end/panels/application/KeyValueStorageItemsView.ts +32 -14
- package/front_end/panels/application/ResourcesPanel.ts +5 -5
- package/front_end/panels/application/StorageItemsToolbar.ts +0 -19
- package/front_end/panels/application/WebMCPView.ts +285 -86
- package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +4 -4
- package/front_end/panels/application/preloading/components/MismatchedPreloadingGrid.ts +4 -4
- package/front_end/panels/application/webMCPView.css +261 -182
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +9 -5
- package/front_end/panels/changes/ChangesSidebar.ts +2 -2
- package/front_end/panels/changes/ChangesView.ts +9 -14
- package/front_end/panels/console/ConsolePanel.ts +10 -3
- package/front_end/panels/console/ConsoleSidebar.ts +5 -5
- package/front_end/panels/console/ConsoleView.ts +11 -4
- package/front_end/panels/console/ConsoleViewMessage.ts +1 -19
- package/front_end/panels/coverage/CoverageView.ts +4 -5
- package/front_end/panels/elements/ElementsPanel.ts +9 -12
- package/front_end/panels/elements/ElementsSidebarPane.ts +4 -5
- package/front_end/panels/elements/ElementsTreeElement.ts +61 -0
- package/front_end/panels/elements/ElementsTreeOutline.ts +46 -0
- package/front_end/panels/elements/LayersWidget.ts +2 -2
- package/front_end/panels/elements/MetricsSidebarPane.ts +5 -4
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +11 -6
- package/front_end/panels/elements/StylesSidebarPane.ts +4 -1
- package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +19 -20
- package/front_end/panels/elements/components/ElementsBreadcrumbsUtils.ts +29 -29
- package/front_end/panels/elements/components/QueryContainer.ts +5 -6
- package/front_end/panels/elements/components/components.ts +0 -2
- package/front_end/panels/emulation/MediaQueryInspector.ts +4 -7
- package/front_end/panels/layer_viewer/LayerDetailsView.ts +4 -7
- package/front_end/panels/layer_viewer/Layers3DView.ts +2 -2
- package/front_end/panels/lighthouse/LighthouseStartView.ts +2 -2
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +47 -66
- package/front_end/panels/network/NetworkConfigView.ts +11 -11
- package/front_end/panels/network/RequestConditionsDrawer.ts +6 -4
- package/front_end/panels/network/RequestCookiesView.ts +2 -2
- package/front_end/panels/network/RequestDeviceBoundSessionsView.ts +2 -2
- package/front_end/panels/network/RequestHeadersView.ts +2 -2
- package/front_end/panels/network/components/DirectSocketConnectionView.ts +4 -5
- package/front_end/panels/performance_monitor/PerformanceMonitor.ts +6 -9
- package/front_end/panels/profiler/HeapProfileView.ts +29 -4
- package/front_end/panels/profiler/ProfilesPanel.ts +1 -1
- package/front_end/panels/protocol_monitor/JSONEditor.css +8 -1
- package/front_end/panels/protocol_monitor/JSONEditor.ts +7 -2
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +6 -4
- package/front_end/panels/recorder/components/ControlButton.ts +4 -4
- package/front_end/panels/recorder/components/StepView.ts +6 -6
- package/front_end/panels/search/SearchView.ts +4 -7
- package/front_end/panels/sources/DebuggerPausedMessage.ts +18 -22
- package/front_end/panels/sources/SourcesView.ts +1 -1
- package/front_end/panels/sources/TabbedEditorContainer.ts +2 -2
- package/front_end/panels/sources/ThreadsSidebarPane.ts +2 -4
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +24 -20
- package/front_end/panels/timeline/StatusDialog.ts +5 -8
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +10 -0
- package/front_end/panels/timeline/TimelineLoader.ts +3 -4
- package/front_end/panels/timeline/TimelineSelectorStatsView.ts +2 -2
- package/front_end/panels/timeline/components/TimelineRangeSummaryView.ts +2 -0
- package/front_end/panels/timeline/components/TimelineSummary.ts +9 -1
- package/front_end/panels/timeline/components/timelineSummary.css +4 -0
- package/front_end/panels/timeline/overlays/components/TimespanBreakdownOverlay.ts +2 -2
- package/front_end/panels/timeline/thirdPartyTreeView.css +8 -1
- package/front_end/panels/web_audio/WebAudioView.ts +5 -4
- package/front_end/panels/whats_new/ReleaseNoteText.ts +9 -9
- package/front_end/panels/whats_new/resources/WNDT.md +9 -6
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.d.ts +41 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.d.ts +13 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.js +21 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/ElementHandle.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +5 -5
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserConnector.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserConnector.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ElementHandle.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.js +52 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebMCP.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebMCP.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts +25 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +0 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/third_party/urlpattern-polyfill/urlpattern-polyfill.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/third_party/urlpattern-polyfill/urlpattern-polyfill.js +853 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +91 -11
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +1046 -33
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.d.ts +41 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.d.ts +13 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.js +21 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/ElementHandle.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +5 -5
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserConnector.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserConnector.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ElementHandle.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.js +52 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebMCP.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebMCP.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts +25 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +0 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/third_party/urlpattern-polyfill/urlpattern-polyfill.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/third_party/urlpattern-polyfill/urlpattern-polyfill.js +805 -0
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +91 -11
- package/front_end/third_party/puppeteer/package/package.json +3 -2
- package/front_end/third_party/puppeteer/package/src/api/ElementHandle.ts +53 -11
- package/front_end/third_party/puppeteer/package/src/api/Extension.ts +29 -1
- package/front_end/third_party/puppeteer/package/src/bidi/ElementHandle.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +6 -0
- package/front_end/third_party/puppeteer/package/src/cdp/BrowserConnector.ts +2 -0
- package/front_end/third_party/puppeteer/package/src/cdp/ElementHandle.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Extension.ts +9 -2
- package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +59 -0
- package/front_end/third_party/puppeteer/package/src/cdp/WebMCP.ts +6 -1
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +26 -0
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +2 -0
- package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +0 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/third_party/puppeteer/puppeteer-tsconfig.json +2 -1
- package/front_end/third_party/web-vitals/README.chromium +2 -2
- package/front_end/third_party/web-vitals/package/README.md +21 -10
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onCLS.js +2 -4
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.js +1 -2
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.d.ts +4 -0
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +44 -39
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +25 -19
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.js +1 -2
- package/front_end/third_party/web-vitals/package/dist/modules/lib/doubleRAF.js +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/lib/getActivationStart.js +1 -2
- package/front_end/third_party/web-vitals/package/dist/modules/lib/getLoadState.js +16 -18
- package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.js +2 -1
- package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.d.ts +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.js +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.js +1 -3
- package/front_end/third_party/web-vitals/package/dist/modules/lib/whenActivated.js +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/lib/whenIdleOrHidden.js +11 -7
- package/front_end/third_party/web-vitals/package/dist/modules/onCLS.js +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/types/inp.d.ts +4 -0
- package/front_end/third_party/web-vitals/package/dist/modules/types.d.ts +1 -2
- package/front_end/third_party/web-vitals/package/dist/modules/types.js +0 -1
- package/front_end/third_party/web-vitals/package/package.json +24 -27
- package/front_end/third_party/web-vitals/package/src/attribution/onCLS.ts +2 -7
- package/front_end/third_party/web-vitals/package/src/attribution/onFCP.ts +1 -2
- package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +49 -43
- package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +27 -24
- package/front_end/third_party/web-vitals/package/src/attribution/onTTFB.ts +1 -2
- package/front_end/third_party/web-vitals/package/src/lib/doubleRAF.ts +1 -1
- package/front_end/third_party/web-vitals/package/src/lib/getActivationStart.ts +1 -2
- package/front_end/third_party/web-vitals/package/src/lib/getLoadState.ts +21 -20
- package/front_end/third_party/web-vitals/package/src/lib/getVisibilityWatcher.ts +2 -3
- package/front_end/third_party/web-vitals/package/src/lib/observe.ts +1 -1
- package/front_end/third_party/web-vitals/package/src/lib/polyfills/interactionCountPolyfill.ts +2 -4
- package/front_end/third_party/web-vitals/package/src/lib/whenActivated.ts +1 -1
- package/front_end/third_party/web-vitals/package/src/lib/whenIdleOrHidden.ts +13 -7
- package/front_end/third_party/web-vitals/package/src/onCLS.ts +1 -1
- package/front_end/third_party/web-vitals/package/src/types/inp.ts +4 -0
- package/front_end/third_party/web-vitals/package/src/types.ts +1 -2
- package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +13 -74
- package/front_end/third_party/web-vitals/rebuild.sh +3 -3
- package/front_end/third_party/web-vitals/web-vitals-tsconfig.json +0 -1
- package/front_end/ui/components/icon_button/iconButton.css +1 -0
- package/front_end/ui/components/legacy_wrapper/LegacyWrapper.ts +6 -6
- package/front_end/ui/components/lists/list.css +4 -0
- package/front_end/ui/legacy/Dialog.ts +21 -2
- package/front_end/ui/legacy/SoftContextMenu.ts +3 -3
- package/front_end/ui/legacy/SplitWidget.ts +9 -9
- package/front_end/ui/legacy/TabbedPane.ts +12 -12
- package/front_end/ui/legacy/View.ts +24 -22
- package/front_end/ui/legacy/ViewManager.ts +12 -12
- package/front_end/ui/legacy/ViewRegistration.ts +2 -2
- package/front_end/ui/legacy/Widget.ts +165 -119
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +10 -5
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +9 -6
- package/front_end/ui/legacy/components/utils/Linkifier.ts +37 -11
- package/front_end/ui/legacy/components/utils/jsUtils.css +1 -0
- package/front_end/ui/legacy/inspectorCommon.css +0 -6
- package/front_end/ui/lit/render.ts +11 -9
- package/front_end/ui/visual_logging/KnownContextValues.ts +36 -0
- package/package.json +1 -1
- package/front_end/Images/src/dots-circle.svg +0 -10
- package/front_end/panels/elements/components/Helper.ts +0 -35
- package/front_end/third_party/web-vitals/package/dist/modules/types/polyfills.d.ts +0 -4
- package/front_end/third_party/web-vitals/package/dist/modules/types/polyfills.js +0 -16
- package/front_end/third_party/web-vitals/package/src/types/polyfills.ts +0 -24
|
@@ -324,7 +324,7 @@ While `web-vitals` can be called directly from Google Tag Manager, using a pre-d
|
|
|
324
324
|
|
|
325
325
|
### Send attribution data
|
|
326
326
|
|
|
327
|
-
When using the [attribution build](#attribution-build), you can send additional data to help you debug _why_ the metric values are
|
|
327
|
+
When using the [attribution build](#attribution-build), you can send additional data to help you debug _why_ the metric values are the way they are.
|
|
328
328
|
|
|
329
329
|
This example sends an additional `debug_target` param to Google Analytics, corresponding to the element most associated with each metric.
|
|
330
330
|
|
|
@@ -349,7 +349,7 @@ function sendToGoogleAnalytics({name, delta, value, id, attribution}) {
|
|
|
349
349
|
eventParams.debug_target = attribution.interactionTarget;
|
|
350
350
|
break;
|
|
351
351
|
case 'LCP':
|
|
352
|
-
eventParams.debug_target = attribution.
|
|
352
|
+
eventParams.debug_target = attribution.target;
|
|
353
353
|
break;
|
|
354
354
|
}
|
|
355
355
|
|
|
@@ -481,7 +481,7 @@ The following table lists all the builds distributed with the `web-vitals` packa
|
|
|
481
481
|
|
|
482
482
|
Most developers will generally want to use "standard" build (via either the ES module or UMD version, depending on your bundler/build system), as it's the easiest to use out of the box and integrate into existing tools.
|
|
483
483
|
|
|
484
|
-
However, if you'd
|
|
484
|
+
However, if you'd like to collect additional debug information to help you diagnose performance bottlenecks based on real-user issues, use the ["attribution" build](#attribution-build).
|
|
485
485
|
|
|
486
486
|
For guidance on how to collect and use real-user data to debug performance issues, see [Debug performance in the field](https://web.dev/debug-performance-in-the-field/).
|
|
487
487
|
|
|
@@ -659,6 +659,7 @@ Metric-specific subclasses:
|
|
|
659
659
|
```ts
|
|
660
660
|
interface INPAttributionReportOpts extends AttributionReportOpts {
|
|
661
661
|
durationThreshold?: number;
|
|
662
|
+
includeProcessedEventEntries?: boolean;
|
|
662
663
|
}
|
|
663
664
|
```
|
|
664
665
|
|
|
@@ -800,7 +801,7 @@ In the [attribution build](#attribution-build) each of the metric functions has
|
|
|
800
801
|
}
|
|
801
802
|
```
|
|
802
803
|
|
|
803
|
-
For example, if a web page has unique `data-name`
|
|
804
|
+
For example, if a web page has unique `data-name` attribute on many elements, you may prefer to use those over the built-in selector-style strings that are generated by default.
|
|
804
805
|
|
|
805
806
|
```js
|
|
806
807
|
function customGenerateTarget(el) {
|
|
@@ -814,6 +815,15 @@ In the [attribution build](#attribution-build) each of the metric functions has
|
|
|
814
815
|
onLCP(sendToAnalytics, {generateTarget: customGenerateTarget});
|
|
815
816
|
```
|
|
816
817
|
|
|
818
|
+
3. The `onINP` `AttributionReportOpts` supports an additional, optional, `includeProcessedEventEntries` configuration option. When set to `false`, the `event` performance entries will not be included in the `attribution` object to conserve memory if these entries are not needed. The default value is `true`.
|
|
819
|
+
|
|
820
|
+
```ts
|
|
821
|
+
interface INPAttributionReportOpts extends AttributionReportOpts {
|
|
822
|
+
durationThreshold?: number;
|
|
823
|
+
includeProcessedEventEntries?: boolean;
|
|
824
|
+
}
|
|
825
|
+
```
|
|
826
|
+
|
|
817
827
|
The next sections document the shape of the `attribution` object for each of the metrics:
|
|
818
828
|
|
|
819
829
|
#### `CLSAttribution`
|
|
@@ -930,6 +940,9 @@ interface INPAttribution {
|
|
|
930
940
|
/**
|
|
931
941
|
* An array of Event Timing entries that were processed within the same
|
|
932
942
|
* animation frame as the INP candidate interaction.
|
|
943
|
+
* This array can be quite large so it will be empty if the
|
|
944
|
+
* `includeProcessedEventEntries` configuration option is set to `false` to
|
|
945
|
+
* conserve memory if these entries are not required.
|
|
933
946
|
*/
|
|
934
947
|
processedEventEntries: PerformanceEventTiming[];
|
|
935
948
|
/**
|
|
@@ -1129,14 +1142,12 @@ interface TTFBAttribution {
|
|
|
1129
1142
|
|
|
1130
1143
|
The `web-vitals` code is tested in Chrome, Firefox, and Safari. In addition, all JavaScript features used in the code are part of ([Baseline Widely Available](https://web.dev/baseline)), and thus should run without error in all versions of these browsers released within the last 30 months.
|
|
1131
1144
|
|
|
1132
|
-
However, some of the APIs required to capture these metrics are currently only available in
|
|
1133
|
-
|
|
1134
|
-
Browser support for each function is as follows:
|
|
1145
|
+
However, some of the APIs required to capture these metrics (notable CLS) are currently only available in some browsers. The latest browser support for each function is as follows:
|
|
1135
1146
|
|
|
1136
1147
|
- `onCLS()`: Chromium
|
|
1137
1148
|
- `onFCP()`: Chromium, Firefox, Safari
|
|
1138
|
-
- `onINP()`: Chromium
|
|
1139
|
-
- `onLCP()`: Chromium, Firefox
|
|
1149
|
+
- `onINP()`: Chromium, Firefox, Safari
|
|
1150
|
+
- `onLCP()`: Chromium, Firefox, Safari
|
|
1140
1151
|
- `onTTFB()`: Chromium, Firefox, Safari
|
|
1141
1152
|
|
|
1142
1153
|
## Limitations
|
|
@@ -1186,7 +1197,7 @@ You'll likely want to combine this with `npm run watch` to ensure any changes yo
|
|
|
1186
1197
|
|
|
1187
1198
|
## Integrations
|
|
1188
1199
|
|
|
1189
|
-
- [**Web Vitals Connector**](https://goo.gle/web-vitals-connector): Data Studio connector to create dashboards from [Web Vitals data captured in
|
|
1200
|
+
- [**Web Vitals Connector**](https://goo.gle/web-vitals-connector): Data Studio connector to create dashboards from [Web Vitals data captured in BigQuery](https://web.dev/articles/vitals-ga4).
|
|
1190
1201
|
- [**Core Web Vitals Custom Tag template**](https://www.simoahava.com/custom-templates/core-web-vitals/): Custom GTM template tag to [add measurement handlers](https://www.simoahava.com/analytics/track-core-web-vitals-in-ga4-with-google-tag-manager/) for all Core Web Vitals metrics.
|
|
1191
1202
|
- [**`web-vitals-reporter`**](https://github.com/treosh/web-vitals-reporter): JavaScript library to batch `callback` functions and send data with a single request.
|
|
1192
1203
|
|
|
@@ -83,11 +83,9 @@ export const onCLS = (onReport, opts = {}) => {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
// Use `Object.assign()` to ensure the original metric object is returned.
|
|
86
|
-
|
|
87
|
-
return metricWithAttribution;
|
|
86
|
+
return Object.assign(metric, { attribution });
|
|
88
87
|
};
|
|
89
88
|
unattributedOnCLS((metric) => {
|
|
90
|
-
|
|
91
|
-
onReport(metricWithAttribution);
|
|
89
|
+
onReport(attributeCLS(metric));
|
|
92
90
|
}, opts);
|
|
93
91
|
};
|
|
@@ -51,7 +51,6 @@ const attributeFCP = (metric) => {
|
|
|
51
51
|
*/
|
|
52
52
|
export const onFCP = (onReport, opts = {}) => {
|
|
53
53
|
unattributedOnFCP((metric) => {
|
|
54
|
-
|
|
55
|
-
onReport(metricWithAttribution);
|
|
54
|
+
onReport(attributeFCP(metric));
|
|
56
55
|
}, opts);
|
|
57
56
|
};
|
|
@@ -14,6 +14,10 @@ import { INPAttributionReportOpts, INPMetricWithAttribution } from '../types.js'
|
|
|
14
14
|
* less than 40 (well below the recommended
|
|
15
15
|
* [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
|
|
16
16
|
*
|
|
17
|
+
* A custom `includeProcessedEventEntries` configuration option can optionally
|
|
18
|
+
* be passed to control whether the `processedEventEntries` array in the
|
|
19
|
+
* attribution object is populated. The default value is `true`.
|
|
20
|
+
*
|
|
17
21
|
* If the `reportAllChanges` configuration option is set to `true`, the
|
|
18
22
|
* `callback` function will be called as soon as the value is initially
|
|
19
23
|
* determined as well as any time the value changes throughout the page
|
|
@@ -26,8 +26,8 @@ import { onINP as unattributedOnINP } from '../onINP.js';
|
|
|
26
26
|
// frame data is needed to determine various bits of INP attribution once all
|
|
27
27
|
// the frame-related data has come in.
|
|
28
28
|
// In most cases this out-of-order data is only off by a frame or two, so
|
|
29
|
-
// keeping the most recent
|
|
30
|
-
const
|
|
29
|
+
// keeping the most recent 10 should be more than sufficient.
|
|
30
|
+
const MAX_PENDING_FRAMES = 10;
|
|
31
31
|
/**
|
|
32
32
|
* Calculates the [INP](https://web.dev/articles/inp) value for the current
|
|
33
33
|
* page and calls the `callback` function once the value is ready, along with
|
|
@@ -43,6 +43,10 @@ const MAX_PREVIOUS_FRAMES = 50;
|
|
|
43
43
|
* less than 40 (well below the recommended
|
|
44
44
|
* [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
|
|
45
45
|
*
|
|
46
|
+
* A custom `includeProcessedEventEntries` configuration option can optionally
|
|
47
|
+
* be passed to control whether the `processedEventEntries` array in the
|
|
48
|
+
* attribution object is populated. The default value is `true`.
|
|
49
|
+
*
|
|
46
50
|
* If the `reportAllChanges` configuration option is set to `true`, the
|
|
47
51
|
* `callback` function will be called as soon as the value is initially
|
|
48
52
|
* determined as well as any time the value changes throughout the page
|
|
@@ -109,6 +113,8 @@ export const onINP = (onReport, opts = {}) => {
|
|
|
109
113
|
const groupEntriesByRenderTime = (entry) => {
|
|
110
114
|
const renderTime = entry.startTime + entry.duration;
|
|
111
115
|
let group;
|
|
116
|
+
// Update `latestProcessingEnd` to correspond to the `processingEnd`
|
|
117
|
+
// value of the most recently dispatched `event` entry.
|
|
112
118
|
latestProcessingEnd = Math.max(latestProcessingEnd, entry.processingEnd);
|
|
113
119
|
// Iterate over all previous render times in reverse order to find a match.
|
|
114
120
|
// Go in reverse since the most likely match will be at the end.
|
|
@@ -121,11 +127,11 @@ export const onINP = (onReport, opts = {}) => {
|
|
|
121
127
|
group.startTime = Math.min(entry.startTime, group.startTime);
|
|
122
128
|
group.processingStart = Math.min(entry.processingStart, group.processingStart);
|
|
123
129
|
group.processingEnd = Math.max(entry.processingEnd, group.processingEnd);
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
// processedEventEntries can be quite large, so only include them if
|
|
131
|
+
// the user explicitly requests them (default is to include).
|
|
132
|
+
if (opts.includeProcessedEventEntries !== false) {
|
|
133
|
+
group.entries.push(entry);
|
|
134
|
+
}
|
|
129
135
|
break;
|
|
130
136
|
}
|
|
131
137
|
}
|
|
@@ -136,12 +142,9 @@ export const onINP = (onReport, opts = {}) => {
|
|
|
136
142
|
processingStart: entry.processingStart,
|
|
137
143
|
processingEnd: entry.processingEnd,
|
|
138
144
|
renderTime,
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
// See https://crbug.com/484342204
|
|
143
|
-
// entries: [entry],
|
|
144
|
-
entries: [],
|
|
145
|
+
// processedEventEntries can be quite large, so only include them if
|
|
146
|
+
// the user explicitly requests them (default is to include).
|
|
147
|
+
entries: opts.includeProcessedEventEntries !== false ? [entry] : [],
|
|
145
148
|
};
|
|
146
149
|
pendingEntriesGroups.push(group);
|
|
147
150
|
}
|
|
@@ -159,35 +162,39 @@ export const onINP = (onReport, opts = {}) => {
|
|
|
159
162
|
}
|
|
160
163
|
};
|
|
161
164
|
const cleanupEntries = () => {
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
const longestInteractionGroups = interactionManager._longestInteractionList.map((i) => {
|
|
165
|
+
// Create a set of entries groups that are part of the longest
|
|
166
|
+
// interactions (for faster lookup below).
|
|
167
|
+
const longestInteractionGroups = new Set(interactionManager._longestInteractionList.map((i) => {
|
|
165
168
|
return entryToEntriesGroupMap.get(i.entries[0]);
|
|
169
|
+
}));
|
|
170
|
+
// Clean up the `pendingEntriesGroups` list so it doesn't grow endlessly.
|
|
171
|
+
// Keep any groups that:
|
|
172
|
+
// 1) Correspond to one of the current longest interactions, OR
|
|
173
|
+
// 2) Are part of one of the most recent set of frames (which is
|
|
174
|
+
// determined by checking if the index in the group is within
|
|
175
|
+
// `MAX_PENDING_FRAMES` of the group's length).
|
|
176
|
+
const minIndexToKeep = pendingEntriesGroups.length - MAX_PENDING_FRAMES;
|
|
177
|
+
pendingEntriesGroups = pendingEntriesGroups.filter((group, i) => {
|
|
178
|
+
// Check index first because it's faster.
|
|
179
|
+
return i >= minIndexToKeep || longestInteractionGroups.has(group);
|
|
166
180
|
});
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return true;
|
|
171
|
-
return longestInteractionGroups.includes(group);
|
|
172
|
-
});
|
|
173
|
-
// Keep all pending LoAF entries that either:
|
|
174
|
-
// 1) intersect with entries in the newly cleaned up `pendingEntriesGroups`
|
|
175
|
-
// 2) occur after the most recently-processed event entry (for up to MAX_PREVIOUS_FRAMES)
|
|
176
|
-
const loafsToKeep = new Set();
|
|
181
|
+
// Create a set of LoAF entries that intersect with entries in the newly
|
|
182
|
+
// cleaned up `pendingEntriesGroups` (for faster lookup below).
|
|
183
|
+
const intersectingLoAFs = new Set();
|
|
177
184
|
for (const group of pendingEntriesGroups) {
|
|
178
185
|
const loafs = getIntersectingLoAFs(group.startTime, group.processingEnd);
|
|
179
186
|
for (const loaf of loafs) {
|
|
180
|
-
|
|
187
|
+
intersectingLoAFs.add(loaf);
|
|
181
188
|
}
|
|
182
189
|
}
|
|
183
|
-
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
190
|
+
// Clean up the `pendingLoAFs` list so it doesn't grow endlessly.
|
|
191
|
+
// Keep all LoAFs that either:
|
|
192
|
+
// 1) Intersect with one of the above pending entries groups, OR
|
|
193
|
+
// 2) Occurred more recently than the most recently process event entry.
|
|
194
|
+
pendingLoAFs = pendingLoAFs.filter((loaf) => {
|
|
195
|
+
return (
|
|
196
|
+
// Compare times first because it's faster.
|
|
197
|
+
loaf.startTime > latestProcessingEnd || intersectingLoAFs.has(loaf));
|
|
191
198
|
});
|
|
192
199
|
cleanupPending = false;
|
|
193
200
|
};
|
|
@@ -358,13 +365,11 @@ export const onINP = (onReport, opts = {}) => {
|
|
|
358
365
|
};
|
|
359
366
|
attributeLoAFDetails(attribution);
|
|
360
367
|
// Use `Object.assign()` to ensure the original metric object is returned.
|
|
361
|
-
|
|
362
|
-
return metricWithAttribution;
|
|
368
|
+
return Object.assign(metric, { attribution });
|
|
363
369
|
};
|
|
364
370
|
// Start observing LoAF entries for attribution.
|
|
365
371
|
observe('long-animation-frame', handleLoAFEntries);
|
|
366
372
|
unattributedOnINP((metric) => {
|
|
367
|
-
|
|
368
|
-
onReport(metricWithAttribution);
|
|
373
|
+
onReport(attributeINP(metric));
|
|
369
374
|
}, opts);
|
|
370
375
|
};
|
|
@@ -43,6 +43,11 @@ export const onLCP = (onReport, opts = {}) => {
|
|
|
43
43
|
const customTarget = opts.generateTarget?.(node) ?? getSelector(node);
|
|
44
44
|
lcpTargetMap.set(entry, customTarget);
|
|
45
45
|
}
|
|
46
|
+
else if (entry.id) {
|
|
47
|
+
// Use the LargestContentfulPaint.id property when the element has been
|
|
48
|
+
// removed from the DOM (and so node is null), but still has an ID.
|
|
49
|
+
lcpTargetMap.set(entry, `#${entry.id}`);
|
|
50
|
+
}
|
|
46
51
|
};
|
|
47
52
|
const attributeLCP = (metric) => {
|
|
48
53
|
// Use a default object if no other attribution has been set.
|
|
@@ -53,15 +58,26 @@ export const onLCP = (onReport, opts = {}) => {
|
|
|
53
58
|
elementRenderDelay: metric.value,
|
|
54
59
|
};
|
|
55
60
|
if (metric.entries.length) {
|
|
61
|
+
// The `metric.entries.length` check ensures there will be an entry.
|
|
62
|
+
const lcpEntry = metric.entries.at(-1);
|
|
63
|
+
const lcpResourceEntry = lcpEntry.url &&
|
|
64
|
+
performance
|
|
65
|
+
.getEntriesByType('resource')
|
|
66
|
+
.find((e) => e.name === lcpEntry.url);
|
|
67
|
+
attribution.target = lcpTargetMap.get(lcpEntry);
|
|
68
|
+
attribution.lcpEntry = lcpEntry;
|
|
69
|
+
// Only attribute the URL and resource entry if they exist.
|
|
70
|
+
if (lcpEntry.url) {
|
|
71
|
+
attribution.url = lcpEntry.url;
|
|
72
|
+
}
|
|
73
|
+
if (lcpResourceEntry) {
|
|
74
|
+
attribution.lcpResourceEntry = lcpResourceEntry;
|
|
75
|
+
}
|
|
76
|
+
// Get subparts from navigation entry. Do this last as occasionally
|
|
77
|
+
// Safari seems to fail to find a navigation entry.
|
|
56
78
|
const navigationEntry = getNavigationEntry();
|
|
57
79
|
if (navigationEntry) {
|
|
58
80
|
const activationStart = navigationEntry.activationStart || 0;
|
|
59
|
-
// The `metric.entries.length` check ensures there will be an entry.
|
|
60
|
-
const lcpEntry = metric.entries.at(-1);
|
|
61
|
-
const lcpResourceEntry = lcpEntry.url &&
|
|
62
|
-
performance
|
|
63
|
-
.getEntriesByType('resource')
|
|
64
|
-
.filter((e) => e.name === lcpEntry.url)[0];
|
|
65
81
|
const ttfb = Math.max(0, navigationEntry.responseStart - activationStart);
|
|
66
82
|
const lcpRequestStart = Math.max(ttfb,
|
|
67
83
|
// Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
|
|
@@ -75,29 +91,19 @@ export const onLCP = (onReport, opts = {}) => {
|
|
|
75
91
|
? lcpResourceEntry.responseEnd - activationStart
|
|
76
92
|
: 0));
|
|
77
93
|
attribution = {
|
|
78
|
-
|
|
94
|
+
...attribution,
|
|
79
95
|
timeToFirstByte: ttfb,
|
|
80
96
|
resourceLoadDelay: lcpRequestStart - ttfb,
|
|
81
97
|
resourceLoadDuration: lcpResponseEnd - lcpRequestStart,
|
|
82
98
|
elementRenderDelay: metric.value - lcpResponseEnd,
|
|
83
99
|
navigationEntry,
|
|
84
|
-
lcpEntry,
|
|
85
100
|
};
|
|
86
|
-
// Only attribute the URL and resource entry if they exist.
|
|
87
|
-
if (lcpEntry.url) {
|
|
88
|
-
attribution.url = lcpEntry.url;
|
|
89
|
-
}
|
|
90
|
-
if (lcpResourceEntry) {
|
|
91
|
-
attribution.lcpResourceEntry = lcpResourceEntry;
|
|
92
|
-
}
|
|
93
101
|
}
|
|
94
102
|
}
|
|
95
103
|
// Use `Object.assign()` to ensure the original metric object is returned.
|
|
96
|
-
|
|
97
|
-
return metricWithAttribution;
|
|
104
|
+
return Object.assign(metric, { attribution });
|
|
98
105
|
};
|
|
99
106
|
unattributedOnLCP((metric) => {
|
|
100
|
-
|
|
101
|
-
onReport(metricWithAttribution);
|
|
107
|
+
onReport(attributeLCP(metric));
|
|
102
108
|
}, opts);
|
|
103
109
|
};
|
|
@@ -70,7 +70,6 @@ const attributeTTFB = (metric) => {
|
|
|
70
70
|
*/
|
|
71
71
|
export const onTTFB = (onReport, opts = {}) => {
|
|
72
72
|
unattributedOnTTFB((metric) => {
|
|
73
|
-
|
|
74
|
-
onReport(metricWithAttribution);
|
|
73
|
+
onReport(attributeTTFB(metric));
|
|
75
74
|
}, opts);
|
|
76
75
|
};
|
|
@@ -20,24 +20,22 @@ export const getLoadState = (timestamp) => {
|
|
|
20
20
|
// since the timestamp has to be the current time or earlier.
|
|
21
21
|
return 'loading';
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (navigationEntry) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return 'dom-content-loaded';
|
|
40
|
-
}
|
|
23
|
+
const navigationEntry = getNavigationEntry();
|
|
24
|
+
if (navigationEntry) {
|
|
25
|
+
if (timestamp < navigationEntry.domInteractive) {
|
|
26
|
+
return 'loading';
|
|
27
|
+
}
|
|
28
|
+
if (navigationEntry.domContentLoadedEventStart === 0 ||
|
|
29
|
+
timestamp < navigationEntry.domContentLoadedEventStart) {
|
|
30
|
+
// If the `domContentLoadedEventStart` timestamp has not yet been
|
|
31
|
+
// set, or if the given timestamp is less than that value.
|
|
32
|
+
return 'dom-interactive';
|
|
33
|
+
}
|
|
34
|
+
if (navigationEntry.domComplete === 0 ||
|
|
35
|
+
timestamp < navigationEntry.domComplete) {
|
|
36
|
+
// If the `domComplete` timestamp has not yet been
|
|
37
|
+
// set, or if the given timestamp is less than that value.
|
|
38
|
+
return 'dom-content-loaded';
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
41
|
// If any of the above fail, default to loaded. This could really only
|
|
@@ -61,7 +61,8 @@ export const getVisibilityWatcher = () => {
|
|
|
61
61
|
const firstVisibilityStateHiddenTime = !document.prerendering
|
|
62
62
|
? globalThis.performance
|
|
63
63
|
.getEntriesByType('visibility-state')
|
|
64
|
-
.
|
|
64
|
+
.find((e) => e.name === 'hidden' && e.startTime >= activationStart)
|
|
65
|
+
?.startTime
|
|
65
66
|
: undefined;
|
|
66
67
|
/* eslint-enable indent */
|
|
67
68
|
// Prefer that, but if it's not available and the document is hidden when
|
|
@@ -16,5 +16,5 @@ export declare const initMetric: <MetricName extends MetricType["name"]>(name: M
|
|
|
16
16
|
name: MetricName;
|
|
17
17
|
}>)["entries"];
|
|
18
18
|
id: string;
|
|
19
|
-
navigationType: "reload" | "navigate" | "
|
|
19
|
+
navigationType: "reload" | "navigate" | "back-forward" | "back-forward-cache" | "prerender" | "restore";
|
|
20
20
|
};
|
|
@@ -28,7 +28,7 @@ export const observe = (type, callback, opts = {}) => {
|
|
|
28
28
|
// Delay by a microtask to workaround a bug in Safari where the
|
|
29
29
|
// callback is invoked immediately, rather than in a separate task.
|
|
30
30
|
// See: https://github.com/GoogleChrome/web-vitals/issues/277
|
|
31
|
-
|
|
31
|
+
queueMicrotask(() => {
|
|
32
32
|
callback(list.getEntries());
|
|
33
33
|
});
|
|
34
34
|
});
|
|
@@ -34,7 +34,7 @@ let po;
|
|
|
34
34
|
* or the polyfill estimate in this module.
|
|
35
35
|
*/
|
|
36
36
|
export const getInteractionCount = () => {
|
|
37
|
-
return po ? interactionCountEstimate : performance.interactionCount ?? 0;
|
|
37
|
+
return po ? interactionCountEstimate : (performance.interactionCount ?? 0);
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
40
|
* Feature detects native support or initializes the polyfill if needed.
|
|
@@ -43,8 +43,6 @@ export const initInteractionCountPolyfill = () => {
|
|
|
43
43
|
if ('interactionCount' in performance || po)
|
|
44
44
|
return;
|
|
45
45
|
po = observe('event', updateEstimate, {
|
|
46
|
-
type: 'event',
|
|
47
|
-
buffered: true,
|
|
48
46
|
durationThreshold: 0,
|
|
49
47
|
});
|
|
50
48
|
};
|
|
@@ -20,19 +20,23 @@ import { runOnce } from './runOnce.js';
|
|
|
20
20
|
*/
|
|
21
21
|
export const whenIdleOrHidden = (cb) => {
|
|
22
22
|
const rIC = globalThis.requestIdleCallback || setTimeout;
|
|
23
|
+
const cIC = globalThis.cancelIdleCallback || clearTimeout;
|
|
23
24
|
// If the document is hidden, run the callback immediately, otherwise
|
|
24
25
|
// race an idle callback with the next `visibilitychange` event.
|
|
25
26
|
if (document.visibilityState === 'hidden') {
|
|
26
27
|
cb();
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
const wrappedCb = runOnce(cb);
|
|
31
|
+
let idleHandle = -1;
|
|
32
|
+
const onHidden = () => {
|
|
33
|
+
cIC(idleHandle);
|
|
34
|
+
wrappedCb();
|
|
35
|
+
};
|
|
36
|
+
addEventListener('visibilitychange', onHidden, { once: true, capture: true });
|
|
37
|
+
idleHandle = rIC(() => {
|
|
38
|
+
removeEventListener('visibilitychange', onHidden, { capture: true });
|
|
39
|
+
wrappedCb();
|
|
36
40
|
});
|
|
37
41
|
}
|
|
38
42
|
};
|
|
@@ -79,7 +79,7 @@ export const onCLS = (onReport, opts = {}) => {
|
|
|
79
79
|
layoutShiftManager._sessionValue = 0;
|
|
80
80
|
metric = initMetric('CLS', 0);
|
|
81
81
|
report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);
|
|
82
|
-
doubleRAF(
|
|
82
|
+
doubleRAF(report);
|
|
83
83
|
});
|
|
84
84
|
// Queue a task to report (if nothing else triggers a report first).
|
|
85
85
|
// This allows CLS to be reported as soon as FCP fires when
|
|
@@ -4,6 +4,7 @@ export interface INPReportOpts extends ReportOpts {
|
|
|
4
4
|
}
|
|
5
5
|
export interface INPAttributionReportOpts extends AttributionReportOpts {
|
|
6
6
|
durationThreshold?: number;
|
|
7
|
+
includeProcessedEventEntries?: boolean;
|
|
7
8
|
onEachInteraction?: (interaction: INPMetricWithAttribution) => void;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
@@ -69,6 +70,9 @@ export interface INPAttribution {
|
|
|
69
70
|
/**
|
|
70
71
|
* An array of Event Timing entries that were processed within the same
|
|
71
72
|
* 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
|
|
75
|
+
* conserve memory if these entries are not required.
|
|
72
76
|
*/
|
|
73
77
|
processedEventEntries: PerformanceEventTiming[];
|
|
74
78
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * from './types/base.js';
|
|
2
|
-
export * from './types/polyfills.js';
|
|
3
2
|
export * from './types/cls.js';
|
|
4
3
|
export * from './types/fcp.js';
|
|
5
4
|
export * from './types/inp.js';
|
|
@@ -26,7 +25,7 @@ declare global {
|
|
|
26
25
|
}
|
|
27
26
|
interface PerformanceEventTiming extends PerformanceEntry {
|
|
28
27
|
duration: DOMHighResTimeStamp;
|
|
29
|
-
interactionId: number;
|
|
28
|
+
readonly interactionId: number;
|
|
30
29
|
}
|
|
31
30
|
interface LayoutShiftAttribution {
|
|
32
31
|
node: Node | null;
|