Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[web_benchmarks] migrate to pkg:web #5592

Merged
merged 4 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/web_benchmarks/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.1.0+11

* Migrates benchmark recorder from `dart:html` to `package:web` to support WebAssembly.

## 0.1.0+10

* Ensure the benchmark client reloads with the proper `initialPage`.
Expand Down
67 changes: 37 additions & 30 deletions packages/web_benchmarks/lib/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

import 'dart:async';
import 'dart:convert' show json;
import 'dart:html' as html;
import 'dart:js_interop';
import 'dart:math' as math;

import 'package:web/helpers.dart' as html;
kevmoo marked this conversation as resolved.
Show resolved Hide resolved

import 'src/common.dart';
import 'src/recorder.dart';

export 'src/recorder.dart';

/// Signature for a function that creates a [Recorder].
Expand Down Expand Up @@ -127,33 +130,32 @@ void _fallbackToManual(String error) {
${_benchmarks.keys.map((String name) => '<li><button id="$name">$name</button></li>').join('\n')}
</ul>
</div>
''',
validator: html.NodeValidatorBuilder()
..allowHtml5()
..allowInlineStyles());
''');

kevmoo marked this conversation as resolved.
Show resolved Hide resolved
for (final String benchmarkName in _benchmarks.keys) {
// Find the button elements added above.
final html.Element button = html.document.querySelector('#$benchmarkName')!;
button.addEventListener('click', (_) {
final html.Element? manualPanel =
html.document.querySelector('#manual-panel');
manualPanel?.remove();
_runBenchmark(benchmarkName);
});
button.addEventListener(
'click',
(JSAny? arg) {
final html.Element? manualPanel =
html.document.querySelector('#manual-panel');
manualPanel?.remove();
_runBenchmark(benchmarkName);
}.toJS);
}
}

/// Visualizes results on the Web page for manual inspection.
void _printResultsToScreen(Profile profile) {
final html.BodyElement body = html.document.body!;
final html.HTMLBodyElement body = html.document.body! as html.HTMLBodyElement;

body.innerHtml = '<h2>${profile.name}</h2>';
body.innerHTML = '<h2>${profile.name}</h2>';

profile.scoreData.forEach((String scoreKey, Timeseries timeseries) {
body.appendHtml('<h2>$scoreKey</h2>');
body.appendHtml('<pre>${timeseries.computeStats()}</pre>');
body.append(TimeseriesVisualization(timeseries).render());
body.append(TimeseriesVisualization(timeseries).render() as JSObject);
});
}

Expand All @@ -163,7 +165,7 @@ class TimeseriesVisualization {
TimeseriesVisualization(this._timeseries) {
_stats = _timeseries.computeStats();
_canvas = html.CanvasElement();
_screenWidth = html.window.screen!.width!;
_screenWidth = html.window.screen.width;
_canvas.width = _screenWidth;
_canvas.height = (_kCanvasHeight * html.window.devicePixelRatio).round();
_canvas.style
Expand Down Expand Up @@ -220,19 +222,19 @@ class TimeseriesVisualization {

if (sample.isWarmUpValue) {
// Put gray background behind warm-up samples.
_ctx.fillStyle = 'rgba(200,200,200,1)';
_ctx.fillStyle = 'rgba(200,200,200,1)'.toJS;
_ctx.fillRect(xOffset, 0, barWidth, _normalized(_maxValueChartRange));
}

if (sample.magnitude > _maxValueChartRange) {
// The sample value is so big it doesn't fit on the chart. Paint it purple.
_ctx.fillStyle = 'rgba(100,50,100,0.8)';
_ctx.fillStyle = 'rgba(100,50,100,0.8)'.toJS;
} else if (sample.isOutlier) {
// The sample is an outlier, color it light red.
_ctx.fillStyle = 'rgba(255,50,50,0.6)';
_ctx.fillStyle = 'rgba(255,50,50,0.6)'.toJS;
} else {
// A non-outlier sample, color it light blue.
_ctx.fillStyle = 'rgba(50,50,255,0.6)';
_ctx.fillStyle = 'rgba(50,50,255,0.6)'.toJS;
}

_ctx.fillRect(xOffset, 0, barWidth - 1, _normalized(sample.magnitude));
Expand All @@ -245,12 +247,12 @@ class TimeseriesVisualization {
_normalized(_stats.average));

// Draw a horizontal dashed line corresponding to the outlier cut off.
_ctx.setLineDash(<num>[5, 5]);
_ctx.setLineDash(<JSNumber>[5.toJS, 5.toJS].toJS);
drawLine(0, _normalized(_stats.outlierCutOff), _screenWidth,
_normalized(_stats.outlierCutOff));

// Draw a light red band that shows the noise (1 stddev in each direction).
_ctx.fillStyle = 'rgba(255,50,50,0.3)';
_ctx.fillStyle = 'rgba(255,50,50,0.3)'.toJS;
_ctx.fillRect(
0,
_normalized(_stats.average * (1 - _stats.noise)),
Expand Down Expand Up @@ -283,7 +285,7 @@ class LocalBenchmarkServerClient {
/// Returns [kManualFallback] if local server is not available (uses 404 as a
/// signal).
Future<String> requestNextBenchmark() async {
final html.HttpRequest request = await _requestXhr(
final html.XMLHttpRequest request = await _requestXhr(
'/next-benchmark',
method: 'POST',
mimeType: 'application/json',
Expand All @@ -298,7 +300,7 @@ class LocalBenchmarkServerClient {
}

isInManualMode = false;
return request.responseText ?? kManualFallback;
return request.responseText;
}

void _checkNotManualMode() {
Expand Down Expand Up @@ -335,7 +337,7 @@ class LocalBenchmarkServerClient {
/// server.
Future<void> sendProfileData(Profile profile) async {
_checkNotManualMode();
final html.HttpRequest request = await html.HttpRequest.request(
final html.XMLHttpRequest request = await _requestXhr(
'/profile-data',
method: 'POST',
mimeType: 'application/json',
Expand Down Expand Up @@ -376,21 +378,26 @@ class LocalBenchmarkServerClient {

/// This is the same as calling [html.HttpRequest.request] but it doesn't
/// crash on 404, which we use to detect `flutter run`.
Future<html.HttpRequest> _requestXhr(
Future<html.XMLHttpRequest> _requestXhr(
String url, {
required String method,
required String mimeType,
required dynamic sendData,
required String sendData,
}) {
final Completer<html.HttpRequest> completer = Completer<html.HttpRequest>();
final html.HttpRequest xhr = html.HttpRequest();
xhr.open(method, url, async: true);
final Completer<html.XMLHttpRequest> completer =
Completer<html.XMLHttpRequest>();
final html.XMLHttpRequest xhr = html.XMLHttpRequest();
xhr.open(method, url, true);
xhr.overrideMimeType(mimeType);
xhr.onLoad.listen((html.ProgressEvent e) {
completer.complete(xhr);
});
xhr.onError.listen(completer.completeError);
xhr.send(sendData);
xhr.send(sendData.toJS);
return completer.future;
}
}

extension on html.HTMLElement {
void appendHtml(String input) => insertAdjacentHTML('beforeend', input);
}
5 changes: 3 additions & 2 deletions packages/web_benchmarks/lib/src/recorder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:html' as html;
import 'dart:js_interop';
import 'dart:math' as math;
import 'dart:ui';
import 'dart:ui_web' as ui_web;
Expand All @@ -15,6 +15,7 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
import 'package:web/helpers.dart' as html;

import 'common.dart';

Expand Down Expand Up @@ -1188,7 +1189,7 @@ void endMeasureFrame() {
html.window.performance.mark('measured_frame_end#$_currentFrameNumber');
html.window.performance.measure(
'measured_frame',
'measured_frame_start#$_currentFrameNumber',
'measured_frame_start#$_currentFrameNumber'.toJS,
'measured_frame_end#$_currentFrameNumber',
);

Expand Down
3 changes: 2 additions & 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: 0.1.0+10
version: 0.1.0+11

environment:
sdk: ">=3.2.0 <4.0.0"
Expand All @@ -20,6 +20,7 @@ dependencies:
shelf: ^1.2.0
shelf_static: ^1.1.0
test: ^1.19.5
web: '>=0.3.0 <0.5.0'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the <0.5.0 constraint?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we capture both v0.3.0 and v0.4.0

Because stable pins one version and dev pins the other

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<1.0.0 would also capture 0.4.0, right? And it would also be less sensitive to version constraints in adjacent packages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we're not sure about what we're doing in 0.5.0+ This is a "good" range for things we've tested.

webkit_inspection_protocol: ^1.0.0

topics:
Expand Down
2 changes: 1 addition & 1 deletion packages/web_benchmarks/testing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ do the following:
* Fetch dependencies for the `test_app` directory inside `testing`:

```bash
flutter pub get testing/test_app
flutter pub get --directory testing/test_app
```

* Fetch dependencies for the `web_benchmarks` directory:
Expand Down
3 changes: 0 additions & 3 deletions packages/web_benchmarks/testing/test_app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
.pub/
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

Expand Down