@ng-prism/plugin-perf 22.6.0 → 22.7.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/bundle-section.component.d.ts +11 -5
- package/dist/bundle/bundle-section.component.d.ts.map +1 -1
- package/dist/bundle/bundle-section.component.js +68 -193
- package/dist/memory/memory-section.component.d.ts +5 -2
- package/dist/memory/memory-section.component.d.ts.map +1 -1
- package/dist/memory/memory-section.component.js +69 -119
- package/dist/memory/perf-memory.service.d.ts +1 -1
- package/dist/perf-panel.component.d.ts +5 -0
- package/dist/perf-panel.component.d.ts.map +1 -1
- package/dist/perf-panel.component.js +79 -87
- package/dist/perf-status.d.ts +12 -0
- package/dist/perf-status.d.ts.map +1 -0
- package/dist/perf-status.js +16 -0
- package/dist/render/render-section.component.d.ts +7 -2
- package/dist/render/render-section.component.d.ts.map +1 -1
- package/dist/render/render-section.component.js +39 -105
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, computed, input, signal } from '@angular/core';
|
|
2
|
+
import { PrismButtonComponent, PrismPanelToolbarComponent, PrismTabsComponent } from '@ng-prism/core';
|
|
2
3
|
import { BundleSectionComponent } from './bundle/bundle-section.component.js';
|
|
3
4
|
import { MemorySectionComponent } from './memory/memory-section.component.js';
|
|
4
5
|
import { PerfMemoryService } from './memory/perf-memory.service.js';
|
|
@@ -6,81 +7,66 @@ import { DEFAULT_THRESHOLDS } from './perf.types.js';
|
|
|
6
7
|
import { PerfRenderService } from './render/perf-render.service.js';
|
|
7
8
|
import { RenderSectionComponent } from './render/render-section.component.js';
|
|
8
9
|
import * as i0 from "@angular/core";
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
i0.ɵɵelementStart(0, "button",
|
|
12
|
-
i0.ɵɵlistener("click", function
|
|
13
|
-
i0.ɵɵtext(1, "
|
|
10
|
+
function PerfPanelComponent_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
11
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
12
|
+
i0.ɵɵelementStart(0, "button", 9);
|
|
13
|
+
i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_4_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.renderService.stopRecording()); });
|
|
14
|
+
i0.ɵɵtext(1, " Pause ");
|
|
14
15
|
i0.ɵɵelementEnd();
|
|
16
|
+
} if (rf & 2) {
|
|
17
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
18
|
+
i0.ɵɵproperty("title", ctx_r1.profileTitle());
|
|
15
19
|
} }
|
|
16
|
-
function
|
|
20
|
+
function PerfPanelComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
17
21
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
18
|
-
i0.ɵɵelementStart(0, "button",
|
|
19
|
-
i0.ɵɵlistener("click", function
|
|
20
|
-
i0.ɵɵtext(1, "
|
|
21
|
-
i0.ɵɵelementEnd();
|
|
22
|
-
} }
|
|
23
|
-
function PerfPanelComponent_Conditional_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
24
|
-
i0.ɵɵelementStart(0, "span", 11);
|
|
25
|
-
i0.ɵɵelement(1, "span", 12);
|
|
26
|
-
i0.ɵɵtext(2);
|
|
22
|
+
i0.ɵɵelementStart(0, "button", 9);
|
|
23
|
+
i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_4_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.renderService.startRecording()); });
|
|
24
|
+
i0.ɵɵtext(1, " Profile ");
|
|
27
25
|
i0.ɵɵelementEnd();
|
|
28
26
|
} if (rf & 2) {
|
|
29
|
-
const
|
|
30
|
-
i0.ɵɵ
|
|
31
|
-
i0.ɵɵtextInterpolate1(" live \u00B7 ", ctx_r2.renderService.sampleCount(), " samples ");
|
|
27
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
28
|
+
i0.ɵɵproperty("title", ctx_r1.profileTitle());
|
|
32
29
|
} }
|
|
33
|
-
function
|
|
30
|
+
function PerfPanelComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
34
31
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
35
|
-
i0.ɵɵ
|
|
36
|
-
i0.ɵɵ
|
|
37
|
-
i0.ɵɵ
|
|
38
|
-
i0.ɵɵtext(3, " \u2715 Clear ");
|
|
32
|
+
i0.ɵɵelementStart(0, "button", 7);
|
|
33
|
+
i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.renderService.clear()); });
|
|
34
|
+
i0.ɵɵtext(1, " Clear ");
|
|
39
35
|
i0.ɵɵelementEnd();
|
|
40
|
-
i0.ɵɵconditionalCreate(
|
|
36
|
+
i0.ɵɵconditionalCreate(2, PerfPanelComponent_Conditional_4_Conditional_2_Template, 2, 1, "button", 8)(3, PerfPanelComponent_Conditional_4_Conditional_3_Template, 2, 1, "button", 8);
|
|
41
37
|
} if (rf & 2) {
|
|
42
|
-
const
|
|
43
|
-
i0.ɵɵ
|
|
44
|
-
i0.ɵɵ
|
|
45
|
-
i0.ɵɵconditional(ctx_r2.renderService.isRecording() ? 4 : -1);
|
|
38
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
39
|
+
i0.ɵɵadvance(2);
|
|
40
|
+
i0.ɵɵconditional(ctx_r1.renderService.isRecording() ? 2 : 3);
|
|
46
41
|
} }
|
|
47
|
-
function
|
|
42
|
+
function PerfPanelComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
48
43
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
49
|
-
i0.ɵɵelementStart(0, "button",
|
|
50
|
-
i0.ɵɵlistener("click", function
|
|
51
|
-
i0.ɵɵtext(1, "
|
|
44
|
+
i0.ɵɵelementStart(0, "button", 7);
|
|
45
|
+
i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.memoryService.clear()); });
|
|
46
|
+
i0.ɵɵtext(1, " Clear ");
|
|
52
47
|
i0.ɵɵelementEnd();
|
|
53
48
|
i0.ɵɵelementStart(2, "button", 10);
|
|
54
|
-
i0.ɵɵlistener("click", function
|
|
55
|
-
i0.ɵɵtext(3, "
|
|
49
|
+
i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_5_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.captureMemorySnapshots()); });
|
|
50
|
+
i0.ɵɵtext(3, " Snapshot ");
|
|
56
51
|
i0.ɵɵelementEnd();
|
|
57
52
|
} }
|
|
58
|
-
function
|
|
59
|
-
i0.ɵɵ
|
|
60
|
-
i0.ɵɵtext(1);
|
|
61
|
-
i0.ɵɵelementEnd();
|
|
53
|
+
function PerfPanelComponent_Case_7_Template(rf, ctx) { if (rf & 1) {
|
|
54
|
+
i0.ɵɵelement(0, "perf-bundle-section", 4);
|
|
62
55
|
} if (rf & 2) {
|
|
63
|
-
const
|
|
64
|
-
i0.ɵɵ
|
|
65
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r2.renderService.cdRunCount(), " CD runs ");
|
|
56
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
57
|
+
i0.ɵɵproperty("metrics", ctx_r1.bundleMetrics())("warnKb", ctx_r1.thresholds.bundleWarnKb)("critKb", ctx_r1.thresholds.bundleCritKb);
|
|
66
58
|
} }
|
|
67
|
-
function
|
|
68
|
-
i0.ɵɵelement(0, "perf-
|
|
59
|
+
function PerfPanelComponent_Case_8_Template(rf, ctx) { if (rf & 1) {
|
|
60
|
+
i0.ɵɵelement(0, "perf-render-section", 5);
|
|
69
61
|
} if (rf & 2) {
|
|
70
|
-
const
|
|
71
|
-
i0.ɵɵproperty("
|
|
62
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
63
|
+
i0.ɵɵproperty("renderService", ctx_r1.renderService)("warnMs", ctx_r1.thresholds.renderWarnMs)("critMs", ctx_r1.thresholds.renderCritMs);
|
|
72
64
|
} }
|
|
73
|
-
function
|
|
74
|
-
i0.ɵɵelement(0, "perf-
|
|
65
|
+
function PerfPanelComponent_Case_9_Template(rf, ctx) { if (rf & 1) {
|
|
66
|
+
i0.ɵɵelement(0, "perf-memory-section", 6);
|
|
75
67
|
} if (rf & 2) {
|
|
76
|
-
const
|
|
77
|
-
i0.ɵɵproperty("
|
|
78
|
-
} }
|
|
79
|
-
function PerfPanelComponent_Case_15_Template(rf, ctx) { if (rf & 1) {
|
|
80
|
-
i0.ɵɵelement(0, "perf-memory-section", 8);
|
|
81
|
-
} if (rf & 2) {
|
|
82
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
83
|
-
i0.ɵɵproperty("memoryService", ctx_r2.memoryService);
|
|
68
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
69
|
+
i0.ɵɵproperty("memoryService", ctx_r1.memoryService);
|
|
84
70
|
} }
|
|
85
71
|
export class PerfPanelComponent {
|
|
86
72
|
activeComponent = input(null, /* @ts-ignore */
|
|
@@ -90,6 +76,28 @@ export class PerfPanelComponent {
|
|
|
90
76
|
renderService = PerfRenderService.getInstance();
|
|
91
77
|
memoryService = PerfMemoryService.getInstance();
|
|
92
78
|
thresholds = DEFAULT_THRESHOLDS;
|
|
79
|
+
tabs = [
|
|
80
|
+
{ id: 'bundle', label: 'Bundle' },
|
|
81
|
+
{ id: 'render', label: 'Render' },
|
|
82
|
+
{ id: 'memory', label: 'Memory' }
|
|
83
|
+
];
|
|
84
|
+
selectTab(id) {
|
|
85
|
+
if (id === 'bundle' || id === 'render' || id === 'memory')
|
|
86
|
+
this.activeTab.set(id);
|
|
87
|
+
}
|
|
88
|
+
/** Recording state and change-detection runs: meta for the tooltip, not for the toolbar. */
|
|
89
|
+
profileTitle = computed(() => {
|
|
90
|
+
const parts = [];
|
|
91
|
+
if (this.renderService.isRecording())
|
|
92
|
+
parts.push(`Live · ${this.renderService.sampleCount()} samples`);
|
|
93
|
+
else
|
|
94
|
+
parts.push('Record render times');
|
|
95
|
+
const cd = this.renderService.cdRunCount();
|
|
96
|
+
if (cd > 0)
|
|
97
|
+
parts.push(`${cd} change detection runs`);
|
|
98
|
+
return parts.join(' · ');
|
|
99
|
+
}, /* @ts-ignore */
|
|
100
|
+
...(ngDevMode ? [{ debugName: "profileTitle" }] : /* istanbul ignore next */ []));
|
|
93
101
|
captureMemorySnapshots() {
|
|
94
102
|
this.memoryService.takeSnapshot('before-create');
|
|
95
103
|
setTimeout(() => this.memoryService.takeSnapshot('after-create'), 50);
|
|
@@ -100,47 +108,31 @@ export class PerfPanelComponent {
|
|
|
100
108
|
}, /* @ts-ignore */
|
|
101
109
|
...(ngDevMode ? [{ debugName: "bundleMetrics" }] : /* istanbul ignore next */ []));
|
|
102
110
|
static ɵfac = function PerfPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PerfPanelComponent)(); };
|
|
103
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PerfPanelComponent, selectors: [["prism-perf-panel"]], inputs: { activeComponent: [1, "activeComponent"] }, decls:
|
|
104
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "
|
|
105
|
-
i0.ɵɵlistener("
|
|
106
|
-
i0.ɵɵtext(3, " Bundle ");
|
|
107
|
-
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵelementStart(4, "button", 2);
|
|
109
|
-
i0.ɵɵlistener("click", function PerfPanelComponent_Template_button_click_4_listener() { return ctx.activeTab.set("render"); });
|
|
110
|
-
i0.ɵɵtext(5, " Render ");
|
|
111
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PerfPanelComponent, selectors: [["prism-perf-panel"]], inputs: { activeComponent: [1, "activeComponent"] }, decls: 10, vars: 5, consts: [[1, "prism-perf-panel"], ["toolbarStart", "", "size", "sm", "ariaLabel", "Performance views", 3, "activeChange", "items", "active"], ["toolbarEnd", "", 1, "prism-perf-actions"], [1, "prism-perf-content"], [3, "metrics", "warnKb", "critKb"], [3, "renderService", "warnMs", "critMs"], [3, "memoryService"], ["prismButton", "", "variant", "secondary", 3, "click"], ["prismButton", "", "variant", "primary", 3, "title"], ["prismButton", "", "variant", "primary", 3, "click", "title"], ["prismButton", "", "variant", "primary", 3, "click"]], template: function PerfPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
112
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "prism-panel-toolbar")(2, "prism-tabs", 1);
|
|
113
|
+
i0.ɵɵlistener("activeChange", function PerfPanelComponent_Template_prism_tabs_activeChange_2_listener($event) { return ctx.selectTab($event); });
|
|
111
114
|
i0.ɵɵelementEnd();
|
|
112
|
-
i0.ɵɵelementStart(
|
|
113
|
-
i0.ɵɵ
|
|
114
|
-
i0.ɵɵ
|
|
115
|
-
i0.ɵɵelementEnd();
|
|
116
|
-
i0.ɵɵelementStart(8, "div", 3);
|
|
117
|
-
i0.ɵɵconditionalCreate(9, PerfPanelComponent_Conditional_9_Template, 5, 2);
|
|
118
|
-
i0.ɵɵconditionalCreate(10, PerfPanelComponent_Conditional_10_Template, 4, 0);
|
|
119
|
-
i0.ɵɵconditionalCreate(11, PerfPanelComponent_Conditional_11_Template, 2, 1, "span", 4);
|
|
115
|
+
i0.ɵɵelementStart(3, "div", 2);
|
|
116
|
+
i0.ɵɵconditionalCreate(4, PerfPanelComponent_Conditional_4_Template, 4, 1);
|
|
117
|
+
i0.ɵɵconditionalCreate(5, PerfPanelComponent_Conditional_5_Template, 4, 0);
|
|
120
118
|
i0.ɵɵelementEnd()();
|
|
121
|
-
i0.ɵɵelementStart(
|
|
122
|
-
i0.ɵɵconditionalCreate(
|
|
119
|
+
i0.ɵɵelementStart(6, "div", 3);
|
|
120
|
+
i0.ɵɵconditionalCreate(7, PerfPanelComponent_Case_7_Template, 1, 3, "perf-bundle-section", 4)(8, PerfPanelComponent_Case_8_Template, 1, 3, "perf-render-section", 5)(9, PerfPanelComponent_Case_9_Template, 1, 1, "perf-memory-section", 6);
|
|
123
121
|
i0.ɵɵelementEnd()();
|
|
124
122
|
} if (rf & 2) {
|
|
125
|
-
let
|
|
126
|
-
i0.ɵɵadvance(2);
|
|
127
|
-
i0.ɵɵclassProp("prism-st-tab--active", ctx.activeTab() === "bundle");
|
|
123
|
+
let tmp_4_0;
|
|
128
124
|
i0.ɵɵadvance(2);
|
|
129
|
-
i0.ɵɵ
|
|
125
|
+
i0.ɵɵproperty("items", ctx.tabs)("active", ctx.activeTab());
|
|
130
126
|
i0.ɵɵadvance(2);
|
|
131
|
-
i0.ɵɵ
|
|
132
|
-
i0.ɵɵadvance(3);
|
|
133
|
-
i0.ɵɵconditional(ctx.activeTab() === "render" ? 9 : -1);
|
|
134
|
-
i0.ɵɵadvance();
|
|
135
|
-
i0.ɵɵconditional(ctx.activeTab() === "memory" ? 10 : -1);
|
|
127
|
+
i0.ɵɵconditional(ctx.activeTab() === "render" ? 4 : -1);
|
|
136
128
|
i0.ɵɵadvance();
|
|
137
|
-
i0.ɵɵconditional(ctx.
|
|
129
|
+
i0.ɵɵconditional(ctx.activeTab() === "memory" ? 5 : -1);
|
|
138
130
|
i0.ɵɵadvance(2);
|
|
139
|
-
i0.ɵɵconditional((
|
|
140
|
-
} }, dependencies: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent], styles: ["[_nghost-%COMP%] {\n display:
|
|
131
|
+
i0.ɵɵconditional((tmp_4_0 = ctx.activeTab()) === "bundle" ? 7 : tmp_4_0 === "render" ? 8 : tmp_4_0 === "memory" ? 9 : -1);
|
|
132
|
+
} }, dependencies: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent, PrismPanelToolbarComponent, PrismTabsComponent, PrismButtonComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.prism-perf-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-perf-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.prism-perf-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}"] });
|
|
141
133
|
}
|
|
142
134
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PerfPanelComponent, [{
|
|
143
135
|
type: Component,
|
|
144
|
-
args: [{ selector: 'prism-perf-panel', standalone: true, imports: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"prism-perf-panel\">\n <
|
|
136
|
+
args: [{ selector: 'prism-perf-panel', standalone: true, imports: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent, PrismPanelToolbarComponent, PrismTabsComponent, PrismButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"prism-perf-panel\">\n <prism-panel-toolbar>\n <prism-tabs\n toolbarStart\n size=\"sm\"\n ariaLabel=\"Performance views\"\n [items]=\"tabs\"\n [active]=\"activeTab()\"\n (activeChange)=\"selectTab($event)\" />\n <div\n toolbarEnd\n class=\"prism-perf-actions\">\n @if (activeTab() === 'render') {\n <button\n prismButton\n variant=\"secondary\"\n (click)=\"renderService.clear()\">\n Clear\n </button>\n @if (renderService.isRecording()) {\n <button\n prismButton\n variant=\"primary\"\n [title]=\"profileTitle()\"\n (click)=\"renderService.stopRecording()\">\n Pause\n </button>\n } @else {\n <button\n prismButton\n variant=\"primary\"\n [title]=\"profileTitle()\"\n (click)=\"renderService.startRecording()\">\n Profile\n </button>\n }\n }\n @if (activeTab() === 'memory') {\n <button\n prismButton\n variant=\"secondary\"\n (click)=\"memoryService.clear()\">\n Clear\n </button>\n <button\n prismButton\n variant=\"primary\"\n (click)=\"captureMemorySnapshots()\">\n Snapshot\n </button>\n }\n </div>\n </prism-panel-toolbar>\n\n <div class=\"prism-perf-content\">\n @switch (activeTab()) {\n @case ('bundle') {\n <perf-bundle-section\n [metrics]=\"bundleMetrics()\"\n [warnKb]=\"thresholds.bundleWarnKb\"\n [critKb]=\"thresholds.bundleCritKb\" />\n }\n @case ('render') {\n <perf-render-section\n [renderService]=\"renderService\"\n [warnMs]=\"thresholds.renderWarnMs\"\n [critMs]=\"thresholds.renderCritMs\" />\n }\n @case ('memory') {\n <perf-memory-section [memoryService]=\"memoryService\" />\n }\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.prism-perf-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-perf-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.prism-perf-content {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n"] }]
|
|
145
137
|
}], null, { activeComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeComponent", required: false }] }] }); })();
|
|
146
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PerfPanelComponent, { className: "PerfPanelComponent", filePath: "perf-panel.component.ts", lineNumber:
|
|
138
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PerfPanelComponent, { className: "PerfPanelComponent", filePath: "perf-panel.component.ts", lineNumber: 21 }); })();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type StatusTone } from '@ng-prism/core/plugin';
|
|
2
|
+
/**
|
|
3
|
+
* A perf figure graded against its budget, lower being better: within the
|
|
4
|
+
* warning bound it is OK, up to the critical bound a warning, above it critical.
|
|
5
|
+
* Same rule as every other key figure (`statusFor`), so the card's colour and
|
|
6
|
+
* its label cannot disagree.
|
|
7
|
+
*/
|
|
8
|
+
export declare function perfStatus(value: number, warn: number, crit: number): {
|
|
9
|
+
tone: StatusTone;
|
|
10
|
+
label: 'OK' | 'Warning' | 'Critical';
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=perf-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf-status.d.ts","sourceRoot":"","sources":["../src/perf-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAQnE;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,IAAI,GAAG,SAAS,GAAG,UAAU,CAAA;CAAE,CAIhI"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { statusFor } from '@ng-prism/core/plugin';
|
|
2
|
+
const LABEL = {
|
|
3
|
+
ok: 'OK',
|
|
4
|
+
warn: 'Warning',
|
|
5
|
+
danger: 'Critical'
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A perf figure graded against its budget, lower being better: within the
|
|
9
|
+
* warning bound it is OK, up to the critical bound a warning, above it critical.
|
|
10
|
+
* Same rule as every other key figure (`statusFor`), so the card's colour and
|
|
11
|
+
* its label cannot disagree.
|
|
12
|
+
*/
|
|
13
|
+
export function perfStatus(value, warn, crit) {
|
|
14
|
+
const tone = statusFor(value, { ok: warn, warn: crit, direction: 'lower' });
|
|
15
|
+
return { tone, label: LABEL[tone] };
|
|
16
|
+
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import { type BadgeTone } from '@ng-prism/core';
|
|
1
2
|
import type { PerfRenderService } from './perf-render.service.js';
|
|
2
3
|
import * as i0 from "@angular/core";
|
|
3
4
|
export declare class RenderSectionComponent {
|
|
4
5
|
readonly renderService: import("@angular/core").InputSignal<PerfRenderService>;
|
|
5
6
|
readonly warnMs: import("@angular/core").InputSignal<number>;
|
|
6
7
|
readonly critMs: import("@angular/core").InputSignal<number>;
|
|
7
|
-
readonly initialClass: import("@angular/core").Signal<"" | "crit" | "warn">;
|
|
8
8
|
formatMs(value: number | null): string;
|
|
9
|
-
|
|
9
|
+
/** A measured render time graded against the budget; `null` when there is nothing to grade. */
|
|
10
|
+
statusOf(value: number | null): {
|
|
11
|
+
tone: BadgeTone;
|
|
12
|
+
label: string;
|
|
13
|
+
} | null;
|
|
14
|
+
budgetTitle(what: string): string;
|
|
10
15
|
static ɵfac: i0.ɵɵFactoryDeclaration<RenderSectionComponent, never>;
|
|
11
16
|
static ɵcmp: i0.ɵɵComponentDeclaration<RenderSectionComponent, "perf-render-section", never, { "renderService": { "alias": "renderService"; "required": true; "isSignal": true; }; "warnMs": { "alias": "warnMs"; "required": false; "isSignal": true; }; "critMs": { "alias": "critMs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
12
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-section.component.d.ts","sourceRoot":"","sources":["../../src/render/render-section.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;;AAGlE,qBAQa,sBAAsB;IAC/B,QAAQ,CAAC,aAAa,yDAAuC;IAC7D,QAAQ,CAAC,MAAM,8CAAY;IAC3B,QAAQ,CAAC,MAAM,8CAAa;IAE5B,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"render-section.component.d.ts","sourceRoot":"","sources":["../../src/render/render-section.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,gBAAgB,CAAC;AAEzF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;;AAGlE,qBAQa,sBAAsB;IAC/B,QAAQ,CAAC,aAAa,yDAAuC;IAC7D,QAAQ,CAAC,MAAM,8CAAY;IAC3B,QAAQ,CAAC,MAAM,8CAAa;IAE5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAKtC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOzE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;yCAlBxB,sBAAsB;2CAAtB,sBAAsB;CAqBlC"}
|
|
@@ -1,109 +1,53 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component,
|
|
1
|
+
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
|
2
|
+
import { PrismMetricCardComponent, toneForStatus } from '@ng-prism/core';
|
|
3
|
+
import { perfStatus } from '../perf-status.js';
|
|
2
4
|
import { SparklineComponent } from './sparkline.component.js';
|
|
3
5
|
import * as i0 from "@angular/core";
|
|
4
|
-
function
|
|
5
|
-
i0.ɵɵelementStart(0, "div", 7)(1, "
|
|
6
|
-
i0.ɵɵtext(
|
|
6
|
+
function RenderSectionComponent_Conditional_0_Conditional_0_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
7
|
+
i0.ɵɵelementStart(0, "div", 7)(1, "span", 8);
|
|
8
|
+
i0.ɵɵtext(2, "Render time trace");
|
|
7
9
|
i0.ɵɵelementEnd();
|
|
8
|
-
i0.ɵɵ
|
|
9
|
-
i0.ɵɵtext(6, "avg ");
|
|
10
|
-
i0.ɵɵelementStart(7, "span", 10);
|
|
11
|
-
i0.ɵɵtext(8);
|
|
10
|
+
i0.ɵɵelement(3, "perf-sparkline", 9);
|
|
12
11
|
i0.ɵɵelementEnd();
|
|
13
|
-
i0.ɵɵtext(9, " \u00B7 max ");
|
|
14
|
-
i0.ɵɵelementStart(10, "span", 10);
|
|
15
|
-
i0.ɵɵtext(11);
|
|
16
|
-
i0.ɵɵelementEnd()()();
|
|
17
|
-
i0.ɵɵelementStart(12, "div", 11);
|
|
18
|
-
i0.ɵɵelement(13, "perf-sparkline", 12);
|
|
19
|
-
i0.ɵɵelementEnd()()();
|
|
20
12
|
} if (rf & 2) {
|
|
21
13
|
const svc_r1 = i0.ɵɵnextContext(2);
|
|
22
14
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
23
|
-
i0.ɵɵ
|
|
24
|
-
i0.ɵɵtextInterpolate1("Render Time Trace \u2014 Last ", svc_r1.sampleCount(), " Samples");
|
|
25
|
-
i0.ɵɵadvance(4);
|
|
26
|
-
i0.ɵɵtextInterpolate1("", ctx_r1.formatMs(svc_r1.avgRerender()), " ms");
|
|
15
|
+
i0.ɵɵproperty("title", "Last " + svc_r1.sampleCount() + " samples \u00B7 avg " + ctx_r1.formatMs(svc_r1.avgRerender()) + " ms \u00B7 max " + ctx_r1.formatMs(svc_r1.maxRerender()) + " ms \u00B7 line at " + ctx_r1.warnMs() + " ms");
|
|
27
16
|
i0.ɵɵadvance(3);
|
|
28
|
-
i0.ɵɵtextInterpolate1("", ctx_r1.formatMs(svc_r1.maxRerender()), " ms");
|
|
29
|
-
i0.ɵɵadvance(2);
|
|
30
17
|
i0.ɵɵproperty("samples", svc_r1.rerenders())("thresholdWarn", ctx_r1.warnMs())("height", 80);
|
|
31
18
|
} }
|
|
32
19
|
function RenderSectionComponent_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
33
|
-
i0.ɵɵelementStart(0, "div", 1)
|
|
34
|
-
i0.ɵɵ
|
|
35
|
-
i0.ɵɵelementEnd()
|
|
36
|
-
i0.ɵɵ
|
|
37
|
-
i0.ɵɵtext(6);
|
|
38
|
-
i0.ɵɵelementStart(7, "span");
|
|
39
|
-
i0.ɵɵtext(8, "ms");
|
|
40
|
-
i0.ɵɵelementEnd()()();
|
|
41
|
-
i0.ɵɵelementStart(9, "div", 2)(10, "div", 3)(11, "span", 4);
|
|
42
|
-
i0.ɵɵtext(12, "Avg Re-Render");
|
|
43
|
-
i0.ɵɵelementEnd()();
|
|
44
|
-
i0.ɵɵelementStart(13, "div", 5);
|
|
45
|
-
i0.ɵɵtext(14);
|
|
46
|
-
i0.ɵɵelementStart(15, "span");
|
|
47
|
-
i0.ɵɵtext(16, "ms");
|
|
48
|
-
i0.ɵɵelementEnd()();
|
|
49
|
-
i0.ɵɵelementStart(17, "div", 6);
|
|
50
|
-
i0.ɵɵtext(18);
|
|
51
|
-
i0.ɵɵelementEnd()();
|
|
52
|
-
i0.ɵɵelementStart(19, "div", 2)(20, "div", 3)(21, "span", 4);
|
|
53
|
-
i0.ɵɵtext(22, "Slowest");
|
|
54
|
-
i0.ɵɵelementEnd()();
|
|
55
|
-
i0.ɵɵelementStart(23, "div", 5);
|
|
56
|
-
i0.ɵɵtext(24);
|
|
57
|
-
i0.ɵɵelementStart(25, "span");
|
|
58
|
-
i0.ɵɵtext(26, "ms");
|
|
59
|
-
i0.ɵɵelementEnd()()();
|
|
60
|
-
i0.ɵɵelementStart(27, "div", 2)(28, "div", 3)(29, "span", 4);
|
|
61
|
-
i0.ɵɵtext(30, "P95");
|
|
62
|
-
i0.ɵɵelementEnd()();
|
|
63
|
-
i0.ɵɵelementStart(31, "div", 5);
|
|
64
|
-
i0.ɵɵtext(32);
|
|
65
|
-
i0.ɵɵelementStart(33, "span");
|
|
66
|
-
i0.ɵɵtext(34, "ms");
|
|
67
|
-
i0.ɵɵelementEnd()()();
|
|
68
|
-
i0.ɵɵelementStart(35, "div", 2)(36, "div", 3)(37, "span", 4);
|
|
69
|
-
i0.ɵɵtext(38, "Last Render");
|
|
70
|
-
i0.ɵɵelementEnd()();
|
|
71
|
-
i0.ɵɵelementStart(39, "div", 5);
|
|
72
|
-
i0.ɵɵtext(40);
|
|
73
|
-
i0.ɵɵelementStart(41, "span");
|
|
74
|
-
i0.ɵɵtext(42, "ms");
|
|
75
|
-
i0.ɵɵelementEnd()()()();
|
|
76
|
-
i0.ɵɵconditionalCreate(43, RenderSectionComponent_Conditional_0_Conditional_0_Conditional_43_Template, 14, 6, "div", 7);
|
|
20
|
+
i0.ɵɵelementStart(0, "div", 1);
|
|
21
|
+
i0.ɵɵelement(1, "prism-metric-card", 2)(2, "prism-metric-card", 3)(3, "prism-metric-card", 4)(4, "prism-metric-card", 5)(5, "prism-metric-card", 6);
|
|
22
|
+
i0.ɵɵelementEnd();
|
|
23
|
+
i0.ɵɵconditionalCreate(6, RenderSectionComponent_Conditional_0_Conditional_0_Conditional_6_Template, 4, 4, "div", 7);
|
|
77
24
|
} if (rf & 2) {
|
|
78
25
|
const svc_r1 = i0.ɵɵnextContext();
|
|
79
26
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
80
|
-
|
|
81
|
-
i0.ɵɵstyleProp("color", ctx_r1.colorFor(svc_r1.initialRender()));
|
|
27
|
+
const initial_r3 = ctx_r1.statusOf(svc_r1.initialRender());
|
|
82
28
|
i0.ɵɵadvance();
|
|
83
|
-
i0.ɵɵ
|
|
84
|
-
i0.ɵɵadvance(
|
|
85
|
-
i0.ɵɵ
|
|
86
|
-
i0.ɵɵadvance(
|
|
87
|
-
i0.ɵɵ
|
|
88
|
-
i0.ɵɵadvance(
|
|
89
|
-
i0.ɵɵ
|
|
90
|
-
i0.ɵɵadvance(
|
|
91
|
-
i0.ɵɵ
|
|
92
|
-
i0.ɵɵadvance(
|
|
93
|
-
i0.ɵɵ
|
|
94
|
-
i0.ɵɵadvance(3);
|
|
95
|
-
i0.ɵɵconditional(svc_r1.rerenders().length > 1 ? 43 : -1);
|
|
29
|
+
i0.ɵɵproperty("value", ctx_r1.formatMs(svc_r1.initialRender()))("tone", initial_r3?.tone ?? null)("statusLabel", initial_r3?.label ?? null)("title", ctx_r1.budgetTitle("First render of the component"));
|
|
30
|
+
i0.ɵɵadvance();
|
|
31
|
+
i0.ɵɵproperty("value", ctx_r1.formatMs(svc_r1.avgRerender()))("title", svc_r1.sampleCount() + " samples");
|
|
32
|
+
i0.ɵɵadvance();
|
|
33
|
+
i0.ɵɵproperty("value", ctx_r1.formatMs(svc_r1.maxRerender()));
|
|
34
|
+
i0.ɵɵadvance();
|
|
35
|
+
i0.ɵɵproperty("value", ctx_r1.formatMs(svc_r1.p95Rerender()));
|
|
36
|
+
i0.ɵɵadvance();
|
|
37
|
+
i0.ɵɵproperty("value", ctx_r1.formatMs(svc_r1.lastRerender()));
|
|
38
|
+
i0.ɵɵadvance();
|
|
39
|
+
i0.ɵɵconditional(svc_r1.rerenders().length > 1 ? 6 : -1);
|
|
96
40
|
} }
|
|
97
41
|
function RenderSectionComponent_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
98
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "
|
|
42
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "span");
|
|
99
43
|
i0.ɵɵtext(2, "No profiling data yet");
|
|
100
44
|
i0.ɵɵelementEnd();
|
|
101
|
-
i0.ɵɵelementStart(3, "
|
|
45
|
+
i0.ɵɵelementStart(3, "span");
|
|
102
46
|
i0.ɵɵtext(4, "Click Profile to start recording render times");
|
|
103
47
|
i0.ɵɵelementEnd()();
|
|
104
48
|
} }
|
|
105
49
|
function RenderSectionComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
106
|
-
i0.ɵɵconditionalCreate(0, RenderSectionComponent_Conditional_0_Conditional_0_Template,
|
|
50
|
+
i0.ɵɵconditionalCreate(0, RenderSectionComponent_Conditional_0_Conditional_0_Template, 7, 10)(1, RenderSectionComponent_Conditional_0_Conditional_1_Template, 5, 0, "div", 0);
|
|
107
51
|
} if (rf & 2) {
|
|
108
52
|
const svc_r1 = ctx;
|
|
109
53
|
i0.ɵɵconditional(svc_r1.initialRender() !== null || svc_r1.rerenders().length > 0 ? 0 : 1);
|
|
@@ -115,41 +59,31 @@ export class RenderSectionComponent {
|
|
|
115
59
|
...(ngDevMode ? [{ debugName: "warnMs" }] : /* istanbul ignore next */ []));
|
|
116
60
|
critMs = input(16, /* @ts-ignore */
|
|
117
61
|
...(ngDevMode ? [{ debugName: "critMs" }] : /* istanbul ignore next */ []));
|
|
118
|
-
initialClass = computed(() => {
|
|
119
|
-
const v = this.renderService().initialRender();
|
|
120
|
-
if (v === null)
|
|
121
|
-
return '';
|
|
122
|
-
if (v >= this.critMs())
|
|
123
|
-
return 'crit';
|
|
124
|
-
if (v >= this.warnMs())
|
|
125
|
-
return 'warn';
|
|
126
|
-
return '';
|
|
127
|
-
}, /* @ts-ignore */
|
|
128
|
-
...(ngDevMode ? [{ debugName: "initialClass" }] : /* istanbul ignore next */ []));
|
|
129
62
|
formatMs(value) {
|
|
130
63
|
if (value === null)
|
|
131
64
|
return '—';
|
|
132
65
|
return value < 10 ? value.toFixed(2) : value.toFixed(1);
|
|
133
66
|
}
|
|
134
|
-
|
|
67
|
+
/** A measured render time graded against the budget; `null` when there is nothing to grade. */
|
|
68
|
+
statusOf(value) {
|
|
135
69
|
if (value === null)
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return
|
|
70
|
+
return null;
|
|
71
|
+
const status = perfStatus(value, this.warnMs(), this.critMs());
|
|
72
|
+
return { tone: toneForStatus(status.tone), label: status.label };
|
|
73
|
+
}
|
|
74
|
+
budgetTitle(what) {
|
|
75
|
+
return `${what} · warning above ${this.warnMs()} ms, critical above ${this.critMs()} ms`;
|
|
142
76
|
}
|
|
143
77
|
static ɵfac = function RenderSectionComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RenderSectionComponent)(); };
|
|
144
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RenderSectionComponent, selectors: [["perf-render-section"]], inputs: { renderService: [1, "renderService"], warnMs: [1, "warnMs"], critMs: [1, "critMs"] }, decls: 1, vars: 1, consts: [[1, "perf-empty"], [1, "perf-
|
|
78
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RenderSectionComponent, selectors: [["perf-render-section"]], inputs: { renderService: [1, "renderService"], warnMs: [1, "warnMs"], critMs: [1, "critMs"] }, decls: 1, vars: 1, consts: [[1, "perf-empty"], [1, "perf-grid"], ["label", "Initial render", "unit", "ms", 3, "value", "tone", "statusLabel", "title"], ["label", "Avg re-render", "unit", "ms", 3, "value", "title"], ["label", "Slowest", "unit", "ms", 3, "value"], ["label", "P95", "unit", "ms", 3, "value"], ["label", "Last render", "unit", "ms", 3, "value"], [1, "perf-block", 3, "title"], [1, "perf-block__label"], [3, "samples", "thresholdWarn", "height"]], template: function RenderSectionComponent_Template(rf, ctx) { if (rf & 1) {
|
|
145
79
|
i0.ɵɵconditionalCreate(0, RenderSectionComponent_Conditional_0_Template, 2, 1);
|
|
146
80
|
} if (rf & 2) {
|
|
147
81
|
let tmp_0_0;
|
|
148
82
|
i0.ɵɵconditional((tmp_0_0 = ctx.renderService()) ? 0 : -1, tmp_0_0);
|
|
149
|
-
} }, dependencies: [SparklineComponent], styles: [".perf-
|
|
83
|
+
} }, dependencies: [SparklineComponent, PrismMetricCardComponent], styles: ["\n\n\n[_nghost-%COMP%] {\n display: block;\n}\n\n.perf-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\n gap: 12px;\n padding: 16px 18px 0;\n}\n\n.perf-block[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 12px;\n margin: 12px 18px 0;\n background: var(--%NS%prism-bg-surface);\n border: 1px solid var(--%NS%prism-border);\n border-radius: 6px;\n}\n\n.perf-block[_ngcontent-%COMP%]:last-child {\n margin-bottom: 16px;\n}\n\n.perf-block__label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--%NS%prism-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n\n.perf-bars[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 84px minmax(0, 1fr) auto;\n gap: 10px;\n align-items: center;\n font-family: var(--%NS%font-mono);\n font-size: 12px;\n}\n\n.perf-bar-label[_ngcontent-%COMP%] {\n color: var(--%NS%prism-text-muted);\n}\n\n.perf-bar-track[_ngcontent-%COMP%] {\n height: 6px;\n overflow: hidden;\n background: var(--%NS%prism-input-bg);\n border-radius: 3px;\n}\n\n.perf-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--%NS%prism-primary);\n border-radius: 3px;\n}\n\n.perf-bar-val[_ngcontent-%COMP%] {\n color: var(--%NS%prism-text-2);\n white-space: nowrap;\n}\n\n.perf-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n align-items: center;\n justify-content: center;\n height: 100%;\n min-height: 160px;\n font-size: 12.5px;\n color: var(--%NS%prism-text-muted);\n}\n\n.perf-block[_ngcontent-%COMP%] > prism-badge[_ngcontent-%COMP%] {\n align-self: flex-start;\n}"] });
|
|
150
84
|
}
|
|
151
85
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RenderSectionComponent, [{
|
|
152
86
|
type: Component,
|
|
153
|
-
args: [{ selector: 'perf-render-section', standalone: true, imports: [SparklineComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (renderService(); as svc) {\n @if (svc.initialRender() !== null || svc.rerenders().length > 0) {\n <div class=\"perf-
|
|
87
|
+
args: [{ selector: 'perf-render-section', standalone: true, imports: [SparklineComponent, PrismMetricCardComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (renderService(); as svc) {\n @if (svc.initialRender() !== null || svc.rerenders().length > 0) {\n <div class=\"perf-grid\">\n @let initial = statusOf(svc.initialRender());\n <prism-metric-card\n label=\"Initial render\"\n unit=\"ms\"\n [value]=\"formatMs(svc.initialRender())\"\n [tone]=\"initial?.tone ?? null\"\n [statusLabel]=\"initial?.label ?? null\"\n [title]=\"budgetTitle('First render of the component')\" />\n <prism-metric-card\n label=\"Avg re-render\"\n unit=\"ms\"\n [value]=\"formatMs(svc.avgRerender())\"\n [title]=\"svc.sampleCount() + ' samples'\" />\n <prism-metric-card\n label=\"Slowest\"\n unit=\"ms\"\n [value]=\"formatMs(svc.maxRerender())\" />\n <prism-metric-card\n label=\"P95\"\n unit=\"ms\"\n [value]=\"formatMs(svc.p95Rerender())\" />\n <prism-metric-card\n label=\"Last render\"\n unit=\"ms\"\n [value]=\"formatMs(svc.lastRerender())\" />\n </div>\n\n @if (svc.rerenders().length > 1) {\n <div\n class=\"perf-block\"\n [title]=\"\n 'Last ' +\n svc.sampleCount() +\n ' samples \u00B7 avg ' +\n formatMs(svc.avgRerender()) +\n ' ms \u00B7 max ' +\n formatMs(svc.maxRerender()) +\n ' ms \u00B7 line at ' +\n warnMs() +\n ' ms'\n \">\n <span class=\"perf-block__label\">Render time trace</span>\n <perf-sparkline\n [samples]=\"svc.rerenders()\"\n [thresholdWarn]=\"warnMs()\"\n [height]=\"80\" />\n </div>\n }\n } @else {\n <div class=\"perf-empty\">\n <span>No profiling data yet</span>\n <span>Click Profile to start recording render times</span>\n </div>\n }\n}\n", styles: ["/* Shared by the bundle, render and memory sections: metric cards on a 12 px\n grid, block cards for bars and traces, and the empty state. The cards\n themselves are prism-metric-card from @ng-prism/core. */\n:host {\n display: block;\n}\n\n.perf-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\n gap: 12px;\n padding: 16px 18px 0;\n}\n\n.perf-block {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 12px;\n margin: 12px 18px 0;\n background: var(--prism-bg-surface);\n border: 1px solid var(--prism-border);\n border-radius: 6px;\n}\n\n.perf-block:last-child {\n margin-bottom: 16px;\n}\n\n.perf-block__label {\n font-size: 11px;\n font-weight: 600;\n color: var(--prism-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n/* Quantities, not verdicts: one colour, the primary, never the brand gradient. */\n.perf-bars {\n display: grid;\n grid-template-columns: 84px minmax(0, 1fr) auto;\n gap: 10px;\n align-items: center;\n font-family: var(--font-mono);\n font-size: 12px;\n}\n\n.perf-bar-label {\n color: var(--prism-text-muted);\n}\n\n.perf-bar-track {\n height: 6px;\n overflow: hidden;\n background: var(--prism-input-bg);\n border-radius: 3px;\n}\n\n.perf-bar-fill {\n height: 100%;\n background: var(--prism-primary);\n border-radius: 3px;\n}\n\n.perf-bar-val {\n color: var(--prism-text-2);\n white-space: nowrap;\n}\n\n.perf-empty {\n display: flex;\n flex-direction: column;\n gap: 6px;\n align-items: center;\n justify-content: center;\n height: 100%;\n min-height: 160px;\n font-size: 12.5px;\n color: var(--prism-text-muted);\n}\n\n.perf-block > prism-badge {\n align-self: flex-start;\n}\n"] }]
|
|
154
88
|
}], null, { renderService: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderService", required: true }] }], warnMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "warnMs", required: false }] }], critMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "critMs", required: false }] }] }); })();
|
|
155
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RenderSectionComponent, { className: "RenderSectionComponent", filePath: "render/render-section.component.ts", lineNumber:
|
|
89
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RenderSectionComponent, { className: "RenderSectionComponent", filePath: "render/render-section.component.ts", lineNumber: 15 }); })();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-prism/plugin-perf",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.7.0-beta.1",
|
|
4
4
|
"description": "Performance profiling panel for ng-prism: bundle size, render time, memory footprint.",
|
|
5
5
|
"ng-add": {
|
|
6
6
|
"save": "devDependencies"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@angular/core": ">=20.0.0",
|
|
38
38
|
"typescript": ">=5.0.0",
|
|
39
|
-
"@ng-prism/core": "^22.
|
|
39
|
+
"@ng-prism/core": "^22.7.0-0",
|
|
40
40
|
"@angular-devkit/schematics": ">=20.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|