From 32d58e2c3d5ce90e0a8d432f348a80af08870891 Mon Sep 17 00:00:00 2001 From: devan Date: Wed, 22 Oct 2025 17:49:33 -0400 Subject: [PATCH 1/8] Remove RN exclusion for frames and screenshots --- front_end/panels/timeline/TimelineFlameChartDataProvider.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts index 7c7e281d8d92..ba854e191b91 100644 --- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts @@ -615,9 +615,7 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW // In CPU Profiles the trace data will not have frames nor // screenshots, so we can keep this call as it will be a no-op in // these cases. - if (!this.isReactNative) { - this.#appendFramesAndScreenshotsTrack(); - } + this.#appendFramesAndScreenshotsTrack(); const weight = (track: {type?: string, forMainFrame?: boolean, appenderName?: TrackAppenderName}): number => { switch (track.appenderName) { From 689b29f057e4c2d6bb6183d1333130cefb76c5a1 Mon Sep 17 00:00:00 2001 From: devan Date: Wed, 22 Oct 2025 19:17:53 -0400 Subject: [PATCH 2/8] Remove import --- front_end/panels/timeline/TimelineFlameChartDataProvider.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts index ba854e191b91..b12e99ec226a 100644 --- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts @@ -106,8 +106,6 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectWrapper implements PerfUI.FlameChart.FlameChartDataProvider { - private isReactNative = false; - private droppedFramePatternCanvas: HTMLCanvasElement; private partialFramePatternCanvas: HTMLCanvasElement; private timelineDataInternal: PerfUI.FlameChart.FlameChartTimelineData|null = null; From 83c5d8fe745328dd58de0c58d63bf73c579f9a0a Mon Sep 17 00:00:00 2001 From: devan Date: Wed, 22 Oct 2025 19:19:27 -0400 Subject: [PATCH 3/8] Remove isReactNative --- front_end/panels/timeline/TimelineFlameChartDataProvider.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts index b12e99ec226a..42bbad7f1e50 100644 --- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts @@ -143,11 +143,6 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW constructor() { super(); - // [RN] Used to scope down available features for React Native targets - this.isReactNative = Root.Runtime.experiments.isEnabled( - Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, - ); - this.reset(); this.droppedFramePatternCanvas = document.createElement('canvas'); From 93152ea4a543f85ff98231b0b895471b1382aa06 Mon Sep 17 00:00:00 2001 From: devan Date: Mon, 3 Nov 2025 00:15:42 -0800 Subject: [PATCH 4/8] Place frames under experiment --- front_end/core/host/UserMetrics.ts | 3 ++- front_end/core/root/Runtime.ts | 1 + front_end/entrypoints/main/MainImpl.ts | 2 ++ front_end/panels/timeline/TimelineFlameChartDataProvider.ts | 4 +++- front_end/testing/EnvironmentHelpers.ts | 1 + front_end/ui/visual_logging/KnownContextValues.ts | 1 + 6 files changed, 10 insertions(+), 2 deletions(-) diff --git a/front_end/core/host/UserMetrics.ts b/front_end/core/host/UserMetrics.ts index e1d259558fbb..c5538bfa98f0 100644 --- a/front_end/core/host/UserMetrics.ts +++ b/front_end/core/host/UserMetrics.ts @@ -985,10 +985,11 @@ export enum DevtoolsExperiments { 'timeline-alternative-navigation' = 104, // 106 was historically used [https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6230097] // next experiment should be 107 + 'timeline-frames' = 108, /* eslint-enable @typescript-eslint/naming-convention */ // Increment this when new experiments are added. - MAX_VALUE = 106, + MAX_VALUE = 108, } // Update DevToolsIssuesPanelIssueExpanded from tools/metrics/histograms/enums.xml if new enum is added. diff --git a/front_end/core/root/Runtime.ts b/front_end/core/root/Runtime.ts index 9d1c9265e9d3..a8e19143eb4d 100644 --- a/front_end/core/root/Runtime.ts +++ b/front_end/core/root/Runtime.ts @@ -332,6 +332,7 @@ export const enum ExperimentName { TIMELINE_DEBUG_MODE = 'timeline-debug-mode', TIMELINE_ENHANCED_TRACES = 'timeline-enhanced-traces', TIMELINE_COMPILED_SOURCES = 'timeline-compiled-sources', + TIMELINE_FRAMES = 'timeline-frames', TIMELINE_EXPERIMENTAL_INSIGHTS = 'timeline-experimental-insights', TIMELINE_DIM_UNRELATED_EVENTS = 'timeline-dim-unrelated-events', TIMELINE_ALTERNATIVE_NAVIGATION = 'timeline-alternative-navigation', diff --git a/front_end/entrypoints/main/MainImpl.ts b/front_end/entrypoints/main/MainImpl.ts index 3a66e26580ae..44b06e0b70e9 100644 --- a/front_end/entrypoints/main/MainImpl.ts +++ b/front_end/entrypoints/main/MainImpl.ts @@ -301,6 +301,8 @@ export class MainImpl { Root.Runtime.experiments.register( Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE, 'Performance panel: Enable debug mode (trace event details, etc)', true); + Root.Runtime.experiments.register( + Root.Runtime.ExperimentName.TIMELINE_FRAMES, 'Performance panel: Enable frames track', true); // Debugging Root.Runtime.experiments.register('instrumentation-breakpoints', 'Enable instrumentation breakpoints', true); diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts index 42bbad7f1e50..5c1f58d7b78c 100644 --- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts @@ -608,7 +608,9 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW // In CPU Profiles the trace data will not have frames nor // screenshots, so we can keep this call as it will be a no-op in // these cases. - this.#appendFramesAndScreenshotsTrack(); + if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.TIMELINE_FRAMES)) { + this.#appendFramesAndScreenshotsTrack(); + } const weight = (track: {type?: string, forMainFrame?: boolean, appenderName?: TrackAppenderName}): number => { switch (track.appenderName) { diff --git a/front_end/testing/EnvironmentHelpers.ts b/front_end/testing/EnvironmentHelpers.ts index cc0af871c944..9537d38b8123 100644 --- a/front_end/testing/EnvironmentHelpers.ts +++ b/front_end/testing/EnvironmentHelpers.ts @@ -128,6 +128,7 @@ const REGISTERED_EXPERIMENTS = [ Root.Runtime.ExperimentName.TIMELINE_EXPERIMENTAL_INSIGHTS, Root.Runtime.ExperimentName.TIMELINE_DIM_UNRELATED_EVENTS, Root.Runtime.ExperimentName.TIMELINE_ALTERNATIVE_NAVIGATION, + Root.Runtime.ExperimentName.TIMELINE_FRAMES, Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, Root.Runtime.ExperimentName.NOT_REACT_NATIVE_SPECIFIC_UI, ]; diff --git a/front_end/ui/visual_logging/KnownContextValues.ts b/front_end/ui/visual_logging/KnownContextValues.ts index c1eb4fcbe0cc..0e6408f38ae9 100644 --- a/front_end/ui/visual_logging/KnownContextValues.ts +++ b/front_end/ui/visual_logging/KnownContextValues.ts @@ -3495,6 +3495,7 @@ export const knownContextValues = new Set([ 'time', 'timeline', 'timeline-alternative-navigation', + 'timeline-frames', 'timeline-capture-layers-and-pictures', 'timeline-capture-selector-stats', 'timeline-compiled-sources', From 977d403646bca24a02f9f1778a0f39354e776983 Mon Sep 17 00:00:00 2001 From: devan Date: Mon, 3 Nov 2025 13:06:17 -0800 Subject: [PATCH 5/8] Cleanup experiment --- front_end/core/host/UserMetrics.ts | 3 +-- front_end/core/rn_experiments/experimentsImpl.ts | 7 +++++++ front_end/core/root/Runtime.ts | 3 ++- front_end/entrypoints/main/MainImpl.ts | 4 +--- front_end/global_typings/react_native.d.ts | 2 ++ front_end/ui/visual_logging/KnownContextValues.ts | 1 - 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/front_end/core/host/UserMetrics.ts b/front_end/core/host/UserMetrics.ts index c5538bfa98f0..e1d259558fbb 100644 --- a/front_end/core/host/UserMetrics.ts +++ b/front_end/core/host/UserMetrics.ts @@ -985,11 +985,10 @@ export enum DevtoolsExperiments { 'timeline-alternative-navigation' = 104, // 106 was historically used [https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6230097] // next experiment should be 107 - 'timeline-frames' = 108, /* eslint-enable @typescript-eslint/naming-convention */ // Increment this when new experiments are added. - MAX_VALUE = 108, + MAX_VALUE = 106, } // Update DevToolsIssuesPanelIssueExpanded from tools/metrics/histograms/enums.xml if new enum is added. diff --git a/front_end/core/rn_experiments/experimentsImpl.ts b/front_end/core/rn_experiments/experimentsImpl.ts index b42546e39fc5..4ff411743c76 100644 --- a/front_end/core/rn_experiments/experimentsImpl.ts +++ b/front_end/core/rn_experiments/experimentsImpl.ts @@ -198,3 +198,10 @@ Instance.register({ unstable: true, enabledByDefault: () => false, }); + +Instance.register({ + name: RNExperimentName.ENABLE_TIMELINE_FRAMES, + title: 'Enable performance frames track', + unstable: true, + enabledByDefault: () => globalThis.enableTimelineFrames ?? false, +}); diff --git a/front_end/core/root/Runtime.ts b/front_end/core/root/Runtime.ts index a8e19143eb4d..35c927afe6e7 100644 --- a/front_end/core/root/Runtime.ts +++ b/front_end/core/root/Runtime.ts @@ -307,6 +307,7 @@ export enum RNExperimentName { JS_HEAP_PROFILER_ENABLE = 'js-heap-profiler-enable', ENABLE_PERFORMANCE_PANEL = 'enable-performance-panel', ENABLE_NETWORK_PANEL = 'enable-network-panel', + ENABLE_TIMELINE_FRAMES = 'enable-timeline-frames', } export enum ConditionName { @@ -332,7 +333,6 @@ export const enum ExperimentName { TIMELINE_DEBUG_MODE = 'timeline-debug-mode', TIMELINE_ENHANCED_TRACES = 'timeline-enhanced-traces', TIMELINE_COMPILED_SOURCES = 'timeline-compiled-sources', - TIMELINE_FRAMES = 'timeline-frames', TIMELINE_EXPERIMENTAL_INSIGHTS = 'timeline-experimental-insights', TIMELINE_DIM_UNRELATED_EVENTS = 'timeline-dim-unrelated-events', TIMELINE_ALTERNATIVE_NAVIGATION = 'timeline-alternative-navigation', @@ -344,6 +344,7 @@ export const enum ExperimentName { NOT_REACT_NATIVE_SPECIFIC_UI = '!' + RNExperimentName.REACT_NATIVE_SPECIFIC_UI, ENABLE_PERFORMANCE_PANEL = RNExperimentName.ENABLE_PERFORMANCE_PANEL, ENABLE_NETWORK_PANEL = RNExperimentName.ENABLE_NETWORK_PANEL, + ENABLE_TIMELINE_FRAMES = RNExperimentName.ENABLE_TIMELINE_FRAMES, } export enum GenAiEnterprisePolicyValue { diff --git a/front_end/entrypoints/main/MainImpl.ts b/front_end/entrypoints/main/MainImpl.ts index 44b06e0b70e9..bdd48b1ea515 100644 --- a/front_end/entrypoints/main/MainImpl.ts +++ b/front_end/entrypoints/main/MainImpl.ts @@ -301,10 +301,8 @@ export class MainImpl { Root.Runtime.experiments.register( Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE, 'Performance panel: Enable debug mode (trace event details, etc)', true); - Root.Runtime.experiments.register( - Root.Runtime.ExperimentName.TIMELINE_FRAMES, 'Performance panel: Enable frames track', true); - // Debugging + // Debugging Root.Runtime.experiments.register('instrumentation-breakpoints', 'Enable instrumentation breakpoints', true); Root.Runtime.experiments.register('use-source-map-scopes', 'Use scope information from source maps', true); diff --git a/front_end/global_typings/react_native.d.ts b/front_end/global_typings/react_native.d.ts index ac80b34a4a61..8d485b7631c8 100644 --- a/front_end/global_typings/react_native.d.ts +++ b/front_end/global_typings/react_native.d.ts @@ -16,6 +16,8 @@ declare global { // eslint-disable-next-line no-var var enableDisplayingFullDisconnectedReason: boolean|undefined; // eslint-disable-next-line no-var + var enableTimelineFrames: boolean|undefined; + // eslint-disable-next-line no-var var reactNativeOpenInEditorButtonImage: string|undefined; // eslint-disable-next-line no-var,@typescript-eslint/naming-convention var FB_ONLY__reactNativeFeedbackLink: string|undefined; diff --git a/front_end/ui/visual_logging/KnownContextValues.ts b/front_end/ui/visual_logging/KnownContextValues.ts index 0e6408f38ae9..c1eb4fcbe0cc 100644 --- a/front_end/ui/visual_logging/KnownContextValues.ts +++ b/front_end/ui/visual_logging/KnownContextValues.ts @@ -3495,7 +3495,6 @@ export const knownContextValues = new Set([ 'time', 'timeline', 'timeline-alternative-navigation', - 'timeline-frames', 'timeline-capture-layers-and-pictures', 'timeline-capture-selector-stats', 'timeline-compiled-sources', From ba292d9a69ac3d1c880df0a5327de1f7d26a5c49 Mon Sep 17 00:00:00 2001 From: devan Date: Mon, 3 Nov 2025 13:11:27 -0800 Subject: [PATCH 6/8] Use correct experiment --- front_end/entrypoints/main/MainImpl.ts | 2 +- front_end/panels/timeline/TimelineFlameChartDataProvider.ts | 2 +- front_end/testing/EnvironmentHelpers.ts | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/front_end/entrypoints/main/MainImpl.ts b/front_end/entrypoints/main/MainImpl.ts index bdd48b1ea515..3a66e26580ae 100644 --- a/front_end/entrypoints/main/MainImpl.ts +++ b/front_end/entrypoints/main/MainImpl.ts @@ -302,7 +302,7 @@ export class MainImpl { Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE, 'Performance panel: Enable debug mode (trace event details, etc)', true); - // Debugging + // Debugging Root.Runtime.experiments.register('instrumentation-breakpoints', 'Enable instrumentation breakpoints', true); Root.Runtime.experiments.register('use-source-map-scopes', 'Use scope information from source maps', true); diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts index 5c1f58d7b78c..6826abe4e934 100644 --- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts @@ -608,7 +608,7 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW // In CPU Profiles the trace data will not have frames nor // screenshots, so we can keep this call as it will be a no-op in // these cases. - if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.TIMELINE_FRAMES)) { + if (Root.Runtime.experiments.isEnabled(Root.Runtime.RNExperimentName.ENABLE_TIMELINE_FRAMES)) { this.#appendFramesAndScreenshotsTrack(); } diff --git a/front_end/testing/EnvironmentHelpers.ts b/front_end/testing/EnvironmentHelpers.ts index 9537d38b8123..cc0af871c944 100644 --- a/front_end/testing/EnvironmentHelpers.ts +++ b/front_end/testing/EnvironmentHelpers.ts @@ -128,7 +128,6 @@ const REGISTERED_EXPERIMENTS = [ Root.Runtime.ExperimentName.TIMELINE_EXPERIMENTAL_INSIGHTS, Root.Runtime.ExperimentName.TIMELINE_DIM_UNRELATED_EVENTS, Root.Runtime.ExperimentName.TIMELINE_ALTERNATIVE_NAVIGATION, - Root.Runtime.ExperimentName.TIMELINE_FRAMES, Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, Root.Runtime.ExperimentName.NOT_REACT_NATIVE_SPECIFIC_UI, ]; From 8855c9359b3bca2b5fb50ff243a444308e90a236 Mon Sep 17 00:00:00 2001 From: devan Date: Wed, 12 Nov 2025 14:53:16 -0800 Subject: [PATCH 7/8] Fix experiment --- front_end/core/rn_experiments/experimentsImpl.ts | 7 ------- front_end/core/root/Runtime.ts | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/front_end/core/rn_experiments/experimentsImpl.ts b/front_end/core/rn_experiments/experimentsImpl.ts index d499eac68e08..32b5996d2c5a 100644 --- a/front_end/core/rn_experiments/experimentsImpl.ts +++ b/front_end/core/rn_experiments/experimentsImpl.ts @@ -185,13 +185,6 @@ Instance.register({ enabledByDefault: ({ isReactNativeEntryPoint }) => isReactNativeEntryPoint, }); -Instance.register({ - name: RNExperimentName.ENABLE_NETWORK_PANEL, - title: 'Enable Network panel', - unstable: true, - enabledByDefault: () => false, -}); - Instance.register({ name: RNExperimentName.ENABLE_TIMELINE_FRAMES, title: 'Enable performance frames track', diff --git a/front_end/core/root/Runtime.ts b/front_end/core/root/Runtime.ts index d5e62c28ae33..6c59a91c84c8 100644 --- a/front_end/core/root/Runtime.ts +++ b/front_end/core/root/Runtime.ts @@ -305,6 +305,7 @@ export const experiments = new ExperimentsSupport(); export enum RNExperimentName { REACT_NATIVE_SPECIFIC_UI = 'react-native-specific-ui', JS_HEAP_PROFILER_ENABLE = 'js-heap-profiler-enable', + ENABLE_TIMELINE_FRAMES = 'enable-timeline-frames', } export enum ConditionName { @@ -339,7 +340,6 @@ export const enum ExperimentName { JS_HEAP_PROFILER_ENABLE = RNExperimentName.JS_HEAP_PROFILER_ENABLE, REACT_NATIVE_SPECIFIC_UI = RNExperimentName.REACT_NATIVE_SPECIFIC_UI, NOT_REACT_NATIVE_SPECIFIC_UI = '!' + RNExperimentName.REACT_NATIVE_SPECIFIC_UI, - ENABLE_NETWORK_PANEL = RNExperimentName.ENABLE_NETWORK_PANEL, ENABLE_TIMELINE_FRAMES = RNExperimentName.ENABLE_TIMELINE_FRAMES, } From 6ac687da719a7312f6fd70fca1bc4c52e0f7301d Mon Sep 17 00:00:00 2001 From: devan Date: Wed, 12 Nov 2025 18:36:39 -0800 Subject: [PATCH 8/8] Add back frames track if not RN --- .../panels/timeline/TimelineFlameChartDataProvider.ts | 9 ++++++++- front_end/testing/EnvironmentHelpers.ts | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts index 6826abe4e934..0e11347f5913 100644 --- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts @@ -106,6 +106,8 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectWrapper implements PerfUI.FlameChart.FlameChartDataProvider { + private isReactNative = false; + private droppedFramePatternCanvas: HTMLCanvasElement; private partialFramePatternCanvas: HTMLCanvasElement; private timelineDataInternal: PerfUI.FlameChart.FlameChartTimelineData|null = null; @@ -143,6 +145,11 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW constructor() { super(); + // [RN] Used to scope down available features for React Native targets + this.isReactNative = Root.Runtime.experiments.isEnabled( + Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, + ); + this.reset(); this.droppedFramePatternCanvas = document.createElement('canvas'); @@ -608,7 +615,7 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW // In CPU Profiles the trace data will not have frames nor // screenshots, so we can keep this call as it will be a no-op in // these cases. - if (Root.Runtime.experiments.isEnabled(Root.Runtime.RNExperimentName.ENABLE_TIMELINE_FRAMES)) { + if (Root.Runtime.experiments.isEnabled(Root.Runtime.RNExperimentName.ENABLE_TIMELINE_FRAMES) || !this.isReactNative) { this.#appendFramesAndScreenshotsTrack(); } diff --git a/front_end/testing/EnvironmentHelpers.ts b/front_end/testing/EnvironmentHelpers.ts index cc0af871c944..211940a69fdc 100644 --- a/front_end/testing/EnvironmentHelpers.ts +++ b/front_end/testing/EnvironmentHelpers.ts @@ -130,6 +130,7 @@ const REGISTERED_EXPERIMENTS = [ Root.Runtime.ExperimentName.TIMELINE_ALTERNATIVE_NAVIGATION, Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, Root.Runtime.ExperimentName.NOT_REACT_NATIVE_SPECIFIC_UI, + Root.Runtime.ExperimentName.ENABLE_TIMELINE_FRAMES, ]; export async function initializeGlobalVars({reset = true} = {}) {