add docs about writing/running web benchmarks (#50989)
* add docs about writing/running web benchmarks
* explain how to run like devicelab
* add WidgetBuildRecorder docs
diff --git a/dev/benchmarks/macrobenchmarks/README.md b/dev/benchmarks/macrobenchmarks/README.md
index d8bbe9f..2e2c4a0 100644
--- a/dev/benchmarks/macrobenchmarks/README.md
+++ b/dev/benchmarks/macrobenchmarks/README.md
@@ -1,8 +1,10 @@
# Macrobenchmarks
-Performance benchmarks using flutter drive.
+Performance benchmarks use either flutter drive or the web benchmark harness.
-## Cull opacity benchmark
+## Mobile benchmarks
+
+### Cull opacity benchmark
To run the cull opacity benchmark on a device:
@@ -14,7 +16,7 @@
More detailed logs should be in `build/cull_opacity_perf.timeline.json`.
-## Cubic bezier benchmark
+### Cubic bezier benchmark
To run the cubic bezier benchmark on a device:
@@ -26,7 +28,7 @@
More detailed logs should be in `build/cubic_bezier_perf.timeline.json`.
-## Backdrop filter benchmark
+### Backdrop filter benchmark
To run the backdrop filter benchmark on a device:
@@ -38,7 +40,7 @@
More detailed logs should be in `build/backdrop_filter_perf.timeline.json`.
-## Post Backdrop filter benchmark
+### Post Backdrop filter benchmark
To run the post-backdrop filter benchmark on a device:
@@ -49,3 +51,70 @@
Results should be in the file `build/post_backdrop_filter_perf.timeline_summary.json`.
More detailed logs should be in `build/post_backdrop_filter_perf.timeline.json`.
+
+## Web benchmarks
+
+Web benchmarks are compiled from the same entrypoint in `lib/web_benchmarks.dart`.
+
+### How to write a web benchmark
+
+Create a new file for your benchmark under `lib/src/web`. See `bench_draw_rect.dart`
+as an example.
+
+Choose one of the two benchmark types:
+
+* A "raw benchmark" records performance metrics from direct interactions with
+ `dart:ui` with no framework. This kind of benchmark is good for benchmarking
+ low-level engine primitives, such as layer, picture, and semantics performance.
+* A "widget benchmark" records performance metrics using a widget. This kind of
+ benchmark is good for measuring the performance of widgets, often together with
+ engine work that widget-under-test incurs.
+* A "widget build benchmark" records the cost of building a widget from nothing.
+ This is different from the "widget benchmark" because typically the latter
+ only performs incremental UI updates, such as an animation. In contrast, this
+ benchmark pumps an empty frame to clear all previously built widgets and
+ rebuilds them from scratch.
+
+For a raw benchmark extend `RawRecorder` (tip: you can start by copying
+`bench_draw_rect.dart`).
+
+For a widget benchmark extend `WidgetRecorder` (tip: you can start by copying
+`bench_simple_lazy_text_scroll.dart`).
+
+For a widget build benchmark extend `WidgetBuildRecorder` (tip: you can start by copying
+`bench_build_material_checkbox.dart`).
+
+Pick a unique benchmark name and class name and add it to the `benchmarks` list
+in `lib/web_benchmarks.dart`.
+
+### How to run a web benchmark
+
+Web benchmarks can be run using `flutter run` in debug, profile, and release
+modes, using either the HTML or the CanvasKit rendering backend. Note, however,
+that running in debug mode will result in worse numbers. Profile mode is useful
+for profiling in Chrome DevTools because the numbers are close to release mode
+and the profile contains unobfuscated names.
+
+Example:
+
+```
+cd dev/benchmarks/macrobenchmarks
+
+# Runs in profile mode using the HTML renderer
+flutter run --profile -d web-server lib/web_benchmarks.dart
+
+# Runs in profile mode using the CanvasKit renderer
+flutter run --dart-define=FLUTTER_WEB_USE_SKIA=true --profile -d web-server lib/web_benchmarks.dart
+```
+
+You can also run all benchmarks exactly like the devicelab runs them:
+
+```
+cd dev/devicelab
+
+# Runs using the HTML renderer
+../../bin/cache/dart-sdk/bin/dart bin/run.dart -t bin/tasks/web_benchmarks_html.dart
+
+# Runs using the CanvasKit renderer
+../../bin/cache/dart-sdk/bin/dart bin/run.dart -t bin/tasks/web_benchmarks_canvaskit.dart
+```
diff --git a/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart b/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
index b6c38c4..a5b6f21 100644
--- a/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
@@ -17,6 +17,10 @@
typedef RecorderFactory = Recorder Function();
+/// List of all benchmarks that run in the devicelab.
+///
+/// When adding a new benchmark, add it to this map. Make sure that the name
+/// of your benchmark is unique.
final Map<String, RecorderFactory> benchmarks = <String, RecorderFactory>{
BenchCardInfiniteScroll.benchmarkName: () => BenchCardInfiniteScroll(),
BenchDrawRect.benchmarkName: () => BenchDrawRect(),