From 50fab31ff449baf063859819809bffe425f46077 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:27:23 -0800 Subject: [PATCH 1/3] Fix ?compiler=js escape hatch --- .../lib/src/shared/analytics/constants.dart | 4 +++ .../src/shared/preferences/preferences.dart | 27 ++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/packages/devtools_app/lib/src/shared/analytics/constants.dart b/packages/devtools_app/lib/src/shared/analytics/constants.dart index 68ca5b59077..45450f842d9 100644 --- a/packages/devtools_app/lib/src/shared/analytics/constants.dart +++ b/packages/devtools_app/lib/src/shared/analytics/constants.dart @@ -57,6 +57,10 @@ const memoryPressureReduce = 'memoryPressureReduce'; /// Wasm. const jsFallback = 'jsFallback'; +/// Event that signals we forced the dart2js compiler via the compiler=js query +/// parameter. +const forceLoadJs = 'forceLoadJs'; + // DevTools UI action selected (clicked). // Main bar UX actions: diff --git a/packages/devtools_app/lib/src/shared/preferences/preferences.dart b/packages/devtools_app/lib/src/shared/preferences/preferences.dart index d1ae1de01de..5471aa83f3e 100644 --- a/packages/devtools_app/lib/src/shared/preferences/preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/preferences.dart @@ -42,7 +42,14 @@ enum _ExperimentPreferences { /// Whether a user has opted out of the dart2wasm experiment. wasmOptOut; - String get storageKey => '$storagePrefix.$name'; + String get storageKey { + if (name == 'wasm') { + _log.warning( + '[deprecated] The $wasm key is deprecated, use $wasmOptOut instead.', + ); + } + return '$storagePrefix.$name'; + } static const storagePrefix = 'experiment'; } @@ -180,13 +187,16 @@ class PreferencesController extends DisposableController Future _initWasmEnabled() async { wasmEnabled.value = kIsWasm; + final queryParams = DevToolsQueryParams.load(); // If the user forced the dart2js-compiled DevTools via query parameter, // then set the storage value to match. This will persist across multiple // sessions of DevTools. - if (DevToolsQueryParams.load().useJs) { + final jsEnabledFromQueryParams = queryParams.useJs; + if (jsEnabledFromQueryParams) { safeUnawaited( - storage.setValue(_ExperimentPreferences.wasm.storageKey, 'false'), + storage.setValue(_ExperimentPreferences.wasmOptOut.storageKey, 'true'), ); + ga.impression(gac.devToolsMain, gac.forceLoadJs); } addAutoDisposeListener(wasmEnabled, () async { @@ -217,12 +227,10 @@ class PreferencesController extends DisposableController _ExperimentPreferences.wasmOptOut.storageKey, defaultsTo: false, ); - final enabledFromStorage = !optOutFromStorage; - - final queryParams = DevToolsQueryParams.load(); - final enabledFromQueryParams = queryParams.useWasm; + final wasmEnabledFromStorage = !optOutFromStorage; + final wasmEnabledFromQueryParams = queryParams.useWasm; - if (enabledFromQueryParams && !kIsWasm) { + if (wasmEnabledFromQueryParams && !kIsWasm) { // If we hit this case, we tried to load DevTools with WASM but we fell // back to JS. We know this because the flutter_bootstrap.js logic always // sets the 'wasm' query parameter to 'true' when attempting to load @@ -246,7 +254,8 @@ class PreferencesController extends DisposableController } final shouldEnableWasm = - (enabledFromStorage || enabledFromQueryParams) && + (wasmEnabledFromStorage || wasmEnabledFromQueryParams) && + !jsEnabledFromQueryParams && kIsWeb && // Wasm cannot be enabled if DevTools was built using `flutter run`. !usingDebugDevToolsServer; From c5ca46225113b013537d892eda5db5e9af14716e Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:29:31 -0800 Subject: [PATCH 2/3] Clean up --- .../lib/src/shared/preferences/preferences.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/devtools_app/lib/src/shared/preferences/preferences.dart b/packages/devtools_app/lib/src/shared/preferences/preferences.dart index 5471aa83f3e..afb0cee8193 100644 --- a/packages/devtools_app/lib/src/shared/preferences/preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/preferences.dart @@ -227,10 +227,10 @@ class PreferencesController extends DisposableController _ExperimentPreferences.wasmOptOut.storageKey, defaultsTo: false, ); - final wasmEnabledFromStorage = !optOutFromStorage; - final wasmEnabledFromQueryParams = queryParams.useWasm; + final enabledFromStorage = !optOutFromStorage; + final enabledFromQueryParams = queryParams.useWasm; - if (wasmEnabledFromQueryParams && !kIsWasm) { + if (enabledFromQueryParams && !kIsWasm) { // If we hit this case, we tried to load DevTools with WASM but we fell // back to JS. We know this because the flutter_bootstrap.js logic always // sets the 'wasm' query parameter to 'true' when attempting to load @@ -254,7 +254,7 @@ class PreferencesController extends DisposableController } final shouldEnableWasm = - (wasmEnabledFromStorage || wasmEnabledFromQueryParams) && + (enabledFromStorage || enabledFromQueryParams) && !jsEnabledFromQueryParams && kIsWeb && // Wasm cannot be enabled if DevTools was built using `flutter run`. From f105970de2cb2d4340c669ec77596838b11ddb8e Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:31:01 -0800 Subject: [PATCH 3/3] Update warning message --- .../devtools_app/lib/src/shared/preferences/preferences.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/shared/preferences/preferences.dart b/packages/devtools_app/lib/src/shared/preferences/preferences.dart index afb0cee8193..06ee38c5f8b 100644 --- a/packages/devtools_app/lib/src/shared/preferences/preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/preferences.dart @@ -45,7 +45,7 @@ enum _ExperimentPreferences { String get storageKey { if (name == 'wasm') { _log.warning( - '[deprecated] The $wasm key is deprecated, use $wasmOptOut instead.', + '[deprecated] The "wasm" key is deprecated, use "wasmOptOut" instead.', ); } return '$storagePrefix.$name';