chrome-devtools-frontend 1.0.1512349 → 1.0.1513662
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/docs/cookbook/release_management.md +15 -13
- package/docs/get_the_code.md +114 -35
- package/front_end/core/common/Color.ts +40 -44
- package/front_end/core/common/Console.ts +4 -4
- package/front_end/core/common/ParsedURL.ts +14 -14
- package/front_end/core/common/ResourceType.ts +20 -20
- package/front_end/core/common/SegmentedRange.ts +13 -14
- package/front_end/core/common/Settings.ts +4 -4
- package/front_end/core/common/StringOutputStream.ts +4 -4
- package/front_end/core/host/GdpClient.ts +38 -0
- package/front_end/core/host/InspectorFrontendHost.ts +4 -1
- package/front_end/core/host/InspectorFrontendHostAPI.ts +2 -0
- package/front_end/core/host/ResourceLoader.ts +2 -2
- package/front_end/core/host/UserMetrics.ts +0 -2
- package/front_end/core/protocol_client/InspectorBackend.ts +9 -9
- package/front_end/core/root/Runtime.ts +5 -2
- package/front_end/core/sdk/AccessibilityModel.ts +48 -48
- package/front_end/core/sdk/AnimationModel.ts +78 -79
- package/front_end/core/sdk/CPUProfilerModel.ts +5 -5
- package/front_end/core/sdk/CPUThrottlingManager.ts +17 -17
- package/front_end/core/sdk/CSSMatchedStyles.ts +44 -44
- package/front_end/core/sdk/CSSMedia.ts +22 -22
- package/front_end/core/sdk/CSSModel.ts +4 -4
- package/front_end/core/sdk/CSSProperty.ts +9 -9
- package/front_end/core/sdk/CSSPropertyParser.ts +1 -2
- package/front_end/core/sdk/CSSRule.ts +3 -3
- package/front_end/core/sdk/CSSStyleDeclaration.ts +27 -28
- package/front_end/core/sdk/CSSStyleSheetHeader.ts +13 -13
- package/front_end/core/sdk/CategorizedBreakpoint.ts +4 -4
- package/front_end/core/sdk/ChildTargetManager.ts +6 -6
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +4 -4
- package/front_end/core/sdk/ConsoleModel.ts +24 -24
- package/front_end/core/sdk/Cookie.ts +16 -16
- package/front_end/core/sdk/CookieParser.ts +6 -6
- package/front_end/core/sdk/DOMDebuggerModel.ts +88 -89
- package/front_end/core/sdk/DOMModel.ts +113 -113
- package/front_end/core/sdk/DebuggerModel.ts +102 -103
- package/front_end/core/sdk/EmulationModel.ts +6 -6
- package/front_end/core/sdk/EventBreakpointsModel.ts +5 -5
- package/front_end/core/sdk/HeapProfilerModel.ts +5 -5
- package/front_end/core/sdk/IsolateManager.ts +26 -26
- package/front_end/core/sdk/LayerTreeBase.ts +29 -30
- package/front_end/core/sdk/OverlayModel.ts +6 -6
- package/front_end/core/sdk/Resource.ts +43 -43
- package/front_end/core/sdk/ResourceTreeModel.ts +58 -61
- package/front_end/core/sdk/RuntimeModel.ts +12 -13
- package/front_end/core/sdk/SDKModel.ts +3 -3
- package/front_end/core/sdk/Script.ts +17 -17
- package/front_end/core/sdk/SecurityOriginManager.ts +14 -14
- package/front_end/core/sdk/ServerTiming.ts +2 -2
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +15 -15
- package/front_end/core/sdk/ServiceWorkerManager.ts +19 -24
- package/front_end/core/sdk/SourceMap.ts +10 -10
- package/front_end/core/sdk/StorageKeyManager.ts +12 -12
- package/front_end/core/sdk/Target.ts +33 -34
- package/front_end/core/sdk/TargetManager.ts +20 -20
- package/front_end/entrypoints/formatter_worker/AcornTokenizer.ts +8 -8
- package/front_end/entrypoints/formatter_worker/HTMLFormatter.ts +7 -7
- package/front_end/entrypoints/heap_snapshot_worker/AllocationProfile.ts +7 -7
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +24 -24
- package/front_end/entrypoints/main/GlobalAiButton.ts +3 -3
- package/front_end/entrypoints/main/MainImpl.ts +16 -14
- package/front_end/entrypoints/main/main-meta.ts +1 -2
- package/front_end/generated/InspectorBackendCommands.js +3 -2
- package/front_end/generated/SupportedCSSProperties.js +20 -0
- package/front_end/generated/protocol-mapping.d.ts +4 -0
- package/front_end/generated/protocol-proxy-api.d.ts +5 -0
- package/front_end/generated/protocol.ts +20 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -16
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +127 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +149 -26
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +6 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +9 -10
- package/front_end/models/badges/AiExplorerBadge.ts +21 -0
- package/front_end/models/badges/Badge.ts +3 -5
- package/front_end/models/badges/CodeWhispererBadge.ts +21 -0
- package/front_end/models/badges/DOMDetectiveBadge.ts +4 -3
- package/front_end/models/badges/SpeedsterBadge.ts +6 -4
- package/front_end/models/badges/StarterBadge.ts +4 -3
- package/front_end/models/badges/UserBadges.ts +29 -3
- package/front_end/models/bindings/CSSWorkspaceBinding.ts +6 -6
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +18 -18
- package/front_end/models/bindings/FileUtils.ts +15 -15
- package/front_end/models/bindings/ResourceScriptMapping.ts +14 -14
- package/front_end/models/elements/ElementUpdateRecord.ts +11 -11
- package/front_end/models/emulation/DeviceModeModel.ts +123 -131
- package/front_end/models/emulation/EmulatedDevices.ts +22 -22
- package/front_end/models/extensions/ExtensionPanel.ts +24 -24
- package/front_end/models/extensions/ExtensionServer.ts +4 -4
- package/front_end/models/javascript_metadata/NativeFunctions.js +14 -2
- package/front_end/models/persistence/IsolatedFileSystem.ts +18 -19
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +13 -13
- package/front_end/models/trace/EventsSerializer.ts +5 -5
- package/front_end/models/trace/LanternComputationData.ts +10 -10
- package/front_end/models/trace/ModelImpl.ts +32 -41
- package/front_end/models/trace/Processor.ts +28 -30
- package/front_end/models/trace/extras/FilmStrip.ts +6 -6
- package/front_end/models/trace/extras/StackTraceForEvent.ts +22 -25
- package/front_end/models/trace/extras/ThirdParties.ts +16 -17
- package/front_end/models/trace/extras/TraceFilter.ts +1 -1
- package/front_end/models/trace/handlers/Threads.ts +10 -10
- package/front_end/models/trace/handlers/helpers.ts +9 -9
- package/front_end/models/trace/handlers/types.ts +3 -3
- package/front_end/models/trace/insights/CLSCulprits.ts +12 -14
- package/front_end/models/trace/insights/Cache.ts +8 -4
- package/front_end/models/trace/insights/DOMSize.ts +8 -5
- package/front_end/models/trace/insights/DocumentLatency.ts +2 -2
- package/front_end/models/trace/insights/DuplicatedJavaScript.ts +3 -3
- package/front_end/models/trace/insights/FontDisplay.ts +3 -4
- package/front_end/models/trace/insights/ForcedReflow.ts +3 -3
- package/front_end/models/trace/insights/INPBreakdown.ts +2 -2
- package/front_end/models/trace/insights/ImageDelivery.ts +11 -11
- package/front_end/models/trace/insights/LCPBreakdown.ts +4 -4
- package/front_end/models/trace/insights/LCPDiscovery.ts +4 -4
- package/front_end/models/trace/insights/LegacyJavaScript.ts +2 -2
- package/front_end/models/trace/insights/ModernHTTP.ts +4 -5
- package/front_end/models/trace/insights/NetworkDependencyTree.ts +12 -12
- package/front_end/models/trace/insights/RenderBlocking.ts +9 -10
- package/front_end/models/trace/insights/SlowCSSSelector.ts +2 -2
- package/front_end/models/trace/insights/ThirdParties.ts +4 -5
- package/front_end/models/trace/insights/Viewport.ts +8 -5
- package/front_end/models/trace/insights/types.ts +1 -0
- package/front_end/models/trace/lantern/testing/MetricTestUtils.ts +10 -10
- package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +52 -52
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +8 -8
- package/front_end/panels/animation/AnimationTimeline.ts +5 -5
- package/front_end/panels/animation/AnimationUI.ts +22 -23
- package/front_end/panels/application/ApplicationPanelSidebar.ts +12 -12
- package/front_end/panels/application/DOMStorageModel.ts +23 -23
- package/front_end/panels/application/ExtensionStorageModel.ts +31 -31
- package/front_end/panels/application/IndexedDBModel.ts +1 -0
- package/front_end/panels/application/PreloadingTreeElement.ts +8 -8
- package/front_end/panels/application/ServiceWorkersView.ts +0 -53
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -2
- package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -2
- package/front_end/panels/common/BadgeNotification.ts +24 -4
- package/front_end/panels/common/GdpSignUpDialog.ts +5 -0
- package/front_end/panels/common/badgeNotification.css +26 -9
- package/front_end/panels/console/ConsoleContextSelector.ts +9 -9
- package/front_end/panels/console/ConsolePrompt.ts +8 -5
- package/front_end/panels/console/ConsoleView.ts +13 -13
- package/front_end/panels/console/ConsoleViewport.ts +29 -29
- package/front_end/panels/coverage/CoverageModel.ts +22 -22
- package/front_end/panels/elements/ClassesPaneWidget.ts +1 -1
- package/front_end/panels/elements/ComputedStyleModel.ts +17 -18
- package/front_end/panels/elements/DOMPath.ts +2 -2
- package/front_end/panels/elements/ElementsPanel.ts +13 -13
- package/front_end/panels/elements/ElementsTreeElement.ts +18 -18
- package/front_end/panels/elements/ElementsTreeOutline.ts +41 -48
- package/front_end/panels/elements/ShortcutTreeElement.ts +4 -4
- package/front_end/panels/elements/StylePropertiesSection.ts +4 -4
- package/front_end/panels/elements/StylePropertyTreeElement.ts +49 -50
- package/front_end/panels/elements/StylesSidebarPane.ts +19 -19
- package/front_end/panels/emulation/DeviceModeToolbar.ts +7 -7
- package/front_end/panels/emulation/DeviceModeView.ts +6 -6
- package/front_end/panels/emulation/MediaQueryInspector.ts +18 -18
- package/front_end/panels/event_listeners/EventListenersView.ts +13 -14
- package/front_end/panels/layer_viewer/LayerTreeOutline.ts +3 -3
- package/front_end/panels/layer_viewer/LayerViewHost.ts +13 -13
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +9 -10
- package/front_end/panels/layer_viewer/TransformController.ts +34 -36
- package/front_end/panels/layers/LayerTreeModel.ts +41 -40
- package/front_end/panels/lighthouse/LighthouseReportSelector.ts +13 -13
- package/front_end/panels/lighthouse/LighthouseStartView.ts +7 -7
- package/front_end/panels/media/PlayerMessagesView.ts +5 -5
- package/front_end/panels/media/TickingFlameChart.ts +24 -24
- package/front_end/panels/media/TickingFlameChartHelpers.ts +32 -32
- package/front_end/panels/network/NetworkItemView.ts +4 -4
- package/front_end/panels/network/NetworkLogViewColumns.ts +29 -29
- package/front_end/panels/network/NetworkPanel.ts +8 -5
- package/front_end/panels/network/ResourceWebSocketFrameView.ts +10 -10
- package/front_end/panels/profiler/HeapDetachedElementsView.ts +3 -3
- package/front_end/panels/profiler/HeapProfileView.ts +1 -1
- package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +3 -4
- package/front_end/panels/profiler/ProfileHeader.ts +25 -25
- package/front_end/panels/profiler/ProfileLauncherView.ts +5 -6
- package/front_end/panels/recorder/components/ReplaySection.ts +3 -1
- package/front_end/panels/security/OriginTreeElement.ts +8 -8
- package/front_end/panels/security/SecurityPanel.ts +5 -5
- package/front_end/panels/settings/SettingsScreen.ts +18 -12
- package/front_end/panels/settings/components/SyncSection.ts +20 -6
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +3 -0
- package/front_end/panels/sources/DebuggerPausedMessage.ts +8 -9
- package/front_end/panels/sources/NavigatorView.ts +43 -46
- package/front_end/panels/sources/SourcesPanel.ts +35 -35
- package/front_end/panels/sources/SourcesView.ts +13 -13
- package/front_end/panels/sources/TabbedEditorContainer.ts +19 -22
- package/front_end/panels/sources/UISourceCodeFrame.ts +4 -4
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +34 -36
- package/front_end/panels/timeline/AnimationsTrackAppender.ts +3 -3
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +8 -8
- package/front_end/panels/timeline/CountersGraph.ts +16 -16
- package/front_end/panels/timeline/EntriesFilter.ts +4 -3
- package/front_end/panels/timeline/EventsTimelineTreeView.ts +3 -3
- package/front_end/panels/timeline/GPUTrackAppender.ts +3 -3
- package/front_end/panels/timeline/Initiators.ts +10 -10
- package/front_end/panels/timeline/InteractionsTrackAppender.ts +5 -5
- package/front_end/panels/timeline/LayoutShiftsTrackAppender.ts +7 -7
- package/front_end/panels/timeline/ModificationsManager.ts +8 -15
- package/front_end/panels/timeline/TargetForEvent.ts +2 -2
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -1
- package/front_end/panels/timeline/ThreadAppender.ts +13 -13
- package/front_end/panels/timeline/TimelineDetailsView.ts +6 -14
- package/front_end/panels/timeline/TimelineEventOverview.ts +27 -26
- package/front_end/panels/timeline/TimelineFilters.ts +5 -5
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +54 -53
- package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +34 -34
- package/front_end/panels/timeline/TimelineFlameChartView.ts +18 -31
- package/front_end/panels/timeline/TimelineHistoryManager.ts +17 -18
- package/front_end/panels/timeline/TimelineMiniMap.ts +6 -6
- package/front_end/panels/timeline/TimelinePaintProfilerView.ts +6 -6
- package/front_end/panels/timeline/TimelinePanel.ts +52 -59
- package/front_end/panels/timeline/TimelineSelectorStatsView.ts +7 -5
- package/front_end/panels/timeline/TimelineTreeView.ts +10 -10
- package/front_end/panels/timeline/TimelineUIUtils.ts +43 -43
- package/front_end/panels/timeline/TimingsTrackAppender.ts +12 -12
- package/front_end/panels/timeline/TracingLayerTree.ts +43 -43
- package/front_end/panels/timeline/TrackConfigBanner.ts +6 -6
- package/front_end/panels/timeline/TrackConfiguration.ts +1 -1
- package/front_end/panels/timeline/components/DetailsView.ts +4 -4
- package/front_end/panels/timeline/components/LayoutShiftDetails.ts +12 -21
- package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -1
- package/front_end/panels/timeline/components/NetworkRequestDetails.ts +5 -5
- package/front_end/panels/timeline/components/Sidebar.ts +4 -14
- package/front_end/panels/timeline/components/SidebarInsightsTab.ts +13 -36
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +21 -19
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +1 -1
- package/front_end/panels/timeline/components/insights/Cache.ts +4 -0
- package/front_end/panels/timeline/components/insights/DOMSize.ts +5 -1
- package/front_end/panels/timeline/components/insights/Helpers.ts +19 -0
- package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +1 -1
- package/front_end/panels/timeline/components/insights/Viewport.ts +4 -0
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +1 -1
- package/front_end/panels/timeline/utils/AICallTree.ts +11 -11
- package/front_end/panels/timeline/utils/AIContext.ts +17 -19
- package/front_end/panels/timeline/utils/EntityMapper.ts +6 -5
- package/front_end/panels/timeline/utils/EntryName.ts +2 -2
- package/front_end/panels/timeline/utils/EntryNodes.ts +5 -5
- package/front_end/panels/timeline/utils/EntryStyles.ts +4 -4
- package/front_end/panels/timeline/utils/FreshRecording.ts +3 -3
- package/front_end/panels/timeline/utils/Helpers.ts +0 -18
- package/front_end/panels/timeline/utils/InsightAIContext.ts +6 -6
- package/front_end/panels/timeline/utils/SourceMapsResolver.ts +7 -7
- package/front_end/panels/webauthn/WebauthnPane.ts +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/legacy.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/package.json +1 -1
- package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
- package/front_end/third_party/json5/rebuild.sh +1 -1
- package/front_end/third_party/legacy-javascript/{update.sh → rebuild.sh} +1 -1
- package/front_end/third_party/lit/lib/decorators.d.ts +26 -9
- package/front_end/third_party/lit/lib/decorators.js +5 -5
- package/front_end/third_party/lit/lib/decorators.js.map +1 -1
- package/front_end/third_party/lit/lib/directive.js.map +1 -1
- package/front_end/third_party/lit/lib/directives.js +8 -13
- package/front_end/third_party/lit/lib/directives.js.map +1 -1
- package/front_end/third_party/lit/lib/lit.d.ts +26 -9
- package/front_end/third_party/lit/lib/lit.js +5 -5
- package/front_end/third_party/lit/lib/lit.js.map +1 -1
- package/front_end/third_party/lit/lib/static-html.js +2 -2
- package/front_end/third_party/lit/lib/static-html.js.map +1 -1
- package/front_end/third_party/lit/rebuild.sh +1 -1
- package/front_end/third_party/third-party-web/rebuild.sh +1 -1
- package/front_end/ui/components/dialogs/Dialog.ts +6 -7
- package/front_end/ui/legacy/ActionRegistration.ts +9 -9
- package/front_end/ui/legacy/DockController.ts +18 -18
- package/front_end/ui/legacy/FilterBar.ts +7 -7
- package/front_end/ui/legacy/Fragment.ts +4 -4
- package/front_end/ui/legacy/GlassPane.ts +12 -12
- package/front_end/ui/legacy/InspectorView.ts +5 -15
- package/front_end/ui/legacy/ListControl.ts +27 -27
- package/front_end/ui/legacy/ListWidget.ts +4 -4
- package/front_end/ui/legacy/PopoverHelper.ts +4 -4
- package/front_end/ui/legacy/ShortcutRegistry.ts +17 -17
- package/front_end/ui/legacy/TabbedPane.ts +74 -75
- package/front_end/ui/legacy/TextPrompt.ts +31 -31
- package/front_end/ui/legacy/Toolbar.ts +13 -14
- package/front_end/ui/legacy/ViewManager.ts +30 -31
- package/front_end/ui/legacy/Widget.ts +6 -6
- package/front_end/ui/legacy/XLink.ts +9 -9
- package/front_end/ui/legacy/ZoomManager.ts +9 -9
- package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +27 -27
- package/front_end/ui/legacy/components/color_picker/ContrastInfo.ts +30 -32
- package/front_end/ui/legacy/components/color_picker/Spectrum.ts +15 -15
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +64 -64
- package/front_end/ui/legacy/components/data_grid/ShowMoreDataGridNode.ts +2 -2
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +10 -11
- package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +12 -12
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +3 -3
- package/front_end/ui/legacy/components/perf_ui/TimelineGrid.ts +14 -14
- package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +8 -8
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +5 -5
- package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +4 -4
- package/front_end/ui/legacy/theme_support/ThemeSupport.ts +4 -4
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -2
- package/package.json +1 -1
@@ -14,12 +14,12 @@ import {bytes, micros, millis} from './UnitFormatters.js';
|
|
14
14
|
/**
|
15
15
|
* For a given frame ID and navigation ID, returns the LCP Event and the LCP Request, if the resource was an image.
|
16
16
|
*/
|
17
|
-
function getLCPData(parsedTrace: Trace.
|
17
|
+
function getLCPData(parsedTrace: Trace.TraceModel.ParsedTrace, frameId: string, navigationId: string): {
|
18
18
|
lcpEvent: Trace.Types.Events.LargestContentfulPaintCandidate,
|
19
19
|
metricScore: Trace.Handlers.ModelHandlers.PageLoadMetrics.LCPMetricScore,
|
20
20
|
lcpRequest?: Trace.Types.Events.SyntheticNetworkRequest,
|
21
21
|
}|null {
|
22
|
-
const navMetrics = parsedTrace.PageLoadMetrics.metricScoresByFrameId.get(frameId)?.get(navigationId);
|
22
|
+
const navMetrics = parsedTrace.data.PageLoadMetrics.metricScoresByFrameId.get(frameId)?.get(navigationId);
|
23
23
|
if (!navMetrics) {
|
24
24
|
return null;
|
25
25
|
}
|
@@ -35,16 +35,16 @@ function getLCPData(parsedTrace: Trace.Handlers.Types.ParsedTrace, frameId: stri
|
|
35
35
|
|
36
36
|
return {
|
37
37
|
lcpEvent,
|
38
|
-
lcpRequest: parsedTrace.LargestImagePaint.lcpRequestByNavigationId.get(navigationId),
|
38
|
+
lcpRequest: parsedTrace.data.LargestImagePaint.lcpRequestByNavigationId.get(navigationId),
|
39
39
|
metricScore: metric,
|
40
40
|
};
|
41
41
|
}
|
42
42
|
|
43
43
|
export class PerformanceInsightFormatter {
|
44
44
|
#insight: Trace.Insights.Types.InsightModel;
|
45
|
-
#parsedTrace: Trace.
|
45
|
+
#parsedTrace: Trace.TraceModel.ParsedTrace;
|
46
46
|
|
47
|
-
constructor(parsedTrace: Trace.
|
47
|
+
constructor(parsedTrace: Trace.TraceModel.ParsedTrace, insight: Trace.Insights.Types.InsightModel) {
|
48
48
|
this.#insight = insight;
|
49
49
|
this.#parsedTrace = parsedTrace;
|
50
50
|
}
|
@@ -181,6 +181,87 @@ export class PerformanceInsightFormatter {
|
|
181
181
|
}
|
182
182
|
}
|
183
183
|
|
184
|
+
/**
|
185
|
+
* Create an AI prompt string out of the Cache Insight model to use with Ask AI.
|
186
|
+
* Note: This function accesses the UIStrings within Cache to help build the
|
187
|
+
* AI prompt, but does not (and should not) call i18nString to localize these strings. They
|
188
|
+
* should all be sent in English (at least for now).
|
189
|
+
* @param insight The Cache Insight Model to query.
|
190
|
+
* @returns a string formatted for sending to Ask AI.
|
191
|
+
*/
|
192
|
+
formatCacheInsight(insight: Trace.Insights.Models.Cache.CacheInsightModel): string {
|
193
|
+
if (insight.requests.length === 0) {
|
194
|
+
return Trace.Insights.Models.Cache.UIStrings.noRequestsToCache + '.';
|
195
|
+
}
|
196
|
+
|
197
|
+
let output = 'The following resources were associated with ineffficient cache policies:\n';
|
198
|
+
|
199
|
+
for (const entry of insight.requests) {
|
200
|
+
output += `\n- ${entry.request.args.data.url}`;
|
201
|
+
output += `\n - Cache Time to Live (TTL): ${entry.ttl} seconds`;
|
202
|
+
output += `\n - Wasted bytes: ${bytes(entry.wastedBytes)}`;
|
203
|
+
}
|
204
|
+
|
205
|
+
output += '\n\n' + Trace.Insights.Models.Cache.UIStrings.description;
|
206
|
+
return output;
|
207
|
+
}
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Create an AI prompt string out of the DOM Size model to use with Ask AI.
|
211
|
+
* Note: This function accesses the UIStrings within DomSize to help build the
|
212
|
+
* AI prompt, but does not (and should not) call i18nString to localize these strings. They
|
213
|
+
* should all be sent in English (at least for now).
|
214
|
+
* @param insight The DOM Size Insight Model to query.
|
215
|
+
* @returns a string formatted for sending to Ask AI.
|
216
|
+
*/
|
217
|
+
formatDomSizeInsight(insight: Trace.Insights.Models.DOMSize.DOMSizeInsightModel): string {
|
218
|
+
if (insight.state === 'pass') {
|
219
|
+
return 'No DOM size issues were detected.';
|
220
|
+
}
|
221
|
+
|
222
|
+
let output = Trace.Insights.Models.DOMSize.UIStrings.description + '\n';
|
223
|
+
|
224
|
+
if (insight.maxDOMStats) {
|
225
|
+
output += '\n' + Trace.Insights.Models.DOMSize.UIStrings.statistic + ':\n\n';
|
226
|
+
|
227
|
+
const maxDepthStats = insight.maxDOMStats.args.data.maxDepth;
|
228
|
+
const maxChildrenStats = insight.maxDOMStats.args.data.maxChildren;
|
229
|
+
output += Trace.Insights.Models.DOMSize.UIStrings.totalElements + ': ' +
|
230
|
+
insight.maxDOMStats.args.data.totalElements + '.\n';
|
231
|
+
if (maxDepthStats) {
|
232
|
+
output += Trace.Insights.Models.DOMSize.UIStrings.maxDOMDepth + ': ' + maxDepthStats.depth +
|
233
|
+
` nodes, starting with element '${maxDepthStats.nodeName}'` +
|
234
|
+
' (node id: ' + maxDepthStats.nodeId + ').\n';
|
235
|
+
}
|
236
|
+
if (maxChildrenStats) {
|
237
|
+
output += Trace.Insights.Models.DOMSize.UIStrings.maxChildren + ': ' + maxChildrenStats.numChildren +
|
238
|
+
`, for parent '${maxChildrenStats.nodeName}'` +
|
239
|
+
' (node id: ' + maxChildrenStats.nodeId + ').\n';
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
if (insight.largeLayoutUpdates.length > 0 || insight.largeStyleRecalcs.length > 0) {
|
244
|
+
output += `\nLarge layout updates/style calculations:\n`;
|
245
|
+
}
|
246
|
+
|
247
|
+
if (insight.largeLayoutUpdates.length > 0) {
|
248
|
+
for (const update of insight.largeLayoutUpdates) {
|
249
|
+
output += `\n - Layout update: Duration: ${this.#formatMicro(update.dur)},`;
|
250
|
+
output += ` with ${update.args.beginData.dirtyObjects} of ${
|
251
|
+
update.args.beginData.totalObjects} nodes needing layout.`;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
if (insight.largeStyleRecalcs.length > 0) {
|
256
|
+
for (const recalc of insight.largeStyleRecalcs) {
|
257
|
+
output += `\n - Style recalculation: Duration: ${this.#formatMicro(recalc.dur)}, `;
|
258
|
+
output += `with ${recalc.args.elementCount} elements affected.`;
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
return output;
|
263
|
+
}
|
264
|
+
|
184
265
|
/**
|
185
266
|
* Create an AI prompt string out of the NetworkDependencyTree Insight model to use with Ask AI.
|
186
267
|
* Note: This function accesses the UIStrings within NetworkDependencyTree to help build the
|
@@ -432,6 +513,32 @@ export class PerformanceInsightFormatter {
|
|
432
513
|
return output;
|
433
514
|
}
|
434
515
|
|
516
|
+
/**
|
517
|
+
* Create an AI prompt string out of the Viewport [Mobile] Insight model to use with Ask AI.
|
518
|
+
* Note: This function accesses the UIStrings within Viewport to help build the
|
519
|
+
* AI prompt, but does not (and should not) call i18nString to localize these strings. They
|
520
|
+
* should all be sent in English (at least for now).
|
521
|
+
* @param insight The Network Dependency Tree Insight Model to query.
|
522
|
+
* @returns a string formatted for sending to Ask AI.
|
523
|
+
*/
|
524
|
+
formatViewportInsight(insight: Trace.Insights.Models.Viewport.ViewportInsightModel): string {
|
525
|
+
let output = '';
|
526
|
+
|
527
|
+
output += 'The webpage is ' + (insight.mobileOptimized ? 'already' : 'not') + ' optimized for mobile viewing.\n';
|
528
|
+
|
529
|
+
const hasMetaTag = insight.viewportEvent;
|
530
|
+
if (hasMetaTag) {
|
531
|
+
output += `\nThe viewport meta tag was found: \`${insight.viewportEvent?.args?.data.content}\`.`;
|
532
|
+
} else {
|
533
|
+
output += `\nThe viewport meta tag is missing.`;
|
534
|
+
}
|
535
|
+
|
536
|
+
if (!hasMetaTag) {
|
537
|
+
output += '\n\n' + Trace.Insights.Models.Viewport.UIStrings.description;
|
538
|
+
}
|
539
|
+
return output;
|
540
|
+
}
|
541
|
+
|
435
542
|
/**
|
436
543
|
* Formats and outputs the insight's data.
|
437
544
|
* Pass `{headingLevel: X}` to determine what heading level to use for the
|
@@ -609,7 +716,7 @@ ${checklistBulletPoints.map(point => `- ${point.name}: ${point.passed ? 'PASSED'
|
|
609
716
|
return '';
|
610
717
|
}
|
611
718
|
|
612
|
-
const baseTime = this.#parsedTrace.Meta.traceBounds.min;
|
719
|
+
const baseTime = this.#parsedTrace.data.Meta.traceBounds.min;
|
613
720
|
|
614
721
|
const clusterTimes = {
|
615
722
|
start: worstCluster.ts - baseTime,
|
@@ -682,6 +789,14 @@ Legacy JavaScript by file:
|
|
682
789
|
${filesFormatted}`;
|
683
790
|
}
|
684
791
|
|
792
|
+
if (Trace.Insights.Models.Cache.isCacheInsight(this.#insight)) {
|
793
|
+
return this.formatCacheInsight(this.#insight);
|
794
|
+
}
|
795
|
+
|
796
|
+
if (Trace.Insights.Models.DOMSize.isDomSizeInsight(this.#insight)) {
|
797
|
+
return this.formatDomSizeInsight(this.#insight);
|
798
|
+
}
|
799
|
+
|
685
800
|
if (Trace.Insights.Models.FontDisplay.isFontDisplayInsight(this.#insight)) {
|
686
801
|
return this.formatFontDisplayInsight(this.#insight);
|
687
802
|
}
|
@@ -702,6 +817,10 @@ ${filesFormatted}`;
|
|
702
817
|
return this.formatThirdPartiesInsight(this.#insight);
|
703
818
|
}
|
704
819
|
|
820
|
+
if (Trace.Insights.Models.Viewport.isViewportInsight(this.#insight)) {
|
821
|
+
return this.formatViewportInsight(this.#insight);
|
822
|
+
}
|
823
|
+
|
705
824
|
return '';
|
706
825
|
}
|
707
826
|
|
@@ -724,7 +843,7 @@ ${filesFormatted}`;
|
|
724
843
|
case 'DocumentLatency':
|
725
844
|
return '- https://web.dev/articles/optimize-ttfb';
|
726
845
|
case 'DOMSize':
|
727
|
-
return '';
|
846
|
+
return '- https://developer.chrome.com/docs/lighthouse/performance/dom-size/';
|
728
847
|
case 'DuplicatedJavaScript':
|
729
848
|
return '';
|
730
849
|
case 'FontDisplay':
|
@@ -757,9 +876,9 @@ ${filesFormatted}`;
|
|
757
876
|
case 'ThirdParties':
|
758
877
|
return '- https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/';
|
759
878
|
case 'Viewport':
|
760
|
-
return '';
|
879
|
+
return '- https://developer.chrome.com/blog/300ms-tap-delay-gone-away/';
|
761
880
|
case 'Cache':
|
762
|
-
return '';
|
881
|
+
return '- https://web.dev/uses-long-cache-ttl/';
|
763
882
|
case 'ModernHTTP':
|
764
883
|
return '- https://developer.chrome.com/docs/lighthouse/best-practices/uses-http2';
|
765
884
|
case 'LegacyJavaScript':
|
@@ -781,7 +900,11 @@ ${filesFormatted}`;
|
|
781
900
|
2. Did the server respond in 600ms or less? We want developers to aim for as close to 100ms as possible, but our threshold for this insight is 600ms.
|
782
901
|
3. Was there compression applied to the response to minimize the transfer size?`;
|
783
902
|
case 'DOMSize':
|
784
|
-
return
|
903
|
+
return `This insight evaluates some key metrics about the Document Object Model (DOM) and identifies excess in the DOM tree, for example:
|
904
|
+
- The maximum number of elements within the DOM.
|
905
|
+
- The maximum number of children for any given element.
|
906
|
+
- Excessive depth of the DOM structure.
|
907
|
+
- The largest layout and style recalculation events.`;
|
785
908
|
case 'DuplicatedJavaScript':
|
786
909
|
return `This insight identifies large, duplicated JavaScript modules that are present in your application and create redundant code.
|
787
910
|
This wastes network bandwidth and slows down your page, as the user's browser must download and process the same code multiple times.`;
|
@@ -827,9 +950,9 @@ It is important that all of these checks pass to minimize the delay between the
|
|
827
950
|
case 'ThirdParties':
|
828
951
|
return 'This insight analyzes the performance impact of resources loaded from third-party servers and aggregates the performance cost, in terms of download transfer sizes and total amount of time that third party scripts spent executing on the main thread.';
|
829
952
|
case 'Viewport':
|
830
|
-
return '';
|
953
|
+
return 'The insight identifies web pages that are not specifying the viewport meta tag for mobile devies, which avoids the artificial 300-350ms delay designed to help differentiate between tap and double-click.';
|
831
954
|
case 'Cache':
|
832
|
-
return '';
|
955
|
+
return 'This insight identifies static resources that are not cached effectively by the browser.';
|
833
956
|
case 'ModernHTTP':
|
834
957
|
return `Modern HTTP protocols, such as HTTP/2, are more efficient than older versions like HTTP/1.1 because they allow for multiple requests and responses to be sent over a single network connection, significantly improving page load performance by reducing latency and overhead. This insight identifies requests that can be upgraded to a modern HTTP protocol.
|
835
958
|
|
@@ -854,9 +977,9 @@ export interface NetworkRequestFormatOptions {
|
|
854
977
|
|
855
978
|
export class TraceEventFormatter {
|
856
979
|
static layoutShift(
|
857
|
-
shift: Trace.Types.Events.SyntheticLayoutShift, index: number, parsedTrace: Trace.
|
980
|
+
shift: Trace.Types.Events.SyntheticLayoutShift, index: number, parsedTrace: Trace.TraceModel.ParsedTrace,
|
858
981
|
rootCauses?: Trace.Insights.Models.CLSCulprits.LayoutShiftRootCausesData): string {
|
859
|
-
const baseTime = parsedTrace.Meta.traceBounds.min;
|
982
|
+
const baseTime = parsedTrace.data.Meta.traceBounds.min;
|
860
983
|
|
861
984
|
const potentialRootCauses: string[] = [];
|
862
985
|
if (rootCauses) {
|
@@ -895,7 +1018,7 @@ ${rootCauseText}`;
|
|
895
1018
|
|
896
1019
|
// Stringify network requests for the LLM model.
|
897
1020
|
static networkRequests(
|
898
|
-
requests: readonly Trace.Types.Events.SyntheticNetworkRequest[], parsedTrace: Trace.
|
1021
|
+
requests: readonly Trace.Types.Events.SyntheticNetworkRequest[], parsedTrace: Trace.TraceModel.ParsedTrace,
|
899
1022
|
options?: NetworkRequestFormatOptions): string {
|
900
1023
|
if (requests.length === 0) {
|
901
1024
|
return '';
|
@@ -929,7 +1052,7 @@ ${rootCauseText}`;
|
|
929
1052
|
* talk to jacktfranklin@.
|
930
1053
|
*/
|
931
1054
|
static #networkRequestVerbosely(
|
932
|
-
request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.
|
1055
|
+
request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.TraceModel.ParsedTrace,
|
933
1056
|
customTitle?: string): string {
|
934
1057
|
const {
|
935
1058
|
url,
|
@@ -950,9 +1073,9 @@ ${rootCauseText}`;
|
|
950
1073
|
const navigationForEvent = Trace.Helpers.Trace.getNavigationForTraceEvent(
|
951
1074
|
request,
|
952
1075
|
request.args.data.frame,
|
953
|
-
parsedTrace.Meta.navigationsByFrameId,
|
1076
|
+
parsedTrace.data.Meta.navigationsByFrameId,
|
954
1077
|
);
|
955
|
-
const baseTime = navigationForEvent?.ts ?? parsedTrace.Meta.traceBounds.min;
|
1078
|
+
const baseTime = navigationForEvent?.ts ?? parsedTrace.data.Meta.traceBounds.min;
|
956
1079
|
|
957
1080
|
// Gets all the timings for this request, relative to the base time.
|
958
1081
|
// Note that this is the start time, not total time. E.g. "queuedAt: X"
|
@@ -969,7 +1092,7 @@ ${rootCauseText}`;
|
|
969
1092
|
const downloadTime = syntheticData.finishTime - syntheticData.downloadStart;
|
970
1093
|
|
971
1094
|
const renderBlocking = Trace.Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(request);
|
972
|
-
const initiator = parsedTrace.NetworkRequests.eventToInitiator.get(request);
|
1095
|
+
const initiator = parsedTrace.data.NetworkRequests.eventToInitiator.get(request);
|
973
1096
|
|
974
1097
|
const priorityLines = [];
|
975
1098
|
if (initialPriority === priority) {
|
@@ -1029,7 +1152,7 @@ ${NetworkRequestFormatter.formatHeaders('Response headers', responseHeaders ?? [
|
|
1029
1152
|
// format description.
|
1030
1153
|
static #networkRequestsArrayCompressed(
|
1031
1154
|
requests: readonly Trace.Types.Events.SyntheticNetworkRequest[],
|
1032
|
-
parsedTrace: Trace.
|
1155
|
+
parsedTrace: Trace.TraceModel.ParsedTrace): string {
|
1033
1156
|
const networkDataString = `
|
1034
1157
|
Network requests data:
|
1035
1158
|
|
@@ -1095,8 +1218,8 @@ The order of headers corresponds to an internal fixed list. If a header is not p
|
|
1095
1218
|
* See `networkDataFormatDescription` above for specifics.
|
1096
1219
|
*/
|
1097
1220
|
static #networkRequestCompressedFormat(
|
1098
|
-
urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest,
|
1099
|
-
|
1221
|
+
urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.TraceModel.ParsedTrace,
|
1222
|
+
urlIdToIndex: Map<string, number>): string {
|
1100
1223
|
const {
|
1101
1224
|
statusCode,
|
1102
1225
|
initialPriority,
|
@@ -1111,9 +1234,9 @@ The order of headers corresponds to an internal fixed list. If a header is not p
|
|
1111
1234
|
const navigationForEvent = Trace.Helpers.Trace.getNavigationForTraceEvent(
|
1112
1235
|
request,
|
1113
1236
|
request.args.data.frame,
|
1114
|
-
parsedTrace.Meta.navigationsByFrameId,
|
1237
|
+
parsedTrace.data.Meta.navigationsByFrameId,
|
1115
1238
|
);
|
1116
|
-
const baseTime = navigationForEvent?.ts ?? parsedTrace.Meta.traceBounds.min;
|
1239
|
+
const baseTime = navigationForEvent?.ts ?? parsedTrace.data.Meta.traceBounds.min;
|
1117
1240
|
const queuedTime = micros(request.ts - baseTime);
|
1118
1241
|
const requestSentTime = micros(syntheticData.sendStartTime - baseTime);
|
1119
1242
|
const downloadCompleteTime = micros(syntheticData.finishTime - baseTime);
|
@@ -1168,13 +1291,13 @@ The order of headers corresponds to an internal fixed list. If a header is not p
|
|
1168
1291
|
}
|
1169
1292
|
|
1170
1293
|
static #getInitiatorChain(
|
1171
|
-
parsedTrace: Trace.
|
1294
|
+
parsedTrace: Trace.TraceModel.ParsedTrace,
|
1172
1295
|
request: Trace.Types.Events.SyntheticNetworkRequest): Trace.Types.Events.SyntheticNetworkRequest[] {
|
1173
1296
|
const initiators: Trace.Types.Events.SyntheticNetworkRequest[] = [];
|
1174
1297
|
|
1175
1298
|
let cur: Trace.Types.Events.SyntheticNetworkRequest|undefined = request;
|
1176
1299
|
while (cur) {
|
1177
|
-
const initiator = parsedTrace.NetworkRequests.eventToInitiator.get(cur);
|
1300
|
+
const initiator = parsedTrace.data.NetworkRequests.eventToInitiator.get(cur);
|
1178
1301
|
if (initiator) {
|
1179
1302
|
// Should never happen, but if it did that would be an infinite loop.
|
1180
1303
|
if (initiators.includes(initiator)) {
|
package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt
CHANGED
@@ -900,6 +900,12 @@ Available insights:
|
|
900
900
|
description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page's content.
|
901
901
|
relevant trace bounds: {min: 157423742399, max: 157427277086}
|
902
902
|
example question: Which third parties are having the largest impact on my page performance?
|
903
|
+
- insight name: Cache
|
904
|
+
description: A long cache lifetime can speed up repeat visits to your page. [Learn more](https://web.dev/uses-long-cache-ttl/).
|
905
|
+
relevant trace bounds: {min: 157423742399, max: 157426980482}
|
906
|
+
estimated metric savings: FCP 0 ms, LCP 0 ms
|
907
|
+
estimated wasted bytes: 847.4 kB
|
908
|
+
example question: What caching strategies can I apply to improve my page performance?
|
903
909
|
- insight name: LegacyJavaScript
|
904
910
|
description: Polyfills and transforms enable older browsers to use new JavaScript features. However, many aren't necessary for modern browsers. Consider modifying your JavaScript build process to not transpile [Baseline](https://web.dev/articles/baseline-and-polyfills) features, unless you know you must support older browsers. [Learn why most sites can deploy ES6+ code without transpiling](https://philipwalton.com/articles/the-state-of-es5-on-the-web/)
|
905
911
|
relevant trace bounds: {min: 157423489126, max: 157426132225}
|
@@ -9,9 +9,8 @@ import {PerformanceInsightFormatter, TraceEventFormatter} from './PerformanceIns
|
|
9
9
|
import {bytes, micros, millis} from './UnitFormatters.js';
|
10
10
|
|
11
11
|
export class PerformanceTraceFormatter {
|
12
|
-
#parsedTrace: Trace.
|
12
|
+
#parsedTrace: Trace.TraceModel.ParsedTrace;
|
13
13
|
#insightSet: Trace.Insights.Types.InsightSet|null;
|
14
|
-
#traceMetadata: Trace.Types.File.MetaData;
|
15
14
|
#eventsSerializer: Trace.EventsSerializer.EventsSerializer;
|
16
15
|
|
17
16
|
constructor(focus: TimelineUtils.AIContext.AgentFocus, eventsSerializer: Trace.EventsSerializer.EventsSerializer) {
|
@@ -21,7 +20,6 @@ export class PerformanceTraceFormatter {
|
|
21
20
|
|
22
21
|
this.#parsedTrace = focus.data.parsedTrace;
|
23
22
|
this.#insightSet = focus.data.insightSet;
|
24
|
-
this.#traceMetadata = focus.data.traceMetadata;
|
25
23
|
this.#eventsSerializer = eventsSerializer;
|
26
24
|
}
|
27
25
|
|
@@ -37,7 +35,8 @@ export class PerformanceTraceFormatter {
|
|
37
35
|
formatTraceSummary(): string {
|
38
36
|
const parsedTrace = this.#parsedTrace;
|
39
37
|
const insightSet = this.#insightSet;
|
40
|
-
const traceMetadata = this.#
|
38
|
+
const traceMetadata = this.#parsedTrace.metadata;
|
39
|
+
const data = parsedTrace.data;
|
41
40
|
|
42
41
|
const parts = [];
|
43
42
|
|
@@ -45,8 +44,8 @@ export class PerformanceTraceFormatter {
|
|
45
44
|
const cls = insightSet ? Trace.Insights.Common.getCLS(insightSet) : null;
|
46
45
|
const inp = insightSet ? Trace.Insights.Common.getINP(insightSet) : null;
|
47
46
|
|
48
|
-
parts.push(`URL: ${
|
49
|
-
parts.push(`Bounds: ${this.serializeBounds(
|
47
|
+
parts.push(`URL: ${data.Meta.mainFrameURL}`);
|
48
|
+
parts.push(`Bounds: ${this.serializeBounds(data.Meta.traceBounds)}`);
|
50
49
|
parts.push('CPU throttling: ' + (traceMetadata.cpuThrottling ? `${traceMetadata.cpuThrottling}x` : 'none'));
|
51
50
|
parts.push(`Network throttling: ${traceMetadata.networkThrottling ?? 'none'}`);
|
52
51
|
if (lcp || cls || inp) {
|
@@ -178,7 +177,7 @@ export class PerformanceTraceFormatter {
|
|
178
177
|
const parsedTrace = this.#parsedTrace;
|
179
178
|
const insightSet = this.#insightSet;
|
180
179
|
|
181
|
-
const bounds = parsedTrace.Meta.traceBounds;
|
180
|
+
const bounds = parsedTrace.data.Meta.traceBounds;
|
182
181
|
const rootNode = TimelineUtils.InsightAIContext.AIQueries.mainThreadActivityBottomUp(
|
183
182
|
insightSet?.navigation?.args.data?.navigationId,
|
184
183
|
bounds,
|
@@ -231,7 +230,7 @@ export class PerformanceTraceFormatter {
|
|
231
230
|
const parsedTrace = this.#parsedTrace;
|
232
231
|
const insightSet = this.#insightSet;
|
233
232
|
|
234
|
-
const bounds = parsedTrace.Meta.traceBounds;
|
233
|
+
const bounds = parsedTrace.data.Meta.traceBounds;
|
235
234
|
const longestTaskTrees = TimelineUtils.InsightAIContext.AIQueries.longestTasks(
|
236
235
|
insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
|
237
236
|
if (!longestTaskTrees || longestTaskTrees.length === 0) {
|
@@ -312,7 +311,7 @@ export class PerformanceTraceFormatter {
|
|
312
311
|
results.push(this.#serializeBottomUpRootNode(bottomUpRootNode, 20));
|
313
312
|
}
|
314
313
|
|
315
|
-
const thirdPartySummaries = Trace.Extras.ThirdParties.summarizeByThirdParty(this.#parsedTrace, bounds);
|
314
|
+
const thirdPartySummaries = Trace.Extras.ThirdParties.summarizeByThirdParty(this.#parsedTrace.data, bounds);
|
316
315
|
if (thirdPartySummaries.length) {
|
317
316
|
results.push('# Third parties');
|
318
317
|
results.push(this.#formatThirdPartyEntitySummaries(thirdPartySummaries));
|
@@ -337,7 +336,7 @@ export class PerformanceTraceFormatter {
|
|
337
336
|
formatNetworkTrackSummary(bounds: Trace.Types.Timing.TraceWindowMicro): string {
|
338
337
|
const results = [];
|
339
338
|
|
340
|
-
const requests = this.#parsedTrace.NetworkRequests.byTime.filter(
|
339
|
+
const requests = this.#parsedTrace.data.NetworkRequests.byTime.filter(
|
341
340
|
request => Trace.Helpers.Timing.eventIsInBounds(request, bounds));
|
342
341
|
const requestsText = TraceEventFormatter.networkRequests(requests, this.#parsedTrace, {verbose: false});
|
343
342
|
results.push('# Network requests summary');
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Copyright 2025 The Chromium Authors
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
|
5
|
+
import {Badge, type BadgeAction} from './Badge.js';
|
6
|
+
|
7
|
+
const AI_EXPLORER_BADGE_URI = new URL('../../Images/ai-explorer-badge.svg', import.meta.url).toString();
|
8
|
+
export class AiExplorerBadge extends Badge {
|
9
|
+
override readonly name =
|
10
|
+
'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fai-explorer';
|
11
|
+
override readonly title = 'AI Explorer';
|
12
|
+
override readonly imageUri = AI_EXPLORER_BADGE_URI;
|
13
|
+
|
14
|
+
override readonly interestedActions = [
|
15
|
+
// TODO(ergunsh): Instrument related actions.
|
16
|
+
] as const;
|
17
|
+
|
18
|
+
handleAction(_action: BadgeAction): void {
|
19
|
+
this.trigger();
|
20
|
+
}
|
21
|
+
}
|
@@ -5,9 +5,11 @@
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
6
6
|
|
7
7
|
export enum BadgeAction {
|
8
|
+
GDP_SIGN_UP_COMPLETE = 'gdp-sign-up-complete',
|
8
9
|
CSS_RULE_MODIFIED = 'css-rule-modified',
|
9
10
|
DOM_ELEMENT_OR_ATTRIBUTE_EDITED = 'dom-element-or-attribute-edited',
|
10
11
|
MODERN_DOM_BADGE_CLICKED = 'modern-dom-badge-clicked',
|
12
|
+
// TODO(ergunsh): Instrument performance insight clicks.
|
11
13
|
PERFORMANCE_INSIGHT_CLICKED = 'performance-insight-clicked',
|
12
14
|
}
|
13
15
|
|
@@ -47,11 +49,6 @@ export abstract class Badge {
|
|
47
49
|
}
|
48
50
|
|
49
51
|
activate(): void {
|
50
|
-
// We don't reactivate a badge that's triggered before.
|
51
|
-
if (this.#triggeredBefore) {
|
52
|
-
return;
|
53
|
-
}
|
54
|
-
|
55
52
|
// The event listeners are already registered, we don't re-register them.
|
56
53
|
if (this.#eventListeners.length > 0) {
|
57
54
|
return;
|
@@ -70,5 +67,6 @@ export abstract class Badge {
|
|
70
67
|
|
71
68
|
Common.EventTarget.removeEventListeners(this.#eventListeners);
|
72
69
|
this.#eventListeners = [];
|
70
|
+
this.#triggeredBefore = false;
|
73
71
|
}
|
74
72
|
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Copyright 2025 The Chromium Authors
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
|
5
|
+
import {Badge, type BadgeAction} from './Badge.js';
|
6
|
+
|
7
|
+
const CODE_WHISPERER_BADGE_IMAGE_URI = new URL('../../Images/code-whisperer-badge.svg', import.meta.url).toString();
|
8
|
+
export class CodeWhispererBadge extends Badge {
|
9
|
+
override readonly name =
|
10
|
+
'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fcode-whisperer';
|
11
|
+
override readonly title = 'Code Whisperer';
|
12
|
+
override readonly imageUri = CODE_WHISPERER_BADGE_IMAGE_URI;
|
13
|
+
|
14
|
+
override readonly interestedActions = [
|
15
|
+
// TODO(ergunsh): Instrument related actions.
|
16
|
+
] as const;
|
17
|
+
|
18
|
+
handleAction(_action: BadgeAction): void {
|
19
|
+
this.trigger();
|
20
|
+
}
|
21
|
+
}
|
@@ -4,14 +4,15 @@
|
|
4
4
|
|
5
5
|
import {Badge, BadgeAction} from './Badge.js';
|
6
6
|
|
7
|
-
const DOM_DETECTIVE_BADGE_IMAGE_URI = new URL('../../Images/
|
7
|
+
const DOM_DETECTIVE_BADGE_IMAGE_URI = new URL('../../Images/dom-detective-badge.svg', import.meta.url).toString();
|
8
8
|
export class DOMDetectiveBadge extends Badge {
|
9
|
-
override readonly name =
|
9
|
+
override readonly name =
|
10
|
+
'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fdom-detective';
|
10
11
|
override readonly title = 'DOM Detective';
|
11
12
|
override readonly imageUri = DOM_DETECTIVE_BADGE_IMAGE_URI;
|
12
13
|
|
13
14
|
override readonly interestedActions = [
|
14
|
-
BadgeAction.
|
15
|
+
BadgeAction.MODERN_DOM_BADGE_CLICKED,
|
15
16
|
] as const;
|
16
17
|
|
17
18
|
handleAction(_action: BadgeAction): void {
|
@@ -4,12 +4,14 @@
|
|
4
4
|
|
5
5
|
import {Badge, BadgeAction} from './Badge.js';
|
6
6
|
|
7
|
-
const SPEEDSTER_BADGE_URI = new URL('../../Images/
|
7
|
+
const SPEEDSTER_BADGE_URI = new URL('../../Images/speedster-badge.svg', import.meta.url).toString();
|
8
8
|
export class SpeedsterBadge extends Badge {
|
9
|
-
|
10
|
-
|
9
|
+
override readonly name =
|
10
|
+
'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fspeedster';
|
11
11
|
override readonly title = 'Speedster';
|
12
|
-
override readonly interestedActions = [
|
12
|
+
override readonly interestedActions = [
|
13
|
+
BadgeAction.PERFORMANCE_INSIGHT_CLICKED,
|
14
|
+
] as const;
|
13
15
|
override readonly imageUri = SPEEDSTER_BADGE_URI;
|
14
16
|
|
15
17
|
handleAction(_action: BadgeAction): void {
|
@@ -4,16 +4,17 @@
|
|
4
4
|
|
5
5
|
import {Badge, BadgeAction} from './Badge.js';
|
6
6
|
|
7
|
-
const STARTER_BADGE_IMAGE_URI = new URL('../../Images/
|
7
|
+
const STARTER_BADGE_IMAGE_URI = new URL('../../Images/devtools-user-badge.svg', import.meta.url).toString();
|
8
8
|
export class StarterBadge extends Badge {
|
9
9
|
override readonly isStarterBadge = true;
|
10
|
-
|
11
|
-
|
10
|
+
override readonly name =
|
11
|
+
'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fchrome-devtools-user';
|
12
12
|
override readonly title = 'Chrome DevTools User';
|
13
13
|
override readonly imageUri = STARTER_BADGE_IMAGE_URI;
|
14
14
|
|
15
15
|
// TODO(ergunsh): Add remaining non-trivial event definitions
|
16
16
|
override readonly interestedActions = [
|
17
|
+
BadgeAction.GDP_SIGN_UP_COMPLETE,
|
17
18
|
BadgeAction.CSS_RULE_MODIFIED,
|
18
19
|
BadgeAction.DOM_ELEMENT_OR_ATTRIBUTE_EDITED,
|
19
20
|
] as const;
|
@@ -5,7 +5,9 @@
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
6
6
|
import * as Host from '../../core/host/host.js';
|
7
7
|
|
8
|
+
import {AiExplorerBadge} from './AiExplorerBadge.js';
|
8
9
|
import type {Badge, BadgeAction, BadgeActionEvents, BadgeContext} from './Badge.js';
|
10
|
+
import {CodeWhispererBadge} from './CodeWhispererBadge.js';
|
9
11
|
import {DOMDetectiveBadge} from './DOMDetectiveBadge.js';
|
10
12
|
import {SpeedsterBadge} from './SpeedsterBadge.js';
|
11
13
|
import {StarterBadge} from './StarterBadge.js';
|
@@ -31,6 +33,8 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
31
33
|
StarterBadge,
|
32
34
|
SpeedsterBadge,
|
33
35
|
DOMDetectiveBadge,
|
36
|
+
CodeWhispererBadge,
|
37
|
+
AiExplorerBadge,
|
34
38
|
];
|
35
39
|
|
36
40
|
private constructor() {
|
@@ -98,7 +102,6 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
98
102
|
}
|
99
103
|
|
100
104
|
// TODO(ergunsh): Implement starter badge dismissal, snooze count & timestamp checks.
|
101
|
-
// TODO(ergunsh): Implement checking for previously awarded badges.
|
102
105
|
async #reconcileBadges(): Promise<void> {
|
103
106
|
const syncInfo = await new Promise<Host.InspectorFrontendHostAPI.SyncInformation>(
|
104
107
|
resolve => Host.InspectorFrontendHost.InspectorFrontendHostInstance.getSyncInformation(resolve));
|
@@ -120,8 +123,31 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
120
123
|
return;
|
121
124
|
}
|
122
125
|
|
123
|
-
|
126
|
+
let awardedBadgeNames: Set<string>|null = null;
|
127
|
+
if (gdpProfile) {
|
128
|
+
awardedBadgeNames = await Host.GdpClient.GdpClient.instance().getAwardedBadgeNames(
|
129
|
+
{names: this.#allBadges.map(badge => badge.name)});
|
130
|
+
// This is a conservative approach. We bail out if `awardedBadgeNames` is null
|
131
|
+
// when there is a profile to prevent a negative user experience.
|
132
|
+
//
|
133
|
+
// A failure here (e.g., from a typo in a badge name) could cause us to
|
134
|
+
// re-trigger the "Receive badges" nudge for a user who has already earned the
|
135
|
+
// starter badge and opted out of receiving badges.
|
136
|
+
//
|
137
|
+
// The trade-off is, we silently failing to enable badge mechanism rather than annoying the user.
|
138
|
+
if (!awardedBadgeNames) {
|
139
|
+
this.#deactivateAllBadges();
|
140
|
+
return;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
const receiveBadgesSettingEnabled = Boolean(this.#receiveBadgesSetting.get());
|
124
145
|
for (const badge of this.#allBadges) {
|
146
|
+
if (awardedBadgeNames?.has(badge.name)) {
|
147
|
+
badge.deactivate();
|
148
|
+
continue;
|
149
|
+
}
|
150
|
+
|
125
151
|
const shouldActivateStarterBadge = badge.isStarterBadge && isEligibleToCreateProfile;
|
126
152
|
const shouldActivateActivityBasedBadge =
|
127
153
|
!badge.isStarterBadge && Boolean(gdpProfile) && receiveBadgesSettingEnabled;
|
@@ -139,6 +165,6 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
139
165
|
}
|
140
166
|
|
141
167
|
isReceiveBadgesSettingEnabled(): boolean {
|
142
|
-
return Boolean(this.#receiveBadgesSetting
|
168
|
+
return Boolean(this.#receiveBadgesSetting.get());
|
143
169
|
}
|
144
170
|
}
|
@@ -283,7 +283,7 @@ export class LiveLocation extends LiveLocationWithPool {
|
|
283
283
|
readonly #lineNumber: number;
|
284
284
|
readonly #columnNumber: number;
|
285
285
|
readonly #info: ModelInfo;
|
286
|
-
|
286
|
+
#header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null;
|
287
287
|
constructor(
|
288
288
|
rawLocation: SDK.CSSModel.CSSLocation, info: ModelInfo,
|
289
289
|
updateDelegate: (arg0: LiveLocationInterface) => Promise<void>, locationPool: LiveLocationPool) {
|
@@ -292,22 +292,22 @@ export class LiveLocation extends LiveLocationWithPool {
|
|
292
292
|
this.#lineNumber = rawLocation.lineNumber;
|
293
293
|
this.#columnNumber = rawLocation.columnNumber;
|
294
294
|
this.#info = info;
|
295
|
-
this
|
295
|
+
this.#header = null;
|
296
296
|
}
|
297
297
|
|
298
298
|
header(): SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null {
|
299
|
-
return this
|
299
|
+
return this.#header;
|
300
300
|
}
|
301
301
|
|
302
302
|
setHeader(header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null): void {
|
303
|
-
this
|
303
|
+
this.#header = header;
|
304
304
|
}
|
305
305
|
|
306
306
|
override async uiLocation(): Promise<Workspace.UISourceCode.UILocation|null> {
|
307
|
-
if (!this
|
307
|
+
if (!this.#header) {
|
308
308
|
return null;
|
309
309
|
}
|
310
|
-
const rawLocation = new SDK.CSSModel.CSSLocation(this
|
310
|
+
const rawLocation = new SDK.CSSModel.CSSLocation(this.#header, this.#lineNumber, this.#columnNumber);
|
311
311
|
return CSSWorkspaceBinding.instance().rawLocationToUILocation(rawLocation);
|
312
312
|
}
|
313
313
|
|