forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(core): add benchmark for defer runtime logic
This commit adds a benchmark for `@defer` runtime logic and uses `@if` as a baseline.
- Loading branch information
1 parent
403e0f2
commit 6b7c454
Showing
14 changed files
with
580 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
load("//tools:defaults.bzl", "ng_module", "ts_library") | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
ng_module( | ||
name = "shared_lib", | ||
srcs = [ | ||
"init.ts", | ||
"util.ts", | ||
], | ||
tsconfig = "//modules/benchmarks:tsconfig-build.json", | ||
deps = [ | ||
"//modules/benchmarks/src:util_lib", | ||
"//packages/core", | ||
"//packages/platform-browser", | ||
], | ||
) | ||
|
||
ts_library( | ||
name = "perf_tests_lib", | ||
testonly = 1, | ||
srcs = ["defer.perf-spec.ts"], | ||
tsconfig = "//modules/benchmarks:tsconfig-e2e.json", | ||
deps = [ | ||
"@npm//@angular/build-tooling/bazel/benchmark/driver-utilities", | ||
"@npm//protractor", | ||
], | ||
) | ||
|
||
ts_library( | ||
name = "e2e_tests_lib", | ||
testonly = 1, | ||
srcs = ["defer.e2e-spec.ts"], | ||
tsconfig = "//modules/benchmarks:tsconfig-e2e.json", | ||
deps = [ | ||
"@npm//@angular/build-tooling/bazel/benchmark/driver-utilities", | ||
"@npm//protractor", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Defer benchmark | ||
|
||
This folder contains defer benchmark that tests the process of `@defer` block creation. | ||
|
||
There are 2 folders in this benchmark: | ||
|
||
* `baseline` - renders a component using an `@if` condition, we use it as a baseline | ||
* `main` - the same code as the `baseline`, but instead of the `@if`, we use `@defer` to compare defer blocks against conditionals | ||
|
||
The benchmarks are based on `largetable` benchmarks. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
load("//tools:defaults.bzl", "app_bundle", "http_server", "ng_module") | ||
load("@npm//@angular/build-tooling/bazel/benchmark/component_benchmark:benchmark_test.bzl", "benchmark_test") | ||
load("//modules/benchmarks:e2e_test.bzl", "e2e_test") | ||
|
||
package(default_visibility = ["//modules/benchmarks:__subpackages__"]) | ||
|
||
ng_module( | ||
name = "main", | ||
srcs = glob(["*.ts"]), | ||
tsconfig = "//modules/benchmarks:tsconfig-build.json", | ||
deps = [ | ||
"//modules/benchmarks/src:util_lib", | ||
"//modules/benchmarks/src/defer:shared_lib", | ||
"//packages/core", | ||
"//packages/platform-browser", | ||
], | ||
) | ||
|
||
app_bundle( | ||
name = "bundle", | ||
entry_point = ":index.ts", | ||
deps = [ | ||
":main", | ||
"@npm//rxjs", | ||
], | ||
) | ||
|
||
# The script needs to be called `app_bundle` for easier syncing into g3. | ||
genrule( | ||
name = "app_bundle", | ||
srcs = [":bundle.debug.min.js"], | ||
outs = ["app_bundle.js"], | ||
cmd = "cp $< $@", | ||
) | ||
|
||
http_server( | ||
name = "prodserver", | ||
srcs = ["index.html"], | ||
deps = [ | ||
":app_bundle", | ||
"//packages/zone.js/bundles:zone.umd.js", | ||
], | ||
) | ||
|
||
benchmark_test( | ||
name = "perf", | ||
server = ":prodserver", | ||
deps = ["//modules/benchmarks/src/defer:perf_tests_lib"], | ||
) | ||
|
||
e2e_test( | ||
name = "e2e", | ||
server = ":prodserver", | ||
deps = ["//modules/benchmarks/src/defer:e2e_tests_lib"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* @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, Input} from '@angular/core'; | ||
import {DomSanitizer, SafeStyle} from '@angular/platform-browser'; | ||
|
||
import {TableCell} from '../util'; | ||
|
||
let trustedEmptyColor: SafeStyle; | ||
let trustedGreyColor: SafeStyle; | ||
|
||
@Component({ | ||
standalone: true, | ||
selector: 'app', | ||
template: ` | ||
<table> | ||
<tbody> | ||
@for (row of data; track $index) { | ||
<tr> | ||
@for (cell of row; track $index) { | ||
<td [style.backgroundColor]="getColor(cell.row)"> | ||
@if (condition) { | ||
<!-- | ||
Use static text in cells to avoid the need | ||
to run a new change detection cycle. | ||
--> | ||
Cell | ||
} | ||
</td> | ||
} | ||
</tr> | ||
} | ||
</tbody> | ||
</table> | ||
`, | ||
}) | ||
export class AppComponent { | ||
@Input() data: TableCell[][] = []; | ||
|
||
condition = true; | ||
|
||
constructor(sanitizer: DomSanitizer) { | ||
trustedEmptyColor = sanitizer.bypassSecurityTrustStyle('white'); | ||
trustedGreyColor = sanitizer.bypassSecurityTrustStyle('grey'); | ||
} | ||
|
||
getColor(row: number) { | ||
return row % 2 ? trustedEmptyColor : trustedGreyColor; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<!-- Prevent the browser from requesting any favicon. --> | ||
<link rel="icon" href="data:," /> | ||
</head> | ||
<body> | ||
<h2>Params</h2> | ||
<form> | ||
Cols: | ||
<input type="number" id="cols" name="cols" value="" /> | ||
<br /> | ||
Rows: | ||
<input type="number" id="rows" name="rows" value="" /> | ||
<br /> | ||
<button>Apply</button> | ||
</form> | ||
|
||
<h2>Defer Benchmark (baseline)</h2> | ||
<p> | ||
<button id="destroyDom">destroyDom</button> | ||
<button id="createDom">createDom</button> | ||
<button id="createDomProfile">profile createDom</button> | ||
<button id="updateDomProfile">profile updateDom</button> | ||
</p> | ||
|
||
<div> | ||
<app id="root"></app> | ||
</div> | ||
|
||
<!-- BEGIN-EXTERNAL --> | ||
<script src="/angular/packages/zone.js/bundles/zone.umd.js"></script> | ||
<!-- END-EXTERNAL --> | ||
|
||
<!-- Needs to be named `app_bundle` for sync into Google. --> | ||
<script src="/app_bundle.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* @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 {bootstrapApplication, provideProtractorTestingSupport} from '@angular/platform-browser'; | ||
|
||
import {init, syncUrlParamsToForm} from '../init'; | ||
|
||
import {AppComponent} from './app.component'; | ||
|
||
syncUrlParamsToForm(); | ||
|
||
bootstrapApplication(AppComponent, { | ||
providers: [ | ||
provideProtractorTestingSupport(), | ||
], | ||
}).then(init); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* @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 {openBrowser, verifyNoBrowserErrors} from '@angular/build-tooling/bazel/benchmark/driver-utilities'; | ||
import {$} from 'protractor'; | ||
|
||
describe('defer benchmark', () => { | ||
afterEach(verifyNoBrowserErrors); | ||
|
||
it(`should render the table`, async () => { | ||
openBrowser({ | ||
url: '', | ||
ignoreBrowserSynchronization: true, | ||
params: [{name: 'cols', value: 5}, {name: 'rows', value: 5}], | ||
}); | ||
await $('#createDom').click(); | ||
expect($('#root').getText()).toContain('Cell'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* @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 {runBenchmark, verifyNoBrowserErrors} from '@angular/build-tooling/bazel/benchmark/driver-utilities'; | ||
import {$} from 'protractor'; | ||
|
||
interface Worker { | ||
id: string; | ||
prepare?(): void; | ||
work(): void; | ||
} | ||
|
||
const CreateWorker: Worker = { | ||
id: 'create', | ||
prepare: () => $('#destroyDom').click(), | ||
work: () => $('#createDom').click() | ||
}; | ||
|
||
const UpdateWorker: Worker = { | ||
id: 'update', | ||
prepare: () => { | ||
$('#createDom').click(); | ||
}, | ||
work: () => $('#createDom').click() | ||
}; | ||
|
||
// In order to make sure that we don't change the ids of the benchmarks, we need to | ||
// determine the current test package name from the Bazel target. This is necessary | ||
// because previous to the Bazel conversion, the benchmark test ids contained the test | ||
// name. e.g. "largeTable.ng2_switch.createDestroy". We determine the name of the | ||
// Bazel package where this test runs from the current test target. The Bazel target | ||
// looks like: "//modules/benchmarks/src/largetable/{pkg_name}:{target_name}". | ||
const testPackageName = process.env['BAZEL_TARGET']!.split(':')[0].split('/').pop(); | ||
|
||
describe('defer benchmark perf', () => { | ||
afterEach(verifyNoBrowserErrors); | ||
|
||
[CreateWorker, UpdateWorker].forEach((worker) => { | ||
describe(worker.id, () => { | ||
it(`should run benchmark for ${testPackageName}`, async () => { | ||
await runTableBenchmark({ | ||
id: `defer.${testPackageName}.${worker.id}`, | ||
url: '/', | ||
ignoreBrowserSynchronization: true, | ||
worker, | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
function runTableBenchmark( | ||
config: {id: string, url: string, ignoreBrowserSynchronization?: boolean, worker: Worker}) { | ||
return runBenchmark({ | ||
id: config.id, | ||
url: config.url, | ||
ignoreBrowserSynchronization: config.ignoreBrowserSynchronization, | ||
params: [{name: 'cols', value: 40}, {name: 'rows', value: 200}], | ||
prepare: config.worker.prepare, | ||
work: config.worker.work | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* @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 {ApplicationRef} from '@angular/core'; | ||
|
||
import {bindAction, profile} from '../util'; | ||
|
||
import {buildTable, emptyTable, initTableUtils} from './util'; | ||
|
||
const DEFAULT_COLS_COUNT = '40'; | ||
const DEFAULT_ROWS_COUNT = '200'; | ||
|
||
function getUrlParamValue(name: string): string|null { | ||
const url = new URL(document.location.href); | ||
return url.searchParams.get(name); | ||
} | ||
|
||
export function syncUrlParamsToForm(): {cols: string, rows: string} { | ||
let cols = getUrlParamValue('cols') ?? DEFAULT_COLS_COUNT; | ||
let rows = getUrlParamValue('rows') ?? DEFAULT_ROWS_COUNT; | ||
(document.getElementById('cols') as HTMLInputElement).value = cols; | ||
(document.getElementById('rows') as HTMLInputElement).value = rows; | ||
return {cols, rows}; | ||
} | ||
|
||
export function init(appRef: ApplicationRef) { | ||
const table = appRef.components[0].instance; | ||
|
||
function destroyDom() { | ||
table.data = emptyTable; | ||
appRef.tick(); | ||
} | ||
|
||
function createDom() { | ||
table.data = buildTable(); | ||
appRef.tick(); | ||
} | ||
|
||
function noop() {} | ||
|
||
initTableUtils(); | ||
|
||
bindAction('#destroyDom', destroyDom); | ||
bindAction('#createDom', createDom); | ||
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create')); | ||
bindAction('#updateDomProfile', profile(createDom, noop, 'update')); | ||
} |
Oops, something went wrong.