diff --git a/test/benchmarks/material/card/app.module.ts b/test/benchmarks/material/card/app.module.ts
index 0598c16badd8..56eafed66e58 100644
--- a/test/benchmarks/material/card/app.module.ts
+++ b/test/benchmarks/material/card/app.module.ts
@@ -30,7 +30,6 @@ export class CardBenchmarkApp {
hide() { this.isVisible = false; }
}
-
@NgModule({
declarations: [CardBenchmarkApp],
imports: [
diff --git a/test/benchmarks/material/checkbox/app.module.ts b/test/benchmarks/material/checkbox/app.module.ts
index 428643cbec03..c4644df9e4c7 100644
--- a/test/benchmarks/material/checkbox/app.module.ts
+++ b/test/benchmarks/material/checkbox/app.module.ts
@@ -29,6 +29,10 @@ import {MatCheckboxModule} from '@angular/material/checkbox';
styleUrls: ['//src/material/core/theming/prebuilt/indigo-pink.css'],
})
export class CheckboxBenchmarkApp {
+
+ // isChecked is used to maintain the buttons checked state even after it has been hidden. This is
+ // used, for example, when we want to test the render speed of a checked vs unchecked checkbox.
+
isChecked = false;
isVisible = false;
isIndeterminate = false;
@@ -39,7 +43,6 @@ export class CheckboxBenchmarkApp {
toggleIsChecked() { this.isChecked = !this.isChecked; }
}
-
@NgModule({
declarations: [CheckboxBenchmarkApp],
imports: [
diff --git a/test/benchmarks/material/chips/app.module.ts b/test/benchmarks/material/chips/app.module.ts
index 4fbf380b0696..c2bbd656f1ee 100644
--- a/test/benchmarks/material/chips/app.module.ts
+++ b/test/benchmarks/material/chips/app.module.ts
@@ -46,7 +46,6 @@ export class ChipsBenchmarkApp {
hideMultiple() { this.isMultipleVisible = false; }
}
-
@NgModule({
declarations: [ChipsBenchmarkApp],
imports: [
diff --git a/test/benchmarks/material/form-field/app.module.ts b/test/benchmarks/material/form-field/app.module.ts
index fac1c7552764..88de3e9feffe 100644
--- a/test/benchmarks/material/form-field/app.module.ts
+++ b/test/benchmarks/material/form-field/app.module.ts
@@ -59,7 +59,6 @@ export class FormFieldBenchmarkApp {
}
}
-
@NgModule({
declarations: [FormFieldBenchmarkApp],
imports: [
diff --git a/test/benchmarks/material/radio/app.module.ts b/test/benchmarks/material/radio/app.module.ts
index 9fc92ae9366c..488c4b937149 100644
--- a/test/benchmarks/material/radio/app.module.ts
+++ b/test/benchmarks/material/radio/app.module.ts
@@ -53,7 +53,6 @@ export class RadioBenchmarkApp {
hideTen() { this.isTenVisible = false; }
}
-
@NgModule({
declarations: [RadioBenchmarkApp],
imports: [
diff --git a/test/benchmarks/material/slide-toggle/app.module.ts b/test/benchmarks/material/slide-toggle/app.module.ts
index 99a373160074..4ad5c948a4cb 100644
--- a/test/benchmarks/material/slide-toggle/app.module.ts
+++ b/test/benchmarks/material/slide-toggle/app.module.ts
@@ -31,7 +31,6 @@ export class SlideToggleBenchmarkApp {
hide() { this.isVisible = false; }
}
-
@NgModule({
declarations: [SlideToggleBenchmarkApp],
imports: [
diff --git a/test/benchmarks/material/table/app.module.ts b/test/benchmarks/material/table/app.module.ts
index 3974d80677c6..e70ca149d0c0 100644
--- a/test/benchmarks/material/table/app.module.ts
+++ b/test/benchmarks/material/table/app.module.ts
@@ -68,7 +68,6 @@ export class TableBenchmarkApp {
showTenRowsTwentyCols() { this.isTenRowsTwentyColsVisible = true; }
}
-
@NgModule({
declarations: [BasicTable, TableBenchmarkApp],
imports: [
diff --git a/test/benchmarks/mdc/button/app.module.ts b/test/benchmarks/mdc/button/app.module.ts
index b60d5759f9f6..bdc6905584cb 100644
--- a/test/benchmarks/mdc/button/app.module.ts
+++ b/test/benchmarks/mdc/button/app.module.ts
@@ -30,14 +30,12 @@ export class ButtonBenchmarkApp {
hide() { this.isVisible = false; }
}
-
@NgModule({
declarations: [ButtonBenchmarkApp],
imports: [
BrowserModule,
MatButtonModule,
],
- providers: [],
bootstrap: [ButtonBenchmarkApp],
})
export class AppModule {}
diff --git a/test/benchmarks/mdc/card/app.module.ts b/test/benchmarks/mdc/card/app.module.ts
index 988454dafd2c..3aa9eabf5f59 100644
--- a/test/benchmarks/mdc/card/app.module.ts
+++ b/test/benchmarks/mdc/card/app.module.ts
@@ -30,7 +30,6 @@ export class CardBenchmarkApp {
hide() { this.isVisible = false; }
}
-
@NgModule({
declarations: [CardBenchmarkApp],
imports: [
diff --git a/test/benchmarks/mdc/checkbox/BUILD.bazel b/test/benchmarks/mdc/checkbox/BUILD.bazel
new file mode 100644
index 000000000000..66162cd2cb3d
--- /dev/null
+++ b/test/benchmarks/mdc/checkbox/BUILD.bazel
@@ -0,0 +1,22 @@
+load("@npm_angular_dev_infra_private//benchmark/component_benchmark:component_benchmark.bzl", "component_benchmark")
+
+# TODO(wagnermaciel): Update this target to provide indigo-pink in a way that doesn't require having to import it with
+# stylesUrls inside the components once `component_benchmark` supports asset injection.
+
+component_benchmark(
+ name = "benchmark",
+ driver = ":checkbox.perf-spec.ts",
+ driver_deps = [
+ "@npm//@angular/dev-infra-private",
+ "@npm//protractor",
+ "@npm//@types/jasmine",
+ ],
+ ng_deps = [
+ "@npm//@angular/core",
+ "@npm//@angular/platform-browser",
+ "//src/material-experimental/mdc-checkbox",
+ ],
+ ng_srcs = [":app.module.ts"],
+ prefix = "",
+ styles = ["//src/material-experimental/mdc-theming:indigo_pink_prebuilt"],
+)
diff --git a/test/benchmarks/mdc/checkbox/app.module.ts b/test/benchmarks/mdc/checkbox/app.module.ts
new file mode 100644
index 000000000000..fd1ea1d6c907
--- /dev/null
+++ b/test/benchmarks/mdc/checkbox/app.module.ts
@@ -0,0 +1,54 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {Component, NgModule, ViewEncapsulation} from '@angular/core';
+import {BrowserModule} from '@angular/platform-browser';
+import {MatCheckboxModule} from '@angular/material-experimental/mdc-checkbox';
+
+/** component: mdc-checkbox */
+
+@Component({
+ selector: 'app-root',
+ template: `
+
+
+
+
+
+ Check me!
+ `,
+ encapsulation: ViewEncapsulation.None,
+ styleUrls: ['//src/material-experimental/mdc-theming/prebuilt/indigo-pink.css'],
+})
+export class CheckboxBenchmarkApp {
+
+ // isChecked is used to maintain the buttons checked state even after it has been hidden. This is
+ // used, for example, when we want to test the render speed of a checked vs unchecked checkbox.
+
+ isChecked = false;
+ isVisible = false;
+ isIndeterminate = false;
+
+ show() { this.isVisible = true; }
+ hide() { this.isVisible = false; }
+ indeterminate() { this.isIndeterminate = true; }
+ toggleIsChecked() { this.isChecked = !this.isChecked; }
+}
+
+@NgModule({
+ declarations: [CheckboxBenchmarkApp],
+ imports: [
+ BrowserModule,
+ MatCheckboxModule,
+ ],
+ bootstrap: [CheckboxBenchmarkApp],
+})
+export class AppModule {}
diff --git a/test/benchmarks/mdc/checkbox/checkbox.perf-spec.ts b/test/benchmarks/mdc/checkbox/checkbox.perf-spec.ts
new file mode 100755
index 000000000000..7fa5d688d841
--- /dev/null
+++ b/test/benchmarks/mdc/checkbox/checkbox.perf-spec.ts
@@ -0,0 +1,105 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {$, browser} from 'protractor';
+import {runBenchmark} from '@angular/dev-infra-private/benchmark/driver-utilities';
+
+describe('checkbox performance benchmarks', () => {
+ beforeAll(() => {
+ browser.rootEl = '#root';
+ });
+
+ it('renders a checked checkbox', async() => {
+ await runBenchmark({
+ id: 'checkbox-render-checked',
+ url: '',
+ ignoreBrowserSynchronization: true,
+ params: [],
+ setup: async () => {
+ await $('#show').click();
+ await $('mat-checkbox').click();
+ },
+ prepare: async () => {
+ expect(await $('mat-checkbox input').isSelected())
+ .toBe(true, 'The checkbox should be in a selected state.');
+ await $('#hide').click();
+ },
+ work: async () => await $('#show').click()
+ });
+ });
+
+ it('renders an unchecked checkbox', async() => {
+ await runBenchmark({
+ id: 'checkbox-render-unchecked',
+ url: '',
+ ignoreBrowserSynchronization: true,
+ params: [],
+ setup: async() => await $('#show').click(),
+ prepare: async () => {
+ expect(await $('mat-checkbox input').isSelected())
+ .toBe(false, 'The checkbox should be in an unselected state.');
+ await $('#hide').click();
+ },
+ work: async () => await $('#show').click()
+ });
+ });
+
+ it('renders an indeterminate checkbox', async() => {
+ await runBenchmark({
+ id: 'checkbox-render-indeterminate',
+ url: '',
+ ignoreBrowserSynchronization: true,
+ params: [],
+ setup: async() => {
+ await $('#show').click();
+ await $('#indeterminate').click();
+ },
+ prepare: async () => {
+ expect(await $('mat-checkbox input').getAttribute('indeterminate'))
+ .toBe('true', 'The checkbox should be in an indeterminate state');
+ await $('#hide').click();
+ },
+ work: async () => await $('#show').click()
+ });
+ });
+
+ it('updates from unchecked to checked', async() => {
+ await runBenchmark({
+ id: 'checkbox-click-unchecked-to-checked',
+ url: '',
+ ignoreBrowserSynchronization: true,
+ params: [],
+ setup: async () => {
+ await $('#show').click();
+ await $('mat-checkbox').click();
+ },
+ prepare: async () => {
+ await $('mat-checkbox').click();
+ expect(await $('mat-checkbox input').isSelected())
+ .toBe(false, 'The checkbox should be in an unchecked state.');
+ },
+ work: async () => await $('mat-checkbox').click(),
+ });
+ });
+
+ it('updates from checked to unchecked', async() => {
+ await runBenchmark({
+ id: 'checkbox-click-checked-to-unchecked',
+ url: '',
+ ignoreBrowserSynchronization: true,
+ params: [],
+ setup: async () => await $('#show').click(),
+ prepare: async () => {
+ await $('mat-checkbox').click();
+ expect(await $('mat-checkbox input').isSelected())
+ .toBe(true, 'The checkbox should be in a checked state.');
+ },
+ work: async () => await $('mat-checkbox').click(),
+ });
+ });
+});