Skip to content

Commit

Permalink
Serve benchmarks with COOP/COEP headers in wasm mode. (flutter#7423)
Browse files Browse the repository at this point in the history
We need `crossOriginIsolated` for skwasm to work. Otherwise, this just falls back and benchmarks JS + canvaskit.
  • Loading branch information
eyebrowsoffire authored Aug 22, 2024
1 parent 50e4138 commit d862279
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 13 deletions.
5 changes: 4 additions & 1 deletion packages/web_benchmarks/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## NEXT
## 2.0.2

* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
* Updates benchmark server to serve the app as `crossOriginIsolated`. This
allows us access to high precision timers and allows wasm benchmarks to run
properly as well.

## 2.0.1

Expand Down
20 changes: 18 additions & 2 deletions packages/web_benchmarks/lib/src/runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,26 @@ class BenchmarkServer {
Cascade cascade = Cascade();

// Serves the static files built for the app (html, js, images, fonts, etc)
cascade = cascade.add(createStaticHandler(
final Handler buildFolderHandler = createStaticHandler(
path.join(benchmarkAppDirectory.path, 'build', 'web'),
defaultDocument: 'index.html',
));
);
// We want our page to be crossOriginIsolated. This will allow us to run the
// skwasm renderer, which uses a SharedArrayBuffer, which requires the page
// to be crossOriginIsolated. But also, even in the non-skwasm case, running
// in crossOriginIsolated gives us access to more accurate timers which are
// useful for capturing good benchmarking data.
// See https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/High_precision_timing#reduced_precision
cascade = cascade.add((Request request) async {
final Response response = await buildFolderHandler(request);
if (response.mimeType == 'text/html') {
return response.change(headers: <String, String>{
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
});
}
return response;
});

// Serves the benchmark server API used by the benchmark app to coordinate
// the running of benchmarks.
Expand Down
2 changes: 1 addition & 1 deletion packages/web_benchmarks/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: 2.0.1
version: 2.0.2

environment:
sdk: ^3.3.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:web_benchmarks/client.dart';

Expand All @@ -12,7 +13,11 @@ class SimpleRecorder extends AppRecorder {

@override
Future<void> automate() async {
// Do nothing.
// Record whether we are in wasm mode or not. Ideally, we'd have a more
// first-class way to add metadata like this, but this will work for us to
// pass information about the environment back to the server for the
// purposes of our own tests.
profile.extraData['isWasm'] = kIsWasm ? 1 : 0;
}
}

Expand Down
40 changes: 32 additions & 8 deletions packages/web_benchmarks/testing/web_benchmarks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,45 @@ Future<void> main() async {
}, timeout: Timeout.none);

test('Can run a web benchmark with an alternate initial page', () async {
await _runBenchmarks(
final BenchmarkResults results = await _runBenchmarks(
benchmarkNames: <String>['simple'],
entryPoint: 'lib/benchmarks/runner_simple.dart',
initialPage: 'index.html#about',
);

// The simple runner just puts an `isWasm` metric in there so we can make
// sure that we're running in the right environment.
final List<BenchmarkScore>? scores = results.scores['simple'];
expect(scores, isNotNull);

final BenchmarkScore isWasmScore =
scores!.firstWhere((BenchmarkScore score) => score.metric == 'isWasm');
expect(isWasmScore.value, 0);
}, timeout: Timeout.none);

test(
'Can run a web benchmark with wasm',
() async {
await _runBenchmarks(
final BenchmarkResults results = await _runBenchmarks(
benchmarkNames: <String>['simple'],
entryPoint: 'lib/benchmarks/runner_simple.dart',
compilationOptions: const CompilationOptions.wasm(),
);

// The simple runner just puts an `isWasm` metric in there so we can make
// sure that we're running in the right environment.
final List<BenchmarkScore>? scores = results.scores['simple'];
expect(scores, isNotNull);

final BenchmarkScore isWasmScore = scores!
.firstWhere((BenchmarkScore score) => score.metric == 'isWasm');
expect(isWasmScore.value, 1);
},
timeout: Timeout.none,
);
}

Future<void> _runBenchmarks({
Future<BenchmarkResults> _runBenchmarks({
required List<String> benchmarkNames,
required String entryPoint,
String initialPage = defaultInitialPage,
Expand All @@ -53,12 +71,17 @@ Future<void> _runBenchmarks({
compilationOptions: compilationOptions,
);

// The skwasm renderer doesn't have preroll or apply frame steps in its rendering.
final List<String> expectedMetrics = compilationOptions.useWasm
? <String>['drawFrameDuration']
: <String>[
'preroll_frame',
'apply_frame',
'drawFrameDuration',
];

for (final String benchmarkName in benchmarkNames) {
for (final String metricName in <String>[
'preroll_frame',
'apply_frame',
'drawFrameDuration',
]) {
for (final String metricName in expectedMetrics) {
for (final String valueName in <String>[
'average',
'outlierAverage',
Expand All @@ -83,4 +106,5 @@ Future<void> _runBenchmarks({
const JsonEncoder.withIndent(' ').convert(taskResult.toJson()),
isA<String>(),
);
return taskResult;
}

0 comments on commit d862279

Please sign in to comment.