chrome-devtools-frontend 1.0.1380117 → 1.0.1386602
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/.stylelintrc.json +2 -1
- package/config/gni/devtools_grd_files.gni +25 -4
- package/config/gni/devtools_image_files.gni +2 -0
- package/docs/README.md +4 -0
- package/docs/contributing/issues.md +13 -10
- package/docs/get_the_code.md +4 -1
- package/docs/policy/README.md +6 -0
- package/docs/policy/slow-close.md +52 -0
- package/docs/styleguide/ux/README.md +1 -0
- package/docs/styleguide/ux/numbers.md +106 -0
- package/front_end/Images/src/cookie_off.svg +3 -0
- package/front_end/Images/src/domain.svg +3 -0
- package/front_end/core/common/Color.ts +3 -3
- package/front_end/core/common/SettingRegistration.ts +7 -0
- package/front_end/core/host/AidaClient.ts +3 -3
- package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -1
- package/front_end/core/host/UserMetrics.ts +0 -8
- package/front_end/core/i18n/locales/af.json +1031 -887
- package/front_end/core/i18n/locales/am.json +1036 -892
- package/front_end/core/i18n/locales/ar.json +1039 -895
- package/front_end/core/i18n/locales/as.json +1032 -888
- package/front_end/core/i18n/locales/az.json +1034 -890
- package/front_end/core/i18n/locales/be.json +1031 -887
- package/front_end/core/i18n/locales/bg.json +1031 -887
- package/front_end/core/i18n/locales/bn.json +1033 -889
- package/front_end/core/i18n/locales/bs.json +1036 -892
- package/front_end/core/i18n/locales/ca.json +1031 -887
- package/front_end/core/i18n/locales/cs.json +1030 -886
- package/front_end/core/i18n/locales/cy.json +1032 -888
- package/front_end/core/i18n/locales/da.json +1031 -887
- package/front_end/core/i18n/locales/de.json +1033 -889
- package/front_end/core/i18n/locales/el.json +1031 -887
- package/front_end/core/i18n/locales/en-GB.json +1033 -889
- package/front_end/core/i18n/locales/es-419.json +1029 -885
- package/front_end/core/i18n/locales/es.json +1032 -888
- package/front_end/core/i18n/locales/et.json +1033 -889
- package/front_end/core/i18n/locales/eu.json +1031 -887
- package/front_end/core/i18n/locales/fa.json +1035 -891
- package/front_end/core/i18n/locales/fi.json +1035 -891
- package/front_end/core/i18n/locales/fil.json +1034 -890
- package/front_end/core/i18n/locales/fr-CA.json +1031 -887
- package/front_end/core/i18n/locales/fr.json +1049 -905
- package/front_end/core/i18n/locales/gl.json +1032 -888
- package/front_end/core/i18n/locales/gu.json +1035 -891
- package/front_end/core/i18n/locales/he.json +1031 -887
- package/front_end/core/i18n/locales/hi.json +1034 -890
- package/front_end/core/i18n/locales/hr.json +1031 -887
- package/front_end/core/i18n/locales/hu.json +1033 -889
- package/front_end/core/i18n/locales/hy.json +1046 -902
- package/front_end/core/i18n/locales/id.json +1023 -879
- package/front_end/core/i18n/locales/is.json +1032 -888
- package/front_end/core/i18n/locales/it.json +1031 -887
- package/front_end/core/i18n/locales/ja.json +1042 -898
- package/front_end/core/i18n/locales/ka.json +1034 -890
- package/front_end/core/i18n/locales/kk.json +1035 -891
- package/front_end/core/i18n/locales/km.json +1035 -891
- package/front_end/core/i18n/locales/kn.json +1036 -892
- package/front_end/core/i18n/locales/ko.json +1031 -887
- package/front_end/core/i18n/locales/ky.json +1032 -888
- package/front_end/core/i18n/locales/lo.json +1030 -886
- package/front_end/core/i18n/locales/lt.json +1032 -888
- package/front_end/core/i18n/locales/lv.json +1032 -888
- package/front_end/core/i18n/locales/mk.json +1032 -888
- package/front_end/core/i18n/locales/ml.json +1033 -889
- package/front_end/core/i18n/locales/mn.json +1034 -890
- package/front_end/core/i18n/locales/mr.json +1035 -891
- package/front_end/core/i18n/locales/ms.json +1033 -889
- package/front_end/core/i18n/locales/my.json +1033 -889
- package/front_end/core/i18n/locales/ne.json +1036 -892
- package/front_end/core/i18n/locales/nl.json +1033 -889
- package/front_end/core/i18n/locales/no.json +1036 -892
- package/front_end/core/i18n/locales/or.json +1043 -899
- package/front_end/core/i18n/locales/pa.json +1030 -886
- package/front_end/core/i18n/locales/pl.json +1032 -888
- package/front_end/core/i18n/locales/pt-PT.json +1033 -889
- package/front_end/core/i18n/locales/pt.json +1033 -889
- package/front_end/core/i18n/locales/ro.json +1029 -885
- package/front_end/core/i18n/locales/ru.json +1026 -882
- package/front_end/core/i18n/locales/si.json +1031 -887
- package/front_end/core/i18n/locales/sk.json +1033 -889
- package/front_end/core/i18n/locales/sl.json +1031 -887
- package/front_end/core/i18n/locales/sq.json +1061 -917
- package/front_end/core/i18n/locales/sr-Latn.json +1033 -889
- package/front_end/core/i18n/locales/sr.json +1033 -889
- package/front_end/core/i18n/locales/sv.json +1031 -887
- package/front_end/core/i18n/locales/sw.json +1033 -889
- package/front_end/core/i18n/locales/ta.json +1058 -914
- package/front_end/core/i18n/locales/te.json +1037 -893
- package/front_end/core/i18n/locales/th.json +1032 -888
- package/front_end/core/i18n/locales/tr.json +1031 -887
- package/front_end/core/i18n/locales/uk.json +1030 -886
- package/front_end/core/i18n/locales/ur.json +1031 -887
- package/front_end/core/i18n/locales/uz.json +1023 -879
- package/front_end/core/i18n/locales/vi.json +1032 -888
- package/front_end/core/i18n/locales/zh-HK.json +1032 -888
- package/front_end/core/i18n/locales/zh-TW.json +1032 -888
- package/front_end/core/i18n/locales/zh.json +1033 -889
- package/front_end/core/i18n/locales/zu.json +1032 -888
- package/front_end/core/root/Runtime.ts +0 -1
- package/front_end/core/sdk/NetworkManager.test.ts +50 -0
- package/front_end/core/sdk/NetworkManager.ts +6 -4
- package/front_end/core/sdk/SourceMap.test.ts +5 -5
- package/front_end/core/sdk/SourceMapScopeChainEntry.test.ts +7 -2
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +2 -2
- package/front_end/core/sdk/SourceMapScopes.test.ts +112 -45
- package/front_end/core/sdk/SourceMapScopes.ts +39 -14
- package/front_end/core/sdk/SourceMapScopesInfo.test.ts +51 -50
- package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
- package/front_end/core/sdk/sdk-meta.ts +27 -0
- package/front_end/devtools_compatibility.js +0 -1
- package/front_end/entrypoints/devtools_app/devtools_app.ts +1 -0
- package/front_end/entrypoints/inspector_main/renderingOptions.css +1 -1
- package/front_end/entrypoints/main/ExecutionContextSelector.test.ts +13 -3
- package/front_end/entrypoints/main/ExecutionContextSelector.ts +23 -1
- package/front_end/entrypoints/main/MainImpl.ts +0 -5
- package/front_end/generated/Deprecation.ts +0 -15
- package/front_end/generated/InspectorBackendCommands.js +1 -1
- package/front_end/generated/SupportedCSSProperties.js +0 -40
- package/front_end/generated/protocol.ts +1 -0
- package/front_end/models/bindings/IgnoreListManager.ts +25 -2
- package/front_end/models/crux-manager/CrUXManager.test.ts +25 -6
- package/front_end/models/crux-manager/CrUXManager.ts +23 -4
- package/front_end/models/extensions/ExtensionServer.test.ts +14 -0
- package/front_end/models/extensions/ExtensionServer.ts +28 -15
- package/front_end/models/issues_manager/CookieIssue.ts +79 -2
- package/front_end/models/issues_manager/IssuesManager.ts +1 -1
- package/front_end/models/issues_manager/descriptions/cookieExcludePortMismatch.md +8 -0
- package/front_end/models/issues_manager/descriptions/cookieExcludeSchemeMismatch.md +7 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +14 -4
- package/front_end/models/persistence/EditFileSystemView.ts +2 -2
- package/front_end/models/persistence/editFileSystemView.css +6 -3
- package/front_end/models/persistence/workspaceSettingsTab.css +2 -2
- package/front_end/models/trace/extras/Metadata.test.ts +35 -2
- package/front_end/models/trace/extras/Metadata.ts +24 -5
- package/front_end/models/trace/extras/TraceTree.ts +28 -18
- package/front_end/models/trace/extras/URLForEntry.ts +6 -5
- package/front_end/models/trace/handlers/ImagePaintingHandler.ts +12 -0
- package/front_end/models/trace/helpers/Timing.ts +8 -0
- package/front_end/models/trace/insights/CLSCulprits.ts +11 -3
- package/front_end/models/trace/insights/DocumentLatency.ts +16 -3
- package/front_end/models/trace/insights/FontDisplay.ts +10 -3
- package/front_end/models/trace/insights/ImageDelivery.test.ts +98 -0
- package/front_end/models/trace/insights/ImageDelivery.ts +183 -0
- package/front_end/models/trace/insights/InteractionToNextPaint.ts +9 -3
- package/front_end/models/trace/insights/LCPDiscovery.ts +24 -3
- package/front_end/models/trace/insights/LCPPhases.ts +25 -3
- package/front_end/models/trace/insights/Models.ts +1 -0
- package/front_end/models/trace/insights/RenderBlocking.ts +10 -2
- package/front_end/models/trace/insights/SlowCSSSelector.ts +10 -3
- package/front_end/models/trace/insights/ThirdParties.ts +11 -3
- package/front_end/models/trace/insights/Viewport.ts +16 -3
- package/front_end/models/trace/insights/types.ts +13 -2
- package/front_end/models/trace/types/File.ts +7 -0
- package/front_end/models/trace/types/TraceEvents.ts +9 -2
- package/front_end/panels/animation/AnimationTimeline.ts +2 -4
- package/front_end/panels/application/ApplicationPanelSidebar.test.ts +0 -5
- package/front_end/panels/application/ApplicationPanelSidebar.ts +15 -21
- package/front_end/panels/application/IndexedDBViews.ts +4 -1
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +4 -1
- package/front_end/panels/application/StorageView.test.ts +1 -1
- package/front_end/panels/application/resourcesSidebar.css +1 -1
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +1 -1
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +1 -1
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +1 -1
- package/front_end/panels/browser_debugger/categorizedBreakpointsSidebarPane.css +1 -1
- package/front_end/panels/browser_debugger/xhrBreakpointsSidebarPane.css +1 -1
- package/front_end/panels/console/ConsoleViewMessage.test.ts +25 -0
- package/front_end/panels/console/ConsoleViewMessage.ts +23 -0
- package/front_end/panels/coverage/CoverageListView.ts +1 -1
- package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
- package/front_end/panels/elements/ClassesPaneWidget.ts +1 -1
- package/front_end/panels/elements/ElementStatePaneWidget.test.ts +3 -2
- package/front_end/panels/elements/ElementStatePaneWidget.ts +7 -2
- package/front_end/panels/elements/ElementsSidebarPane.ts +3 -3
- package/front_end/panels/elements/ElementsTreeElement.ts +1 -0
- package/front_end/panels/elements/LayersWidget.ts +1 -1
- package/front_end/panels/elements/PropertyMatchers.test.ts +7 -0
- package/front_end/panels/elements/PropertyMatchers.ts +3 -0
- package/front_end/panels/elements/classesPaneWidget.css +1 -1
- package/front_end/panels/emulation/DeviceModeView.ts +1 -1
- package/front_end/panels/emulation/DeviceModeWrapper.ts +1 -1
- package/front_end/panels/emulation/InspectedPagePlaceholder.ts +1 -1
- package/front_end/panels/freestyler/AiAgent.test.ts +319 -50
- package/front_end/panels/freestyler/AiAgent.ts +193 -141
- package/front_end/panels/freestyler/AiHistoryStorage.test.ts +159 -0
- package/front_end/panels/freestyler/AiHistoryStorage.ts +73 -0
- package/front_end/panels/freestyler/DrJonesFileAgent.test.ts +14 -15
- package/front_end/panels/freestyler/DrJonesFileAgent.ts +3 -14
- package/front_end/panels/freestyler/DrJonesNetworkAgent.test.ts +14 -13
- package/front_end/panels/freestyler/DrJonesNetworkAgent.ts +3 -3
- package/front_end/panels/freestyler/DrJonesPerformanceAgent.test.ts +38 -36
- package/front_end/panels/freestyler/DrJonesPerformanceAgent.ts +3 -14
- package/front_end/panels/freestyler/FreestylerAgent.test.ts +195 -14
- package/front_end/panels/freestyler/FreestylerAgent.ts +13 -18
- package/front_end/panels/freestyler/FreestylerPanel.test.ts +71 -0
- package/front_end/panels/freestyler/FreestylerPanel.ts +99 -74
- package/front_end/panels/freestyler/components/FreestylerChatUi.ts +128 -29
- package/front_end/panels/freestyler/components/UserActionRow.ts +1 -0
- package/front_end/panels/freestyler/components/freestylerChatUi.css +21 -1
- package/front_end/panels/freestyler/components/userActionRow.css +2 -1
- package/front_end/panels/freestyler/freestyler.ts +1 -0
- package/front_end/panels/issues/IssueAggregator.test.ts +50 -0
- package/front_end/panels/issues/IssueAggregator.ts +10 -10
- package/front_end/panels/issues/issuesTree.css +1 -1
- package/front_end/panels/layer_viewer/LayerDetailsView.ts +1 -1
- package/front_end/panels/layer_viewer/Layers3DView.ts +1 -1
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +1 -1
- package/front_end/panels/layers/LayersPanel.ts +1 -1
- package/front_end/panels/lighthouse/lighthouseStartView.css +1 -1
- package/front_end/panels/media/TickingFlameChart.ts +1 -1
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +1 -1
- package/front_end/panels/network/BlockedURLsPane.ts +1 -1
- package/front_end/panels/network/NetworkDataGridNode.ts +1 -0
- package/front_end/panels/network/NetworkLogView.test.ts +1 -1
- package/front_end/panels/network/NetworkPanel.ts +40 -32
- package/front_end/panels/network/NetworkWaterfallColumn.ts +1 -1
- package/front_end/panels/profiler/HeapProfileView.ts +9 -9
- package/front_end/panels/profiler/HeapTimelineOverview.ts +1 -1
- package/front_end/panels/profiler/IsolateSelector.ts +1 -1
- package/front_end/panels/profiler/LiveHeapProfileView.ts +3 -1
- package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +3 -3
- package/front_end/panels/profiler/ProfileView.ts +2 -2
- package/front_end/panels/profiler/profileLauncherView.css +1 -1
- package/front_end/panels/profiler/profilesSidebarTree.css +1 -1
- package/front_end/panels/recorder/recorderController.css +1 -1
- package/front_end/panels/security/CookieControlsTreeElement.ts +18 -0
- package/front_end/panels/security/CookieControlsView.test.ts +29 -0
- package/front_end/panels/security/CookieControlsView.ts +265 -0
- package/front_end/panels/security/CookieReportView.test.ts +157 -0
- package/front_end/panels/security/CookieReportView.ts +208 -12
- package/front_end/panels/security/SecurityPanel.ts +5 -3
- package/front_end/panels/security/SecurityPanelSidebar.ts +6 -1
- package/front_end/panels/security/cookieControlsView.css +101 -0
- package/front_end/panels/security/cookieReportView.css +26 -3
- package/front_end/panels/security/security.ts +4 -0
- package/front_end/panels/security/sidebar.css +1 -1
- package/front_end/panels/settings/KeybindsSettingsTab.ts +3 -2
- package/front_end/panels/settings/SettingsScreen.ts +5 -1
- package/front_end/panels/settings/frameworkIgnoreListSettingsTab.css +1 -1
- package/front_end/panels/settings/keybindsSettingsTab.css +6 -1
- package/front_end/panels/settings/settings-meta.ts +3 -1
- package/front_end/panels/settings/settingsScreen.css +10 -0
- package/front_end/panels/sources/CallStackSidebarPane.ts +2 -2
- package/front_end/panels/sources/NavigatorView.ts +1 -0
- package/front_end/panels/sources/navigatorTree.css +1 -1
- package/front_end/panels/sources/sourcesPanel.css +2 -2
- package/front_end/panels/timeline/AnimationsTrackAppender.ts +1 -7
- package/front_end/panels/timeline/AppenderUtils.ts +1 -1
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +38 -41
- package/front_end/panels/timeline/ExtensionTrackAppender.ts +4 -13
- package/front_end/panels/timeline/InteractionsTrackAppender.ts +3 -4
- package/front_end/panels/timeline/LayoutShiftsTrackAppender.ts +6 -12
- package/front_end/panels/timeline/ServerTimingsTrackAppender.ts +1 -10
- package/front_end/panels/timeline/ThreadAppender.ts +9 -12
- package/front_end/panels/timeline/TimelineController.ts +1 -1
- package/front_end/panels/timeline/TimelineDetailsView.test.ts +3 -2
- package/front_end/panels/timeline/TimelineDetailsView.ts +18 -17
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +55 -36
- package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +1 -1
- package/front_end/panels/timeline/TimelineFlameChartView.ts +33 -14
- package/front_end/panels/timeline/TimelineHistoryManager.test.ts +20 -15
- package/front_end/panels/timeline/TimelineHistoryManager.ts +46 -58
- package/front_end/panels/timeline/TimelineLayersView.ts +1 -1
- package/front_end/panels/timeline/TimelineLoader.ts +16 -0
- package/front_end/panels/timeline/TimelineMiniMap.ts +2 -2
- package/front_end/panels/timeline/TimelinePaintProfilerView.ts +1 -1
- package/front_end/panels/timeline/TimelinePanel.ts +145 -28
- package/front_end/panels/timeline/TimelineTreeView.ts +65 -16
- package/front_end/panels/timeline/TimelineUIUtils.ts +44 -0
- package/front_end/panels/timeline/TimingsTrackAppender.ts +6 -13
- package/front_end/panels/timeline/components/FieldSettingsDialog.test.ts +1 -0
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +6 -1
- package/front_end/panels/timeline/components/LiveMetricsView.test.ts +12 -0
- package/front_end/panels/timeline/components/LiveMetricsView.ts +13 -18
- package/front_end/panels/timeline/components/Sidebar.ts +1 -4
- package/front_end/panels/timeline/components/SidebarAnnotationsTab.test.ts +1 -1
- package/front_end/panels/timeline/components/SidebarInsightsTab.ts +1 -1
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.test.ts +21 -35
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +16 -9
- package/front_end/panels/timeline/components/TimelineSummary.test.ts +75 -0
- package/front_end/panels/timeline/components/TimelineSummary.ts +101 -0
- package/front_end/panels/timeline/components/Utils.test.ts +49 -0
- package/front_end/panels/timeline/components/Utils.ts +2 -2
- package/front_end/panels/timeline/components/components.ts +2 -0
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.test.ts +84 -0
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +291 -0
- package/front_end/panels/timeline/components/insights/CLSCulprits.ts +17 -41
- package/front_end/panels/timeline/components/insights/DocumentLatency.ts +28 -46
- package/front_end/panels/timeline/components/insights/EventRef.ts +70 -2
- package/front_end/panels/timeline/components/insights/FontDisplay.ts +28 -46
- package/front_end/panels/timeline/components/insights/Helpers.ts +5 -208
- package/front_end/panels/timeline/components/insights/ImageDelivery.ts +142 -0
- package/front_end/panels/timeline/components/insights/InteractionToNextPaint.ts +30 -53
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +36 -75
- package/front_end/panels/timeline/components/insights/LCPPhases.ts +15 -49
- package/front_end/panels/timeline/components/insights/RenderBlocking.ts +27 -44
- package/front_end/panels/timeline/components/insights/SidebarInsight.ts +3 -197
- package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +51 -74
- package/front_end/panels/timeline/components/insights/Table.ts +6 -5
- package/front_end/panels/timeline/components/insights/ThirdParties.ts +41 -61
- package/front_end/panels/timeline/components/insights/Viewport.ts +20 -31
- package/front_end/panels/timeline/components/insights/{sidebarInsight.css → baseInsightComponent.css} +9 -9
- package/front_end/panels/timeline/components/insights/insights.ts +4 -0
- package/front_end/panels/timeline/components/insights/types.ts +0 -7
- package/front_end/panels/timeline/components/liveMetricsView.css +5 -5
- package/front_end/panels/timeline/components/timelineSummary.css +67 -0
- package/front_end/panels/timeline/docs/flame_chart_migration.md +1 -1
- package/front_end/panels/timeline/fixtures/traces/README.md +4 -0
- package/front_end/panels/timeline/fixtures/traces/image-delivery.json.gz +0 -0
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +22 -0
- package/front_end/panels/timeline/timeline-meta.ts +1 -1
- package/front_end/panels/timeline/timelineFlamechartPopover.css +14 -4
- package/front_end/panels/timeline/timelineHistoryManager.css +7 -3
- package/front_end/panels/timeline/timelinePanel.css +0 -1
- package/front_end/panels/timeline/track_appenders/CompatibilityTracksAppender.test.ts +5 -5
- package/front_end/panels/timeline/track_appenders/ExtensionTrackAppender.test.ts +5 -6
- package/front_end/panels/timeline/track_appenders/LayoutShiftsTrackAppender.test.ts +11 -2
- package/front_end/panels/timeline/track_appenders/ServerTimingsTrackAppender.test.ts +0 -9
- package/front_end/panels/timeline/track_appenders/ThreadAppender.test.ts +37 -44
- package/front_end/panels/timeline/track_appenders/TimingsTrackAppender.test.ts +44 -30
- package/front_end/panels/timeline/utils/EntryName.ts +1 -2
- package/front_end/panels/timeline/utils/Helpers.ts +19 -0
- package/front_end/panels/timeline/utils/IgnoreList.test.ts +52 -0
- package/front_end/panels/timeline/utils/IgnoreList.ts +68 -7
- package/front_end/panels/timeline/utils/SourceMapsResolver.ts +2 -0
- package/front_end/panels/webauthn/webauthnPane.css +1 -1
- package/front_end/panels/whats_new/ReleaseNote.test.ts +90 -0
- package/front_end/panels/whats_new/ReleaseNoteText.ts +52 -0
- package/front_end/panels/whats_new/ReleaseNoteView.ts +157 -0
- package/front_end/panels/whats_new/WhatsNewImpl.ts +102 -0
- package/front_end/panels/whats_new/releaseNoteView.css +121 -0
- package/front_end/panels/whats_new/resources/WNDT.md +6 -0
- package/front_end/panels/whats_new/resources/whatsnew.avif +0 -0
- package/front_end/panels/whats_new/whats_new-meta.ts +142 -0
- package/front_end/panels/whats_new/whats_new.ts +13 -0
- package/front_end/services/puppeteer/PuppeteerConnection.ts +4 -3
- package/front_end/testing/EnvironmentHelpers.ts +1 -2
- package/front_end/testing/SourceMapEncoder.ts +27 -11
- package/front_end/testing/TraceHelpers.ts +2 -1
- package/front_end/testing/TraceLoader.ts +6 -2
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1380 -1369
- package/front_end/third_party/lighthouse/locales/ar-XB.json +88 -85
- package/front_end/third_party/lighthouse/locales/ar.json +98 -95
- package/front_end/third_party/lighthouse/locales/bg.json +88 -85
- package/front_end/third_party/lighthouse/locales/ca.json +91 -88
- package/front_end/third_party/lighthouse/locales/cs.json +91 -88
- package/front_end/third_party/lighthouse/locales/da.json +94 -91
- package/front_end/third_party/lighthouse/locales/de.json +92 -89
- package/front_end/third_party/lighthouse/locales/el.json +92 -89
- package/front_end/third_party/lighthouse/locales/en-GB.json +89 -86
- package/front_end/third_party/lighthouse/locales/en-US.json +23 -20
- package/front_end/third_party/lighthouse/locales/en-XA.json +88 -85
- package/front_end/third_party/lighthouse/locales/en-XL.json +23 -20
- package/front_end/third_party/lighthouse/locales/es-419.json +92 -89
- package/front_end/third_party/lighthouse/locales/es.json +91 -88
- package/front_end/third_party/lighthouse/locales/fi.json +92 -89
- package/front_end/third_party/lighthouse/locales/fil.json +93 -90
- package/front_end/third_party/lighthouse/locales/fr.json +94 -91
- package/front_end/third_party/lighthouse/locales/he.json +97 -94
- package/front_end/third_party/lighthouse/locales/hi.json +92 -89
- package/front_end/third_party/lighthouse/locales/hr.json +90 -87
- package/front_end/third_party/lighthouse/locales/hu.json +90 -87
- package/front_end/third_party/lighthouse/locales/id.json +91 -88
- package/front_end/third_party/lighthouse/locales/it.json +90 -87
- package/front_end/third_party/lighthouse/locales/ja.json +90 -87
- package/front_end/third_party/lighthouse/locales/ko.json +90 -87
- package/front_end/third_party/lighthouse/locales/lt.json +90 -87
- package/front_end/third_party/lighthouse/locales/lv.json +91 -88
- package/front_end/third_party/lighthouse/locales/nl.json +90 -87
- package/front_end/third_party/lighthouse/locales/no.json +92 -89
- package/front_end/third_party/lighthouse/locales/pl.json +90 -87
- package/front_end/third_party/lighthouse/locales/pt-PT.json +111 -108
- package/front_end/third_party/lighthouse/locales/pt.json +97 -94
- package/front_end/third_party/lighthouse/locales/ro.json +94 -91
- package/front_end/third_party/lighthouse/locales/ru.json +93 -90
- package/front_end/third_party/lighthouse/locales/sk.json +93 -90
- package/front_end/third_party/lighthouse/locales/sl.json +91 -88
- package/front_end/third_party/lighthouse/locales/sr-Latn.json +91 -88
- package/front_end/third_party/lighthouse/locales/sr.json +91 -88
- package/front_end/third_party/lighthouse/locales/sv.json +92 -89
- package/front_end/third_party/lighthouse/locales/ta.json +101 -98
- package/front_end/third_party/lighthouse/locales/te.json +92 -89
- package/front_end/third_party/lighthouse/locales/th.json +95 -92
- package/front_end/third_party/lighthouse/locales/tr.json +91 -88
- package/front_end/third_party/lighthouse/locales/uk.json +93 -90
- package/front_end/third_party/lighthouse/locales/vi.json +95 -92
- package/front_end/third_party/lighthouse/locales/zh-HK.json +92 -89
- package/front_end/third_party/lighthouse/locales/zh-TW.json +98 -95
- package/front_end/third_party/lighthouse/locales/zh.json +96 -93
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +8 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPRequest.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPRequest.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +3 -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 +10 -4
- 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/BrowserContext.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +7 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPResponse.d.ts +1 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPResponse.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js +24 -12
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts +5 -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/common/DownloadBehavior.d.ts +30 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/DownloadBehavior.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/DownloadBehavior.js +8 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/DownloadBehavior.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/common.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/common.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/version.js +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/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +49 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +118 -88
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +8 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPRequest.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPRequest.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +3 -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 +10 -4
- 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/BrowserContext.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +7 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPResponse.d.ts +1 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPResponse.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js +24 -12
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts +5 -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/common/DownloadBehavior.d.ts +30 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/DownloadBehavior.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/DownloadBehavior.js +7 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/DownloadBehavior.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/common.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/common.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/version.js +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/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +49 -0
- package/front_end/third_party/puppeteer/package/package.json +3 -3
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +8 -0
- package/front_end/third_party/puppeteer/package/src/api/Frame.ts +3 -1
- package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +5 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +4 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +11 -3
- package/front_end/third_party/puppeteer/package/src/cdp/BrowserConnector.ts +2 -0
- package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +11 -0
- package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +4 -0
- package/front_end/third_party/puppeteer/package/src/cdp/HTTPResponse.ts +3 -5
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +34 -17
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +4 -0
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +5 -0
- package/front_end/third_party/puppeteer/package/src/common/DownloadBehavior.ts +31 -0
- package/front_end/third_party/puppeteer/package/src/common/common.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/generated/version.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +2 -0
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/puppeteer-tsconfig.json +1 -0
- package/front_end/ui/components/data_grid/DataGridControllerIntegrator.ts +4 -1
- package/front_end/ui/components/dialogs/ButtonDialog.test.ts +78 -0
- package/front_end/ui/components/dialogs/ButtonDialog.ts +131 -0
- package/front_end/ui/components/dialogs/Dialog.test.ts +43 -0
- package/front_end/ui/components/dialogs/Dialog.ts +64 -2
- package/front_end/ui/components/dialogs/ShortcutDialog.test.ts +15 -1
- package/front_end/ui/components/dialogs/ShortcutDialog.ts +28 -20
- package/front_end/ui/components/dialogs/buttonDialog.css +9 -0
- package/front_end/ui/components/dialogs/dialog.css +15 -0
- package/front_end/ui/components/dialogs/dialogs.ts +2 -0
- package/front_end/ui/components/dialogs/shortcutDialog.css +34 -6
- package/front_end/ui/components/docs/dialog/button_dialog.html +28 -0
- package/front_end/ui/components/docs/dialog/button_dialog.ts +29 -0
- package/front_end/ui/components/docs/performance_panel/basic.ts +1 -1
- package/front_end/ui/components/docs/performance_panel/timeline_history_manager.ts +6 -4
- package/front_end/ui/components/floating_button/FloatingButton.ts +3 -2
- package/front_end/ui/components/icon_button/fileSourceIcon.css +7 -3
- package/front_end/ui/components/issue_counter/IssueCounter.ts +15 -2
- package/front_end/ui/components/legacy_wrapper/LegacyWrapper.ts +1 -1
- package/front_end/ui/components/markdown_view/MarkdownView.ts +15 -0
- package/front_end/ui/components/markdown_view/markdownView.css +1 -1
- package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +24 -18
- package/front_end/ui/components/switch/SwitchImpl.ts +2 -2
- package/front_end/ui/legacy/Infobar.ts +6 -0
- package/front_end/ui/legacy/InspectorView.ts +40 -0
- package/front_end/ui/legacy/ListWidget.ts +4 -2
- package/front_end/ui/legacy/ThrottledWidget.ts +2 -2
- package/front_end/ui/legacy/Toolbar.ts +3 -3
- package/front_end/ui/legacy/UIUtils.ts +8 -6
- package/front_end/ui/legacy/Widget.ts +32 -0
- package/front_end/ui/legacy/components/data_grid/DataGrid.test.ts +6 -9
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +35 -34
- package/front_end/ui/legacy/components/data_grid/ViewportDataGrid.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +32 -25
- package/front_end/ui/legacy/components/perf_ui/TimelineOverviewCalculator.ts +18 -4
- package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +80 -39
- package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +4 -4
- package/front_end/ui/legacy/components/utils/jsUtils.css +8 -0
- package/front_end/ui/legacy/filter.css +1 -1
- package/front_end/ui/legacy/inspectorCommon.css +1 -1
- package/front_end/ui/legacy/listWidget.css +4 -1
- package/front_end/ui/legacy/reportView.css +1 -1
- package/front_end/ui/legacy/toolbar.css +3 -6
- package/front_end/ui/legacy/treeoutline.css +3 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +12 -1
- package/front_end/ui/visual_logging/LoggingDriver.test.ts +27 -1
- package/front_end/ui/visual_logging/LoggingDriver.ts +7 -4
- package/package.json +2 -3
- package/scripts/build/wasm-as.py +1 -1
- package/scripts/freestyler/auto_freestyler.js +12 -4
- package/scripts/freestyler/to_tsv.mjs +40 -0
- package/scripts/tools/update_goldens.py +11 -13
- package/front_end/panels/timeline/components/insights/SidebarInsight.test.ts +0 -72
- package/front_end/ui/components/docs/two_states_counter/basic.html +0 -27
- package/front_end/ui/components/docs/two_states_counter/basic.ts +0 -45
- package/front_end/ui/components/two_states_counter/TwoStatesCounter.test.ts +0 -73
- package/front_end/ui/components/two_states_counter/TwoStatesCounter.ts +0 -104
- package/front_end/ui/components/two_states_counter/twoStatesCounter.css +0 -37
- package/front_end/ui/components/two_states_counter/two_states_counter.ts +0 -9
@@ -13,17 +13,23 @@ export class Node {
|
|
13
13
|
totalTime: number;
|
14
14
|
selfTime: number;
|
15
15
|
id: string|symbol;
|
16
|
-
event
|
16
|
+
/** The first trace event encountered that necessitated the creation of this tree node. */
|
17
|
+
event: Types.Events.Event;
|
18
|
+
/** All of the trace events associated with this aggregate node.
|
19
|
+
* Minor: In the case of Event Log (EventsTimelineTreeView), the node is not aggregate and this will only hold 1 event, the same that's in this.event
|
20
|
+
*/
|
21
|
+
events: Types.Events.Event[];
|
17
22
|
parent!: Node|null;
|
18
23
|
groupId: string;
|
19
24
|
isGroupNodeInternal: boolean;
|
20
25
|
depth: number;
|
21
26
|
|
22
|
-
constructor(id: string|symbol, event: Types.Events.Event
|
27
|
+
constructor(id: string|symbol, event: Types.Events.Event) {
|
23
28
|
this.totalTime = 0;
|
24
29
|
this.selfTime = 0;
|
25
30
|
this.id = id;
|
26
31
|
this.event = event;
|
32
|
+
this.events = [event];
|
27
33
|
|
28
34
|
this.groupId = '';
|
29
35
|
this.isGroupNodeInternal = false;
|
@@ -67,7 +73,7 @@ export class TopDownNode extends Node {
|
|
67
73
|
childrenInternal: ChildrenCache|null;
|
68
74
|
override parent: TopDownNode|null;
|
69
75
|
|
70
|
-
constructor(id: string|symbol, event: Types.Events.Event
|
76
|
+
constructor(id: string|symbol, event: Types.Events.Event, parent: TopDownNode|null) {
|
71
77
|
super(id, event);
|
72
78
|
this.root = parent && parent.root;
|
73
79
|
this.hasChildrenInternal = false;
|
@@ -180,6 +186,8 @@ export class TopDownNode extends Node {
|
|
180
186
|
node = new TopDownNode(id, e, self);
|
181
187
|
node.groupId = groupId;
|
182
188
|
children.set(id, node);
|
189
|
+
} else {
|
190
|
+
node.events.push(e);
|
183
191
|
}
|
184
192
|
node.selfTime += duration;
|
185
193
|
node.totalTime += duration;
|
@@ -238,8 +246,6 @@ export class TopDownNode extends Node {
|
|
238
246
|
|
239
247
|
export class TopDownRootNode extends TopDownNode {
|
240
248
|
readonly filter: (e: Types.Events.Event) => boolean;
|
241
|
-
/** This is all events passed in to create the tree, and it's very likely that it included events outside of the passed startTime/endTime as that filtering is done in `Helpers.Trace.forEachEvent` */
|
242
|
-
readonly events: Types.Events.Event[];
|
243
249
|
readonly startTime: Types.Timing.MilliSeconds;
|
244
250
|
readonly endTime: Types.Timing.MilliSeconds;
|
245
251
|
eventGroupIdCallback: ((arg0: Types.Events.Event) => string)|null|undefined;
|
@@ -253,7 +259,8 @@ export class TopDownRootNode extends TopDownNode {
|
|
253
259
|
events: Types.Events.Event[], filters: TraceFilter[], startTime: Types.Timing.MilliSeconds,
|
254
260
|
endTime: Types.Timing.MilliSeconds, doNotAggregate?: boolean,
|
255
261
|
eventGroupIdCallback?: ((arg0: Types.Events.Event) => string)|null, includeInstantEvents?: boolean) {
|
256
|
-
super('',
|
262
|
+
super('', events[0], null);
|
263
|
+
this.event = events[0];
|
257
264
|
this.root = this;
|
258
265
|
this.events = events;
|
259
266
|
this.filter = (e: Types.Events.Event): boolean => filters.every(f => f.accept(e));
|
@@ -281,14 +288,13 @@ export class TopDownRootNode extends TopDownNode {
|
|
281
288
|
}
|
282
289
|
const groupNodes = new Map<string, GroupNode>();
|
283
290
|
for (const node of flatNodes.values()) {
|
284
|
-
if (!node.event) {
|
285
|
-
continue;
|
286
|
-
}
|
287
291
|
const groupId = this.eventGroupIdCallback(node.event);
|
288
292
|
let groupNode = groupNodes.get(groupId);
|
289
293
|
if (!groupNode) {
|
290
|
-
groupNode = new GroupNode(groupId, this, node.
|
294
|
+
groupNode = new GroupNode(groupId, this, node.events);
|
291
295
|
groupNodes.set(groupId, groupNode);
|
296
|
+
} else {
|
297
|
+
groupNode.events.push(...node.events);
|
292
298
|
}
|
293
299
|
groupNode.addChild(node as BottomUpNode, node.selfTime, node.totalTime);
|
294
300
|
}
|
@@ -303,7 +309,6 @@ export class TopDownRootNode extends TopDownNode {
|
|
303
309
|
|
304
310
|
export class BottomUpRootNode extends Node {
|
305
311
|
private childrenInternal: ChildrenCache|null;
|
306
|
-
readonly events: Types.Events.Event[];
|
307
312
|
private textFilter: TraceFilter;
|
308
313
|
readonly filter: (e: Types.Events.Event) => boolean;
|
309
314
|
readonly startTime: Types.Timing.MilliSeconds;
|
@@ -315,7 +320,7 @@ export class BottomUpRootNode extends Node {
|
|
315
320
|
events: Types.Events.Event[], textFilter: TraceFilter, filters: TraceFilter[],
|
316
321
|
startTime: Types.Timing.MilliSeconds, endTime: Types.Timing.MilliSeconds,
|
317
322
|
eventGroupIdCallback: ((arg0: Types.Events.Event) => string)|null) {
|
318
|
-
super('',
|
323
|
+
super('', events[0]);
|
319
324
|
this.childrenInternal = null;
|
320
325
|
this.events = events;
|
321
326
|
this.textFilter = textFilter;
|
@@ -388,6 +393,8 @@ export class BottomUpRootNode extends Node {
|
|
388
393
|
if (!node) {
|
389
394
|
node = new BottomUpNode(root, id, event, false, root);
|
390
395
|
nodeById.set(id, node);
|
396
|
+
} else {
|
397
|
+
node.events.push(event);
|
391
398
|
}
|
392
399
|
node.selfTime += selfTimeStack.pop() || 0;
|
393
400
|
if (firstNodeStack.pop()) {
|
@@ -415,14 +422,13 @@ export class BottomUpRootNode extends Node {
|
|
415
422
|
}
|
416
423
|
const groupNodes = new Map<string, GroupNode>();
|
417
424
|
for (const node of flatNodes.values()) {
|
418
|
-
if (!node.event) {
|
419
|
-
continue;
|
420
|
-
}
|
421
425
|
const groupId = this.eventGroupIdCallback(node.event);
|
422
426
|
let groupNode = groupNodes.get(groupId);
|
423
427
|
if (!groupNode) {
|
424
|
-
groupNode = new GroupNode(groupId, this, node.
|
428
|
+
groupNode = new GroupNode(groupId, this, node.events);
|
425
429
|
groupNodes.set(groupId, groupNode);
|
430
|
+
} else {
|
431
|
+
groupNode.events.push(...node.events);
|
426
432
|
}
|
427
433
|
groupNode.addChild(node as BottomUpNode, node.selfTime, node.selfTime);
|
428
434
|
}
|
@@ -433,9 +439,11 @@ export class BottomUpRootNode extends Node {
|
|
433
439
|
export class GroupNode extends Node {
|
434
440
|
private readonly childrenInternal: ChildrenCache;
|
435
441
|
override isGroupNodeInternal: boolean;
|
442
|
+
override events: Types.Events.Event[];
|
436
443
|
|
437
|
-
constructor(id: string, parent: BottomUpRootNode|TopDownRootNode,
|
438
|
-
super(id,
|
444
|
+
constructor(id: string, parent: BottomUpRootNode|TopDownRootNode, events: Types.Events.Event[]) {
|
445
|
+
super(id, events[0]);
|
446
|
+
this.events = events;
|
439
447
|
this.childrenInternal = new Map();
|
440
448
|
this.parent = parent;
|
441
449
|
this.isGroupNodeInternal = true;
|
@@ -539,6 +547,8 @@ export class BottomUpNode extends Node {
|
|
539
547
|
const hasChildren = eventStack.length > self.depth;
|
540
548
|
node = new BottomUpNode(self.root, childId, event, hasChildren, self);
|
541
549
|
nodeById.set(childId, node);
|
550
|
+
} else {
|
551
|
+
node.events.push(e);
|
542
552
|
}
|
543
553
|
const actualEndTime = currentEndTime !== undefined ? Math.min(currentEndTime, endTime) : endTime;
|
544
554
|
const totalTime = actualEndTime - Math.max(currentStartTime, lastTimeMarker);
|
@@ -7,12 +7,13 @@ import type * as Handlers from '../handlers/handlers.js';
|
|
7
7
|
import * as Types from '../types/types.js';
|
8
8
|
|
9
9
|
/**
|
10
|
-
*
|
11
|
-
*
|
12
|
-
* helper SourceMapsResolver::resolvedURLForEntry
|
10
|
+
* INSTEAD, you probably want `SourceMapsResolver.resolvedURLForEntry()`!
|
11
|
+
* If an URL will be displayed in the UI, it's likely you should NOT use `getNonResolved`.
|
13
12
|
*
|
14
|
-
*
|
15
|
-
*
|
13
|
+
* Use `getNonResolved` method whenever resolving an URL's source mapping is not an
|
14
|
+
* option. For example when processing non-ui data.
|
15
|
+
*
|
16
|
+
* TODO: migrate existing uses of this over to resolvedURLForEntry.
|
16
17
|
*/
|
17
18
|
|
18
19
|
export function getNonResolved(
|
@@ -2,6 +2,7 @@
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
3
3
|
// found in the LICENSE file.
|
4
4
|
|
5
|
+
import * as Platform from '../../../core/platform/platform.js';
|
5
6
|
import * as Types from '../types/types.js';
|
6
7
|
|
7
8
|
/**
|
@@ -37,11 +38,14 @@ const paintImageByLazyPixelRef: Map<number, Types.Events.PaintImage> = new Map()
|
|
37
38
|
// have a relationship to a individual PaintImage event.
|
38
39
|
const eventToPaintImage: Map<Types.Events.Event, Types.Events.PaintImage> = new Map();
|
39
40
|
|
41
|
+
const urlToPaintImage: Map<string, Types.Events.PaintImage[]> = new Map();
|
42
|
+
|
40
43
|
export function reset(): void {
|
41
44
|
paintImageEvents.clear();
|
42
45
|
decodeLazyPixelRefEvents.clear();
|
43
46
|
paintImageByLazyPixelRef.clear();
|
44
47
|
eventToPaintImage.clear();
|
48
|
+
urlToPaintImage.clear();
|
45
49
|
}
|
46
50
|
|
47
51
|
export function handleEvent(event: Types.Events.Event): void {
|
@@ -51,6 +55,12 @@ export function handleEvent(event: Types.Events.Event): void {
|
|
51
55
|
forThread.push(event);
|
52
56
|
forProcess.set(event.tid, forThread);
|
53
57
|
paintImageEvents.set(event.pid, forProcess);
|
58
|
+
|
59
|
+
if (event.args.data.url) {
|
60
|
+
const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);
|
61
|
+
paintsForUrl.push(event);
|
62
|
+
}
|
63
|
+
|
54
64
|
return;
|
55
65
|
}
|
56
66
|
|
@@ -118,11 +128,13 @@ export async function finalize(): Promise<void> {
|
|
118
128
|
export interface ImagePaintData {
|
119
129
|
paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;
|
120
130
|
paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;
|
131
|
+
paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;
|
121
132
|
}
|
122
133
|
|
123
134
|
export function data(): ImagePaintData {
|
124
135
|
return {
|
125
136
|
paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,
|
126
137
|
paintImageForEvent: eventToPaintImage,
|
138
|
+
paintImageEventForUrl: urlToPaintImage,
|
127
139
|
};
|
128
140
|
}
|
@@ -147,6 +147,14 @@ export function traceWindowFromMicroSeconds(
|
|
147
147
|
return traceWindow;
|
148
148
|
}
|
149
149
|
|
150
|
+
export function traceWindowFromEvent(event: Types.Events.Event): Types.Timing.TraceWindowMicroSeconds {
|
151
|
+
return {
|
152
|
+
min: event.ts,
|
153
|
+
max: Types.Timing.MicroSeconds(event.ts + (event.dur ?? 0)),
|
154
|
+
range: event.dur ?? Types.Timing.MicroSeconds(0),
|
155
|
+
};
|
156
|
+
}
|
157
|
+
|
150
158
|
export interface BoundsIncludeTimeRange {
|
151
159
|
timeRange: Types.Timing.TraceWindowMicroSeconds;
|
152
160
|
bounds: Types.Timing.TraceWindowMicroSeconds;
|
@@ -8,7 +8,7 @@ import type * as Protocol from '../../../generated/protocol.js';
|
|
8
8
|
import * as Helpers from '../helpers/helpers.js';
|
9
9
|
import * as Types from '../types/types.js';
|
10
10
|
|
11
|
-
import type
|
11
|
+
import {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';
|
12
12
|
|
13
13
|
const UIStrings = {
|
14
14
|
/** Title of an insight that provides details about why elements shift/move on the page. The causes for these shifts are referred to as culprits ("reasons"). */
|
@@ -420,8 +420,16 @@ function getFontRootCauses(
|
|
420
420
|
return rootCausesByShift;
|
421
421
|
}
|
422
422
|
|
423
|
-
function finalize(partialModel: Omit<CLSCulpritsInsightModel, 'title'|'description'>):
|
424
|
-
|
423
|
+
function finalize(partialModel: Omit<CLSCulpritsInsightModel, 'title'|'description'|'category'|'shouldShow'>):
|
424
|
+
CLSCulpritsInsightModel {
|
425
|
+
return {
|
426
|
+
title: i18nString(UIStrings.title),
|
427
|
+
description: i18nString(UIStrings.description),
|
428
|
+
category: InsightCategory.CLS,
|
429
|
+
// TODO: getTopCulprits in component needs to move to model so this can be set here.
|
430
|
+
shouldShow: true,
|
431
|
+
...partialModel,
|
432
|
+
};
|
425
433
|
}
|
426
434
|
|
427
435
|
export function generateInsight(
|
@@ -6,7 +6,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
|
|
6
6
|
import * as Helpers from '../helpers/helpers.js';
|
7
7
|
import * as Types from '../types/types.js';
|
8
8
|
|
9
|
-
import type
|
9
|
+
import {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';
|
10
10
|
|
11
11
|
const UIStrings = {
|
12
12
|
/**
|
@@ -119,8 +119,21 @@ function getCompressionSavings(request: Types.Events.SyntheticNetworkRequest): n
|
|
119
119
|
return estimatedSavings < IGNORE_THRESHOLD_IN_BYTES ? 0 : estimatedSavings;
|
120
120
|
}
|
121
121
|
|
122
|
-
function finalize(partialModel: Omit<DocumentLatencyInsightModel, 'title'|'description'>):
|
123
|
-
|
122
|
+
function finalize(partialModel: Omit<DocumentLatencyInsightModel, 'title'|'description'|'category'|'shouldShow'>):
|
123
|
+
DocumentLatencyInsightModel {
|
124
|
+
let hasFailure = false;
|
125
|
+
if (partialModel.data) {
|
126
|
+
hasFailure = partialModel.data.redirectDuration > 0 || partialModel.data.serverResponseTooSlow ||
|
127
|
+
partialModel.data.uncompressedResponseBytes > 0;
|
128
|
+
}
|
129
|
+
|
130
|
+
return {
|
131
|
+
title: i18nString(UIStrings.title),
|
132
|
+
description: i18nString(UIStrings.description),
|
133
|
+
category: InsightCategory.ALL,
|
134
|
+
shouldShow: hasFailure,
|
135
|
+
...partialModel,
|
136
|
+
};
|
124
137
|
}
|
125
138
|
|
126
139
|
export function generateInsight(
|
@@ -7,7 +7,7 @@ import * as Platform from '../../../core/platform/platform.js';
|
|
7
7
|
import * as Helpers from '../helpers/helpers.js';
|
8
8
|
import * as Types from '../types/types.js';
|
9
9
|
|
10
|
-
import type
|
10
|
+
import {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';
|
11
11
|
|
12
12
|
const UIStrings = {
|
13
13
|
/** Title of an insight that provides details about the fonts used on the page, and the value of their `font-display` properties. */
|
@@ -34,8 +34,15 @@ export type FontDisplayInsightModel = InsightModel<{
|
|
34
34
|
}>,
|
35
35
|
}>;
|
36
36
|
|
37
|
-
function finalize(partialModel: Omit<FontDisplayInsightModel, 'title'|'description'>):
|
38
|
-
|
37
|
+
function finalize(partialModel: Omit<FontDisplayInsightModel, 'title'|'description'|'category'|'shouldShow'>):
|
38
|
+
FontDisplayInsightModel {
|
39
|
+
return {
|
40
|
+
title: i18nString(UIStrings.title),
|
41
|
+
description: i18nString(UIStrings.description),
|
42
|
+
category: InsightCategory.INP,
|
43
|
+
shouldShow: Boolean(partialModel.fonts.find(font => font.wastedTime > 0)),
|
44
|
+
...partialModel,
|
45
|
+
};
|
39
46
|
}
|
40
47
|
|
41
48
|
export function generateInsight(
|
@@ -0,0 +1,98 @@
|
|
1
|
+
// Copyright 2024 The Chromium Authors. All rights reserved.
|
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 {describeWithEnvironment} from '../../../testing/EnvironmentHelpers.js';
|
6
|
+
import {getFirstOrError, getInsightOrError} from '../../../testing/InsightHelpers.js';
|
7
|
+
import {TraceLoader} from '../../../testing/TraceLoader.js';
|
8
|
+
|
9
|
+
export async function processTrace(testContext: Mocha.Suite|Mocha.Context|null, traceFile: string) {
|
10
|
+
const {parsedTrace, insights} = await TraceLoader.traceEngine(testContext, traceFile);
|
11
|
+
if (!insights) {
|
12
|
+
throw new Error('No insights');
|
13
|
+
}
|
14
|
+
|
15
|
+
return {data: parsedTrace, insights};
|
16
|
+
}
|
17
|
+
|
18
|
+
describeWithEnvironment('ImageDelivery', function() {
|
19
|
+
it('finds requests for remote fonts', async () => {
|
20
|
+
// See the following for a description of each test case:
|
21
|
+
// https://gist.github.com/adamraine/397e2bd08665f9e45f6072e446715115
|
22
|
+
const {data, insights} = await processTrace(this, 'image-delivery.json.gz');
|
23
|
+
|
24
|
+
const imageRequests = data.NetworkRequests.byTime.filter(r => r.args.data.resourceType === 'Image');
|
25
|
+
assert.deepStrictEqual(imageRequests.map(r => r.args.data.url), [
|
26
|
+
'https://images.ctfassets.net/u275ja1nivmq/6T6z40ay5GFCUtwV7DONgh/0e23606ed1692d9721ab0f39a8d8a99e/yeti_cover.jpg',
|
27
|
+
'https://raw.githubusercontent.com/GoogleChrome/lighthouse/refs/heads/main/cli/test/fixtures/dobetterweb/lighthouse-rotating.gif',
|
28
|
+
'https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/5d52a2ab-7be3-4931-9e82-8728d1f55620/d51jfzi-b0efc925-7704-44bb-a3b8-8d98545af693.gif?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzVkNTJhMmFiLTdiZTMtNDkzMS05ZTgyLTg3MjhkMWY1NTYyMFwvZDUxamZ6aS1iMGVmYzkyNS03NzA0LTQ0YmItYTNiOC04ZDk4NTQ1YWY2OTMuZ2lmIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.T898HUlAbGFPboxRE43H5JujnDGl0zd_T128PnGLlpg',
|
29
|
+
'https://images.ctfassets.net/u275ja1nivmq/6T6z40ay5GFCUtwV7DONgh/0e23606ed1692d9721ab0f39a8d8a99e/yeti_cover.jpg?fm=webp',
|
30
|
+
'https://images.ctfassets.net/u275ja1nivmq/6T6z40ay5GFCUtwV7DONgh/0e23606ed1692d9721ab0f39a8d8a99e/yeti_cover.jpg?fm=avif',
|
31
|
+
'https://raw.githubusercontent.com/GoogleChrome/lighthouse/refs/heads/main/cli/test/fixtures/byte-efficiency/lighthouse-2048x1356.webp',
|
32
|
+
'https://raw.githubusercontent.com/GoogleChrome/lighthouse/refs/heads/main/cli/test/fixtures/byte-efficiency/lighthouse-480x320.webp',
|
33
|
+
'https://onlinepngtools.com/images/examples-onlinepngtools/elephant-hd-quality.png',
|
34
|
+
'https://raw.githubusercontent.com/GoogleChrome/lighthouse/refs/heads/main/cli/test/fixtures/dobetterweb/lighthouse-480x318.jpg',
|
35
|
+
]);
|
36
|
+
|
37
|
+
const insight =
|
38
|
+
getInsightOrError('ImageDelivery', insights, getFirstOrError(data.Meta.navigationsByNavigationId.values()));
|
39
|
+
assert.deepStrictEqual(
|
40
|
+
insight.optimizableImages.map(o => ({url: o.request.args.data.url, optimizations: o.optimizations})),
|
41
|
+
[
|
42
|
+
{
|
43
|
+
optimizations: [
|
44
|
+
{
|
45
|
+
byteSavings: 1057876,
|
46
|
+
type: 'modern-format-or-compression',
|
47
|
+
},
|
48
|
+
],
|
49
|
+
url:
|
50
|
+
'https://images.ctfassets.net/u275ja1nivmq/6T6z40ay5GFCUtwV7DONgh/0e23606ed1692d9721ab0f39a8d8a99e/yeti_cover.jpg',
|
51
|
+
},
|
52
|
+
{
|
53
|
+
optimizations: [
|
54
|
+
{
|
55
|
+
byteSavings: 682028,
|
56
|
+
type: 'video-format',
|
57
|
+
},
|
58
|
+
],
|
59
|
+
url:
|
60
|
+
'https://raw.githubusercontent.com/GoogleChrome/lighthouse/refs/heads/main/cli/test/fixtures/dobetterweb/lighthouse-rotating.gif',
|
61
|
+
},
|
62
|
+
{
|
63
|
+
optimizations: [
|
64
|
+
{
|
65
|
+
byteSavings: 49760,
|
66
|
+
type: 'compression',
|
67
|
+
},
|
68
|
+
],
|
69
|
+
url:
|
70
|
+
'https://images.ctfassets.net/u275ja1nivmq/6T6z40ay5GFCUtwV7DONgh/0e23606ed1692d9721ab0f39a8d8a99e/yeti_cover.jpg?fm=webp',
|
71
|
+
},
|
72
|
+
{
|
73
|
+
optimizations: [
|
74
|
+
{
|
75
|
+
byteSavings: 41421,
|
76
|
+
type: 'responsive-size',
|
77
|
+
},
|
78
|
+
],
|
79
|
+
url:
|
80
|
+
'https://raw.githubusercontent.com/GoogleChrome/lighthouse/refs/heads/main/cli/test/fixtures/byte-efficiency/lighthouse-2048x1356.webp',
|
81
|
+
},
|
82
|
+
{
|
83
|
+
optimizations: [
|
84
|
+
{
|
85
|
+
byteSavings: 134075,
|
86
|
+
type: 'modern-format-or-compression',
|
87
|
+
},
|
88
|
+
{
|
89
|
+
byteSavings: 162947,
|
90
|
+
type: 'responsive-size',
|
91
|
+
},
|
92
|
+
],
|
93
|
+
url: 'https://onlinepngtools.com/images/examples-onlinepngtools/elephant-hd-quality.png',
|
94
|
+
},
|
95
|
+
],
|
96
|
+
);
|
97
|
+
});
|
98
|
+
});
|
@@ -0,0 +1,183 @@
|
|
1
|
+
// Copyright 2024 The Chromium Authors. All rights reserved.
|
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 * as i18n from '../../../core/i18n/i18n.js';
|
6
|
+
import * as Helpers from '../helpers/helpers.js';
|
7
|
+
import type * as Types from '../types/types.js';
|
8
|
+
|
9
|
+
import {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';
|
10
|
+
|
11
|
+
const UIStrings = {
|
12
|
+
/**
|
13
|
+
* @description Title of an insight that recommends ways to reduce the size of images downloaded and used on the page.
|
14
|
+
*/
|
15
|
+
title: 'Improve image delivery',
|
16
|
+
/**
|
17
|
+
* @description Description of an insight that recommends ways to reduce the size of images downloaded and used on the page.
|
18
|
+
*/
|
19
|
+
description:
|
20
|
+
'Reducing the download time of images can improve the perceived load time of the page and LCP. [Learn more about optimizing image size](https://developer.chrome.com/docs/lighthouse/performance/uses-optimized-images/)',
|
21
|
+
};
|
22
|
+
|
23
|
+
const str_ = i18n.i18n.registerUIStrings('models/trace/insights/ImageDelivery.ts', UIStrings);
|
24
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Even JPEGs with lots of detail can usually be compressed down to <1 byte per pixel
|
28
|
+
* Using 4:2:2 subsampling already gets an uncompressed bitmap to 2 bytes per pixel.
|
29
|
+
* The compression ratio for JPEG is usually somewhere around 10:1 depending on content, so
|
30
|
+
* 8:1 is a reasonable expectation for web content which is 1.5MB for a 6MP image.
|
31
|
+
*
|
32
|
+
* WebP usually gives ~20% additional savings on top of that, so we will assume 10:1 for WebP.
|
33
|
+
* This is quite pessimistic as their study shows a photographic compression ratio of ~29:1.
|
34
|
+
* https://developers.google.com/speed/webp/docs/webp_lossless_alpha_study#results
|
35
|
+
*
|
36
|
+
* AVIF usually gives ~20% additional savings on top of WebP, so we will use 12:1 for AVIF.
|
37
|
+
* This is quite pessimistic as Netflix study shows a photographic compression ratio of ~40:1
|
38
|
+
* (0.4 *bits* per pixel at SSIM 0.97).
|
39
|
+
* https://netflixtechblog.com/avif-for-next-generation-image-coding-b1d75675fe4
|
40
|
+
*/
|
41
|
+
const TARGET_BYTES_PER_PIXEL_AVIF = 2 * 1 / 12;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* If GIFs are above this size, we'll flag them
|
45
|
+
* See https://github.com/GoogleChrome/lighthouse/pull/4885#discussion_r178406623 and https://github.com/GoogleChrome/lighthouse/issues/4696#issuecomment-370979920
|
46
|
+
*/
|
47
|
+
const GIF_SIZE_THRESHOLD = 100 * 1024;
|
48
|
+
|
49
|
+
const BYTE_SAVINGS_THRESHOLD = 4096;
|
50
|
+
|
51
|
+
export function deps(): ['NetworkRequests', 'Meta', 'ImagePainting'] {
|
52
|
+
return ['NetworkRequests', 'Meta', 'ImagePainting'];
|
53
|
+
}
|
54
|
+
|
55
|
+
export type ImageOptimizationType = 'modern-format-or-compression'|'compression'|'video-format'|'responsive-size';
|
56
|
+
|
57
|
+
export interface ImageOptimization {
|
58
|
+
type: ImageOptimizationType;
|
59
|
+
byteSavings: number;
|
60
|
+
}
|
61
|
+
|
62
|
+
export interface OptimizableImage {
|
63
|
+
request: Types.Events.SyntheticNetworkRequest;
|
64
|
+
optimizations: ImageOptimization[];
|
65
|
+
/**
|
66
|
+
* If the an image resource has multiple `PaintImage`s, we compare its intrinsic size to the largest of the displayed sizes.
|
67
|
+
*
|
68
|
+
* It is theoretically possible for `PaintImage` events with the same URL to have different intrinsic sizes.
|
69
|
+
* However, this should be rare because it requires serving different images from the same URL.
|
70
|
+
*/
|
71
|
+
largestImagePaint: Types.Events.PaintImage;
|
72
|
+
}
|
73
|
+
|
74
|
+
export type ImageDeliveryInsightModel = InsightModel<{
|
75
|
+
optimizableImages: OptimizableImage[],
|
76
|
+
}>;
|
77
|
+
|
78
|
+
function finalize(partialModel: Omit<ImageDeliveryInsightModel, 'title'|'description'|'category'|'shouldShow'>):
|
79
|
+
ImageDeliveryInsightModel {
|
80
|
+
return {
|
81
|
+
title: i18nString(UIStrings.title),
|
82
|
+
description: i18nString(UIStrings.description),
|
83
|
+
category: InsightCategory.LCP,
|
84
|
+
shouldShow: partialModel.optimizableImages.length > 0,
|
85
|
+
...partialModel,
|
86
|
+
relatedEvents: partialModel.optimizableImages.map(image => image.request),
|
87
|
+
};
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Calculate rough savings percentage based on 1000 real gifs transcoded to video
|
92
|
+
* https://github.com/GoogleChrome/lighthouse/issues/4696#issuecomment-380296510
|
93
|
+
*/
|
94
|
+
function estimateGIFPercentSavings(request: Types.Events.SyntheticNetworkRequest): number {
|
95
|
+
return Math.round((29.1 * Math.log10(request.args.data.decodedBodyLength) - 100.7)) / 100;
|
96
|
+
}
|
97
|
+
|
98
|
+
function getPixelCounts(paintImage: Types.Events.PaintImage): {displayedPixels: number, filePixels: number} {
|
99
|
+
return {
|
100
|
+
filePixels: paintImage.args.data.srcWidth * paintImage.args.data.srcHeight,
|
101
|
+
displayedPixels: paintImage.args.data.width * paintImage.args.data.height,
|
102
|
+
};
|
103
|
+
}
|
104
|
+
|
105
|
+
export function generateInsight(
|
106
|
+
parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ImageDeliveryInsightModel {
|
107
|
+
const isWithinContext = (event: Types.Events.Event): boolean => Helpers.Timing.eventIsInBounds(event, context.bounds);
|
108
|
+
|
109
|
+
const contextRequests = parsedTrace.NetworkRequests.byTime.filter(isWithinContext);
|
110
|
+
|
111
|
+
const optimizableImages: OptimizableImage[] = [];
|
112
|
+
for (const request of contextRequests) {
|
113
|
+
if (request.args.data.resourceType !== 'Image') {
|
114
|
+
continue;
|
115
|
+
}
|
116
|
+
|
117
|
+
const imagePaints =
|
118
|
+
parsedTrace.ImagePainting.paintImageEventForUrl.get(request.args.data.url)?.filter(isWithinContext);
|
119
|
+
|
120
|
+
// This will filter out things like preloaded image requests where an image file is downloaded
|
121
|
+
// but never rendered on the page.
|
122
|
+
if (!imagePaints?.length) {
|
123
|
+
continue;
|
124
|
+
}
|
125
|
+
|
126
|
+
const largestImagePaint = imagePaints.reduce((prev, curr) => {
|
127
|
+
const prevPixels = getPixelCounts(prev).displayedPixels;
|
128
|
+
const currPixels = getPixelCounts(curr).displayedPixels;
|
129
|
+
return prevPixels > currPixels ? prev : curr;
|
130
|
+
});
|
131
|
+
|
132
|
+
const {
|
133
|
+
filePixels: imageFilePixels,
|
134
|
+
displayedPixels: largestImageDisplayPixels,
|
135
|
+
} = getPixelCounts(largestImagePaint);
|
136
|
+
|
137
|
+
// Decoded body length is almost always the right one to be using because of the below:
|
138
|
+
// `encodedDataLength = decodedBodyLength + headers`.
|
139
|
+
// HOWEVER, there are some cases where an image is compressed again over the network and transfer size
|
140
|
+
// is smaller (see https://github.com/GoogleChrome/lighthouse/pull/4968).
|
141
|
+
// Use the min of the two numbers to be safe.
|
142
|
+
const imageBytes = Math.min(request.args.data.decodedBodyLength, request.args.data.encodedDataLength);
|
143
|
+
|
144
|
+
const bytesPerPixel = imageBytes / imageFilePixels;
|
145
|
+
|
146
|
+
let optimizations: ImageOptimization[] = [];
|
147
|
+
if (request.args.data.mimeType === 'image/gif') {
|
148
|
+
if (imageBytes > GIF_SIZE_THRESHOLD) {
|
149
|
+
const percentSavings = estimateGIFPercentSavings(request);
|
150
|
+
const byteSavings = Math.round(imageBytes * percentSavings);
|
151
|
+
optimizations.push({type: 'video-format', byteSavings});
|
152
|
+
}
|
153
|
+
} else if (bytesPerPixel > TARGET_BYTES_PER_PIXEL_AVIF) {
|
154
|
+
const idealAvifImageSize = Math.round(TARGET_BYTES_PER_PIXEL_AVIF * imageFilePixels);
|
155
|
+
const byteSavings = imageBytes - idealAvifImageSize;
|
156
|
+
if (request.args.data.mimeType !== 'image/webp' && request.args.data.mimeType !== 'image/avif') {
|
157
|
+
optimizations.push({type: 'modern-format-or-compression', byteSavings});
|
158
|
+
} else {
|
159
|
+
optimizations.push({type: 'compression', byteSavings});
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
const wastedPixelRatio = 1 - (largestImageDisplayPixels / imageFilePixels);
|
164
|
+
if (wastedPixelRatio > 0) {
|
165
|
+
const byteSavings = Math.round(wastedPixelRatio * imageBytes);
|
166
|
+
optimizations.push({type: 'responsive-size', byteSavings});
|
167
|
+
}
|
168
|
+
|
169
|
+
optimizations = optimizations.filter(optimization => optimization.byteSavings > BYTE_SAVINGS_THRESHOLD);
|
170
|
+
|
171
|
+
if (optimizations.length > 0) {
|
172
|
+
optimizableImages.push({
|
173
|
+
request,
|
174
|
+
largestImagePaint,
|
175
|
+
optimizations,
|
176
|
+
});
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
return finalize({
|
181
|
+
optimizableImages,
|
182
|
+
});
|
183
|
+
}
|
@@ -6,7 +6,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
|
|
6
6
|
import * as Helpers from '../helpers/helpers.js';
|
7
7
|
import type {SyntheticInteractionPair} from '../types/TraceEvents.js';
|
8
8
|
|
9
|
-
import type
|
9
|
+
import {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';
|
10
10
|
|
11
11
|
const UIStrings = {
|
12
12
|
/**
|
@@ -32,8 +32,14 @@ export type INPInsightModel = InsightModel<{
|
|
32
32
|
highPercentileInteractionEvent?: SyntheticInteractionPair,
|
33
33
|
}>;
|
34
34
|
|
35
|
-
function finalize(partialModel: Omit<INPInsightModel, 'title'|'description'>): INPInsightModel {
|
36
|
-
return {
|
35
|
+
function finalize(partialModel: Omit<INPInsightModel, 'title'|'description'|'category'|'shouldShow'>): INPInsightModel {
|
36
|
+
return {
|
37
|
+
title: i18nString(UIStrings.title),
|
38
|
+
description: i18nString(UIStrings.description),
|
39
|
+
category: InsightCategory.INP,
|
40
|
+
shouldShow: Boolean(partialModel.longestInteractionEvent),
|
41
|
+
...partialModel,
|
42
|
+
};
|
37
43
|
}
|
38
44
|
|
39
45
|
export function generateInsight(parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): INPInsightModel {
|
@@ -7,7 +7,13 @@ import * as Handlers from '../handlers/handlers.js';
|
|
7
7
|
import * as Helpers from '../helpers/helpers.js';
|
8
8
|
import * as Types from '../types/types.js';
|
9
9
|
|
10
|
-
import {
|
10
|
+
import {
|
11
|
+
InsightCategory,
|
12
|
+
type InsightModel,
|
13
|
+
type InsightSetContext,
|
14
|
+
InsightWarning,
|
15
|
+
type RequiredData,
|
16
|
+
} from './types.js';
|
11
17
|
|
12
18
|
const UIStrings = {
|
13
19
|
/**
|
@@ -38,8 +44,23 @@ export type LCPDiscoveryInsightModel = InsightModel<{
|
|
38
44
|
earliestDiscoveryTimeTs?: Types.Timing.MicroSeconds,
|
39
45
|
}>;
|
40
46
|
|
41
|
-
function finalize(partialModel: Omit<LCPDiscoveryInsightModel, 'title'|'description'>):
|
42
|
-
|
47
|
+
function finalize(partialModel: Omit<LCPDiscoveryInsightModel, 'title'|'description'|'category'|'shouldShow'>):
|
48
|
+
LCPDiscoveryInsightModel {
|
49
|
+
const relatedEvents = partialModel.lcpEvent && partialModel.lcpRequest ?
|
50
|
+
// TODO: add entire request initiator chain?
|
51
|
+
[partialModel.lcpEvent, partialModel.lcpRequest] :
|
52
|
+
[];
|
53
|
+
return {
|
54
|
+
title: i18nString(UIStrings.title),
|
55
|
+
description: i18nString(UIStrings.description),
|
56
|
+
category: InsightCategory.LCP,
|
57
|
+
shouldShow: Boolean(
|
58
|
+
partialModel.lcpRequest &&
|
59
|
+
(partialModel.shouldIncreasePriorityHint || partialModel.shouldPreloadImage ||
|
60
|
+
partialModel.shouldRemoveLazyLoading)),
|
61
|
+
...partialModel,
|
62
|
+
relatedEvents,
|
63
|
+
};
|
43
64
|
}
|
44
65
|
|
45
66
|
export function generateInsight(
|