diff --git a/packages/web_benchmarks/CHANGELOG.md b/packages/web_benchmarks/CHANGELOG.md index 9acd4517ab2..b70677fb31b 100644 --- a/packages/web_benchmarks/CHANGELOG.md +++ b/packages/web_benchmarks/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.0.0 + +* **Breaking change:** replace the `useCanvasKit` parameter in the `serveWebBenchmark` +method with a new parameter `compilationOptions`, which allows you to: + * specify the web renderer to use for the benchmark app (html, canvaskit, or skwasm) + * specify whether to use WebAssembly to build the benchmark app +* **Breaking change:** `serveWebBenchmark` now uses `canvaskit` instead of `html` as the +default web renderer. + ## 0.1.0+11 * Migrates benchmark recorder from `dart:html` to `package:web` to support WebAssembly. diff --git a/packages/web_benchmarks/lib/client.dart b/packages/web_benchmarks/lib/client.dart index 6f64d048995..baaab84fe50 100644 --- a/packages/web_benchmarks/lib/client.dart +++ b/packages/web_benchmarks/lib/client.dart @@ -53,15 +53,18 @@ Future runBenchmarks( final Uri currentUri = Uri.parse(window.location.href); // Create a new URI with the current 'page' value set to [initialPage] to // ensure the benchmark app is reloaded at the proper location. - final Uri newUri = Uri( + final String newUri = Uri( scheme: currentUri.scheme, host: currentUri.host, port: currentUri.port, path: initialPage, - ); + ).toString(); // Reloading the window will trigger the next benchmark to run. - window.location.replace(newUri.toString()); + await _client.printToConsole( + 'Client preparing to reload the window to: "$newUri"', + ); + window.location.replace(newUri); } Future _runBenchmark(String? benchmarkName) async { diff --git a/packages/web_benchmarks/lib/server.dart b/packages/web_benchmarks/lib/server.dart index 41ae7623ec9..1742ac507c9 100644 --- a/packages/web_benchmarks/lib/server.dart +++ b/packages/web_benchmarks/lib/server.dart @@ -9,9 +9,11 @@ import 'package:logging/logging.dart'; import 'src/benchmark_result.dart'; import 'src/common.dart'; +import 'src/compilation_options.dart'; import 'src/runner.dart'; export 'src/benchmark_result.dart'; +export 'src/compilation_options.dart'; /// The default port number used by the local benchmark server. const int defaultBenchmarkServerPort = 9999; @@ -43,12 +45,12 @@ const int defaultChromeDebugPort = 10000; Future serveWebBenchmark({ required io.Directory benchmarkAppDirectory, required String entryPoint, - required bool useCanvasKit, int benchmarkServerPort = defaultBenchmarkServerPort, int chromeDebugPort = defaultChromeDebugPort, bool headless = true, bool treeShakeIcons = true, String initialPage = defaultInitialPage, + CompilationOptions compilationOptions = const CompilationOptions(), }) async { // Reduce logging level. Otherwise, package:webkit_inspection_protocol is way too spammy. Logger.root.level = Level.INFO; @@ -56,10 +58,10 @@ Future serveWebBenchmark({ return BenchmarkServer( benchmarkAppDirectory: benchmarkAppDirectory, entryPoint: entryPoint, - useCanvasKit: useCanvasKit, benchmarkServerPort: benchmarkServerPort, chromeDebugPort: chromeDebugPort, headless: headless, + compilationOptions: compilationOptions, treeShakeIcons: treeShakeIcons, initialPage: initialPage, ).run(); diff --git a/packages/web_benchmarks/lib/src/compilation_options.dart b/packages/web_benchmarks/lib/src/compilation_options.dart new file mode 100644 index 00000000000..3a994703c63 --- /dev/null +++ b/packages/web_benchmarks/lib/src/compilation_options.dart @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Compilation options for bulding a Flutter web app. +/// +/// This object holds metadata that is used to determine how the benchmark app +/// should be built. +class CompilationOptions { + /// Creates a [CompilationOptions] object. + const CompilationOptions({ + this.renderer = WebRenderer.canvaskit, + this.useWasm = false, + }); + + /// The renderer to use for the build. + final WebRenderer renderer; + + /// Whether to build the app with dart2wasm. + final bool useWasm; + + @override + String toString() { + return '(renderer: ${renderer.name}, compiler: ${useWasm ? 'dart2wasm' : 'dart2js'})'; + } +} + +/// The possible types of web renderers Flutter can build for. +enum WebRenderer { + /// The HTML web renderer. + html, + + /// The CanvasKit web renderer. + canvaskit, + + /// The SKIA Wasm web renderer. + skwasm, +} diff --git a/packages/web_benchmarks/lib/src/runner.dart b/packages/web_benchmarks/lib/src/runner.dart index 9396f42ebc3..8eeaeb0617a 100644 --- a/packages/web_benchmarks/lib/src/runner.dart +++ b/packages/web_benchmarks/lib/src/runner.dart @@ -18,6 +18,7 @@ import 'package:shelf_static/shelf_static.dart'; import 'benchmark_result.dart'; import 'browser.dart'; import 'common.dart'; +import 'compilation_options.dart'; /// The default port number used by the local benchmark server. const int defaultBenchmarkServerPort = 9999; @@ -50,11 +51,11 @@ class BenchmarkServer { BenchmarkServer({ required this.benchmarkAppDirectory, required this.entryPoint, - required this.useCanvasKit, required this.benchmarkServerPort, required this.chromeDebugPort, required this.headless, required this.treeShakeIcons, + this.compilationOptions = const CompilationOptions(), this.initialPage = defaultInitialPage, }); @@ -72,8 +73,8 @@ class BenchmarkServer { /// the app. final String entryPoint; - /// Whether to build the app in CanvasKit mode. - final bool useCanvasKit; + /// The compilation options to use for building the benchmark web app. + final CompilationOptions compilationOptions; /// The port this benchmark server serves the app on. final int benchmarkServerPort; @@ -109,13 +110,20 @@ class BenchmarkServer { "flutter executable is not runnable. Make sure it's in the PATH."); } + final DateTime startTime = DateTime.now(); + print('Building Flutter web app $compilationOptions...'); final io.ProcessResult buildResult = await _processManager.run( [ 'flutter', 'build', 'web', + if (compilationOptions.useWasm) ...[ + '--wasm', + '--wasm-opt=debug', + '--omit-type-checks', + ], + '--web-renderer=${compilationOptions.renderer.name}', '--dart-define=FLUTTER_WEB_ENABLE_PROFILING=true', - if (useCanvasKit) '--dart-define=FLUTTER_WEB_USE_SKIA=true', if (!treeShakeIcons) '--no-tree-shake-icons', '--profile', '-t', @@ -124,6 +132,12 @@ class BenchmarkServer { workingDirectory: benchmarkAppDirectory.path, ); + final int buildTime = Duration( + milliseconds: DateTime.now().millisecondsSinceEpoch - + startTime.millisecondsSinceEpoch, + ).inSeconds; + print('Build took ${buildTime}s to complete.'); + if (buildResult.exitCode != 0) { io.stderr.writeln(buildResult.stdout); io.stderr.writeln(buildResult.stderr); diff --git a/packages/web_benchmarks/pubspec.yaml b/packages/web_benchmarks/pubspec.yaml index e9e1791bd75..c0222abe91c 100644 --- a/packages/web_benchmarks/pubspec.yaml +++ b/packages/web_benchmarks/pubspec.yaml @@ -2,7 +2,7 @@ name: web_benchmarks description: A benchmark harness for performance-testing Flutter apps in Chrome. repository: https://github.com/flutter/packages/tree/main/packages/web_benchmarks issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+web_benchmarks%22 -version: 0.1.0+11 +version: 1.0.0 environment: sdk: ">=3.2.0 <4.0.0" diff --git a/packages/web_benchmarks/testing/web_benchmarks_test.dart b/packages/web_benchmarks/testing/web_benchmarks_test.dart index 5d005e2afc7..4a3ffa35169 100644 --- a/packages/web_benchmarks/testing/web_benchmarks_test.dart +++ b/packages/web_benchmarks/testing/web_benchmarks_test.dart @@ -25,19 +25,28 @@ Future main() async { initialPage: 'index.html#about', ); }, timeout: Timeout.none); + + test('Can run a web benchmark with wasm', () async { + await _runBenchmarks( + benchmarkNames: ['simple'], + entryPoint: 'lib/benchmarks/runner_simple.dart', + compilationOptions: const CompilationOptions(useWasm: true), + ); + }, timeout: Timeout.none); } Future _runBenchmarks({ required List benchmarkNames, required String entryPoint, String initialPage = defaultInitialPage, + CompilationOptions compilationOptions = const CompilationOptions(), }) async { final BenchmarkResults taskResult = await serveWebBenchmark( benchmarkAppDirectory: Directory('testing/test_app'), entryPoint: entryPoint, - useCanvasKit: false, treeShakeIcons: false, initialPage: initialPage, + compilationOptions: compilationOptions, ); for (final String benchmarkName in benchmarkNames) {