Skip to content

Commit ffd3fca

Browse files
devversionalxhub
authored andcommitted
test: add benchmark for ng template outlet context modifications (angular#51887)
Adds a benchmark for potential upcoming `NgTemplateOutlet` context logic updates. PR Close angular#51887
1 parent d77c4b2 commit ffd3fca

File tree

5 files changed

+225
-0
lines changed

5 files changed

+225
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
load("//tools:defaults.bzl", "ts_library")
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
ts_library(
6+
name = "perf_lib",
7+
testonly = True,
8+
srcs = ["ng_template_outlet_context.perf-spec.ts"],
9+
tsconfig = "//modules/benchmarks:tsconfig-e2e.json",
10+
deps = [
11+
"@npm//@angular/build-tooling/bazel/benchmark/driver-utilities",
12+
"@npm//protractor",
13+
],
14+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
load("//tools:defaults.bzl", "app_bundle", "http_server", "ng_module")
2+
load("@npm//@angular/build-tooling/bazel/benchmark/component_benchmark:benchmark_test.bzl", "benchmark_test")
3+
4+
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
5+
6+
ng_module(
7+
name = "ng2",
8+
srcs = glob(["*.ts"]),
9+
strict_templates = True,
10+
tsconfig = "//modules/benchmarks:tsconfig-build.json",
11+
deps = [
12+
"//modules/benchmarks/src:util_lib",
13+
"//packages/core",
14+
"//packages/platform-browser",
15+
],
16+
)
17+
18+
app_bundle(
19+
name = "bundle",
20+
entry_point = ":index.ts",
21+
deps = [
22+
":ng2",
23+
],
24+
)
25+
26+
http_server(
27+
name = "prodserver",
28+
srcs = ["index.html"],
29+
deps = [
30+
":bundle.debug.min.js",
31+
"//packages/zone.js/bundles:zone.umd.js",
32+
],
33+
)
34+
35+
benchmark_test(
36+
name = "perf",
37+
server = ":prodserver",
38+
deps = ["//modules/benchmarks/src/ng_template_outlet_context:perf_lib"],
39+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<!-- Prevent the browser from requesting any favicon. -->
5+
<link rel="icon" href="data:," />
6+
</head>
7+
8+
<body>
9+
<div>
10+
<app-component>Loading...</app-component>
11+
</div>
12+
13+
<script src="/angular/packages/zone.js/bundles/zone.umd.js"></script>
14+
<script src="/bundle.debug.min.js"></script>
15+
</body>
16+
</html>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {NgIf, NgTemplateOutlet} from '@angular/common';
10+
import {Component, enableProdMode, Input} from '@angular/core';
11+
import {bootstrapApplication} from '@angular/platform-browser';
12+
13+
@Component({
14+
selector: 'deep',
15+
standalone: true,
16+
imports: [NgIf],
17+
template: `<deep *ngIf="depth > 1" [depth]="depth - 1" /> Level: {{depth}}`,
18+
})
19+
class Deep {
20+
@Input({required: true}) depth: number;
21+
}
22+
23+
@Component({
24+
selector: 'app-component',
25+
standalone: true,
26+
imports: [NgTemplateOutlet, Deep],
27+
template: `
28+
<button id="swapOutFull" (click)="swapOutFull()">Swap out full context</button>
29+
<button id="modifyProperty" (click)="modifyProperty()">Modify property</button>
30+
<button id="modifyDeepProperty" (click)="modifyDeepProperty()">Modify deep property</button>
31+
<button id="addNewProperty" (click)="addNewProperty()">Add new property</button>
32+
33+
<ng-template #templateRef let-implicit let-a="a" let-b="b" let-deep="deep" let-new="new">
34+
<p>Implicit: {{implicit}}</p>
35+
<p>A: {{a}}</p>
36+
<p>B: {{b}}</p>
37+
<p>Deep: {{deep.next.text}}</p>
38+
<p>New: {{new}}</p>
39+
40+
<deep [depth]="20" />
41+
</ng-template>
42+
43+
<div>
44+
<p>Outlet</p>
45+
<ng-template [ngTemplateOutlet]="templateRef"
46+
[ngTemplateOutletContext]="context" />
47+
</div>
48+
`,
49+
})
50+
class AppComponent {
51+
context:
52+
{$implicit: unknown, a: unknown, b: unknown, deep: {next: {text: unknown}}, new?: unknown} = {
53+
$implicit: 'Default Implicit',
54+
a: 'Default A',
55+
b: 'Default B',
56+
deep: {next: {text: 'Default deep text'}},
57+
};
58+
59+
swapOutFull() {
60+
this.context = {
61+
$implicit: 'New Implicit new Object',
62+
a: 'New A new Object',
63+
b: 'New B new Object',
64+
deep: {next: {text: 'New Deep text new Object'}},
65+
};
66+
}
67+
68+
modifyProperty() {
69+
this.context.a = 'Modified a';
70+
}
71+
72+
modifyDeepProperty() {
73+
this.context.deep.next.text = 'Modified deep a';
74+
}
75+
76+
addNewProperty() {
77+
this.context.new = 'New property set';
78+
}
79+
}
80+
81+
enableProdMode();
82+
bootstrapApplication(AppComponent);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {runBenchmark, verifyNoBrowserErrors} from '@angular/build-tooling/bazel/benchmark/driver-utilities';
10+
import {$} from 'protractor';
11+
12+
interface Worker {
13+
id: string;
14+
prepare?(): void;
15+
work(): void;
16+
}
17+
18+
const SwapFullContext = {
19+
id: 'swapFullContext',
20+
work: () => {
21+
$('#swapOutFull').click();
22+
}
23+
};
24+
25+
const ModifyContextProperty = {
26+
id: 'modifyContextProperty',
27+
work: () => {
28+
$('#modifyProperty').click();
29+
}
30+
};
31+
32+
const ModifyContextDeepProperty = {
33+
id: 'modifyContextDeepProperty',
34+
work: () => {
35+
$('#modifyDeepProperty').click();
36+
}
37+
};
38+
39+
const AddNewContextProperty = {
40+
id: 'addNewContextProperty',
41+
work: () => {
42+
$('#addNewProperty').click();
43+
}
44+
};
45+
46+
const scenarios = [
47+
SwapFullContext,
48+
ModifyContextProperty,
49+
ModifyContextDeepProperty,
50+
AddNewContextProperty,
51+
];
52+
53+
describe('ng_template_outlet_context benchmark spec', () => {
54+
afterEach(verifyNoBrowserErrors);
55+
56+
scenarios.forEach((worker) => {
57+
describe(worker.id, () => {
58+
it('should run for ng2', async () => {
59+
await runBenchmarkScenario(
60+
{url: '/', id: `ngTemplateOutletContext.ng2.${worker.id}`, worker: worker});
61+
});
62+
});
63+
});
64+
65+
function runBenchmarkScenario(config: {id: string, url: string, worker: Worker}) {
66+
return runBenchmark({
67+
id: config.id,
68+
url: config.url,
69+
ignoreBrowserSynchronization: true,
70+
prepare: config.worker.prepare,
71+
work: config.worker.work
72+
});
73+
}
74+
});

0 commit comments

Comments
 (0)