From 30b8eb635bd4e85bf70faccdb2f7a23608173aed Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Mon, 10 Feb 2025 13:29:35 -0800 Subject: [PATCH] Change the default optimization level to `-O2` for wasm in release mode. (#162917) As per the investigation in https://github.com/flutter/flutter/issues/162620, we determined that the soundness we gain from using `-O2` outweighs the perf benefits of `-O4`. --- .../lib/src/web/compiler_config.dart | 39 ++++++++++++------- .../build_system/targets/web_test.dart | 11 +++++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/packages/flutter_tools/lib/src/web/compiler_config.dart b/packages/flutter_tools/lib/src/web/compiler_config.dart index 63b38ffaf5f..627086d5f8c 100644 --- a/packages/flutter_tools/lib/src/web/compiler_config.dart +++ b/packages/flutter_tools/lib/src/web/compiler_config.dart @@ -21,15 +21,9 @@ sealed class WebCompilerConfig { /// Build environment flag for [sourceMaps]. static const String kSourceMapsEnabled = 'SourceMaps'; - /// Calculates the optimization level for dart2js/dart2wasm for the given + /// Calculates the optimization level for the compiler for the given /// build mode. - int optimizationLevelForBuildMode(BuildMode mode) => - optimizationLevel ?? - switch (mode) { - BuildMode.debug => 0, - BuildMode.profile || BuildMode.release => 4, - BuildMode.jitRelease => throw ArgumentError('Invalid build mode for web'), - }; + int optimizationLevelForBuildMode(BuildMode mode); /// The compiler optimization level specified by the user. /// @@ -111,13 +105,15 @@ class JsCompilerConfig extends WebCompilerConfig { ]; @override - int optimizationLevelForBuildMode(BuildMode mode) { - final int level = super.optimizationLevelForBuildMode(mode); - - // dart2js optimization level 0 is not well supported. Use - // 1 instead. - return level == 0 ? 1 : level; - } + int optimizationLevelForBuildMode(BuildMode mode) => + optimizationLevel ?? + switch (mode) { + // dart2js optimization level 0 is not well supported. Use + // 1 instead. + BuildMode.debug => 1, + BuildMode.profile || BuildMode.release => 4, + BuildMode.jitRelease => throw ArgumentError('Invalid build mode for web'), + }; /// Arguments to use in the full JS compile, but not CFE-only. /// @@ -163,6 +159,19 @@ class WasmCompilerConfig extends WebCompilerConfig { @override CompileTarget get compileTarget => CompileTarget.wasm; + @override + int optimizationLevelForBuildMode(BuildMode mode) => + optimizationLevel ?? + switch (mode) { + BuildMode.debug => 0, + + // The optimization level of O2 uses only sound optimizations. We default + // to this level because our web benchmarks have shown that the difference + // between O2 and O4 is marginal enough that we would prefer soundness here. + BuildMode.profile || BuildMode.release => 2, + BuildMode.jitRelease => throw ArgumentError('Invalid build mode for web'), + }; + List toCommandOptions(BuildMode buildMode) { final bool stripSymbols = buildMode == BuildMode.release && stripWasm; return [ diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart index c7dd8c29b0f..dd4d3c1a3f8 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart @@ -1140,7 +1140,7 @@ void main() { WebRendererMode.canvaskit, WebRendererMode.skwasm, ]) { - for (int level = 1; level <= 4; level++) { + for (final int? level in [null, 0, 1, 2, 3, 4]) { for (final bool strip in [true, false]) { for (final List defines in const >[ [], @@ -1151,6 +1151,13 @@ void main() { test( 'Dart2WasmTarget invokes dart2wasm with renderer=$renderer, -O$level, stripping=$strip, defines=$defines, modeMode=$buildMode sourceMaps=$sourceMaps', () => testbed.run(() async { + final int expectedLevel = + level ?? + switch (buildMode) { + 'debug' => 0, + 'profile' || 'release' => 2, + _ => throw UnimplementedError(), + }; environment.defines[kBuildMode] = buildMode; environment.defines[kDartDefines] = encodeDartDefines(defines); @@ -1182,7 +1189,7 @@ void main() { ], '-DFLUTTER_WEB_CANVASKIT_URL=https://www.gstatic.com/flutter-canvaskit/abcdefghijklmnopqrstuvwxyz/', '--extra-compiler-option=--depfile=${depFile.absolute.path}', - '-O$level', + '-O$expectedLevel', if (strip && buildMode == 'release') '--strip-wasm' else '--no-strip-wasm', if (!sourceMaps) '--no-source-maps', if (buildMode == 'debug') '--extra-compiler-option=--enable-asserts',