perf(ui): make the libs/ui Eager components OnPush

Plan item C6 step 3 for libs/ui/components and libs/ui/epg: eleven
components (twelve with the EPG trust dialog) set
ChangeDetectionStrategy.Eager and were checked on every tick, among them
the always-mounted EPG progress panel the idle audit found re-rendering
on every idle tick. Their template state is already signals, signal
inputs, immutable dialog data or fields written from template events, so
they switch to OnPush without other changes.

The epg-item-description spec mutated dialog data after creation and
marked only the fixture's host view; it now marks the component's own
view, which OnPush requires. The libs/ui playback and remote-control
components stay Eager for their own PRs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-10-04 10:10:16 +02:00
1 parent 0cfd1dd7ed
commit 8cfb8ab251
13 files changed
+30 -34

No files matched your search

+11 -11
View File
@@ -85,17 +85,17 @@ files that still contain `ChangeDetectionStrategy.Eager`.
### libs/ui (20 files, 21 components)
- [ ] `libs/ui/components/src/lib/confirm-dialog/confirm-dialog.component.ts`
- [ ] `libs/ui/components/src/lib/content-hero/content-hero.component.ts`
- [ ] `libs/ui/components/src/lib/expandable-text/expandable-text.component.ts`
- [ ] `libs/ui/components/src/lib/portal-detail-shell/content-about.component.ts`
- [ ] `libs/ui/components/src/lib/portal-detail-shell/portal-detail-shell.component.ts`
- [ ] `libs/ui/components/src/lib/progress-capsule/progress-capsule.component.ts`
- [ ] `libs/ui/components/src/lib/season-container/episode-info-dialog.component.ts`
- [ ] `libs/ui/components/src/lib/watched-badge/watched-badge.component.ts`
- [ ] `libs/ui/epg/src/lib/epg-item-description/epg-item-description.component.ts`
- [ ] `libs/ui/epg/src/lib/epg-progress-panel/epg-progress-panel.component.ts` (idle audit root; also `EpgTrustConfirmDialogComponent`)
- [ ] `libs/ui/epg/src/lib/epg-source-status/epg-source-status.component.ts`
- [x] `libs/ui/components/src/lib/confirm-dialog/confirm-dialog.component.ts`
- [x] `libs/ui/components/src/lib/content-hero/content-hero.component.ts`
- [x] `libs/ui/components/src/lib/expandable-text/expandable-text.component.ts`
- [x] `libs/ui/components/src/lib/portal-detail-shell/content-about.component.ts`
- [x] `libs/ui/components/src/lib/portal-detail-shell/portal-detail-shell.component.ts`
- [x] `libs/ui/components/src/lib/progress-capsule/progress-capsule.component.ts`
- [x] `libs/ui/components/src/lib/season-container/episode-info-dialog.component.ts`
- [x] `libs/ui/components/src/lib/watched-badge/watched-badge.component.ts`
- [x] `libs/ui/epg/src/lib/epg-item-description/epg-item-description.component.ts`
- [x] `libs/ui/epg/src/lib/epg-progress-panel/epg-progress-panel.component.ts` (idle audit root; also `EpgTrustConfirmDialogComponent`)
- [x] `libs/ui/epg/src/lib/epg-source-status/epg-source-status.component.ts`
- [ ] `libs/ui/remote-control/src/lib/remote-control/remote-control.component.ts` (`apps/remote-control-web` only)
- [ ] `libs/ui/playback/src/lib/art-player/art-player.component.ts`
- [ ] `libs/ui/playback/src/lib/audio-player/audio-player.component.ts`
@@ -29,8 +29,7 @@ export interface ConfirmDialogData {
@Component({
imports: [MatButtonModule, MatDialogModule, TranslateModule],
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<h2 mat-dialog-title>
{{ dialogData.title }}
@@ -34,8 +34,7 @@ export type ContentHeroLayout = 'stage' | 'compact';
TranslateModule,
],
templateUrl: './content-hero.component.html',
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./content-hero.component.scss'],
})
export class ContentHeroComponent {
@@ -47,8 +47,7 @@ import { TranslateModule } from '@ngx-translate/core';
</button>
}
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
:host {
@@ -56,8 +56,7 @@ import { TranslateModule } from '@ngx-translate/core';
</div>
</section>
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./content-about.component.scss'],
})
export class ContentAboutComponent {
@@ -44,8 +44,7 @@ import {
imports: [ContentHeroComponent, ContentAboutComponent, NgTemplateOutlet],
templateUrl: './portal-detail-shell.component.html',
styleUrls: ['./portal-detail-shell.component.scss'],
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
tabindex: '0',
role: 'region',
@@ -19,8 +19,7 @@ import {
></div>
</div>
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
.progress-capsule {
@@ -105,8 +105,7 @@ export const EPISODE_INFO_PLAY = 'play' as const;
</button>
</div>
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
:host {
@@ -12,8 +12,7 @@ import { MatIcon } from '@angular/material/icon';
</div>
}
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
.watched-badge {
@@ -1,4 +1,4 @@
import { signal } from '@angular/core';
import { ChangeDetectorRef, signal } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { By } from '@angular/platform-browser';
@@ -72,8 +72,12 @@ describe('EpgItemDescriptionComponent', () => {
});
it('offers archive URL copying only with explicit capability and explains credentials', () => {
// The component is OnPush and dialog data is fixed once the dialog
// opens, so the test marks the component's own view after mutating it.
const componentView =
fixture.debugElement.injector.get(ChangeDetectorRef);
Object.assign(component.dialogData, { archiveUrlAvailable: true });
fixture.changeDetectorRef.markForCheck();
componentView.markForCheck();
fixture.detectChanges();
expect(
fixture.nativeElement.querySelector(
@@ -84,7 +88,7 @@ describe('EpgItemDescriptionComponent', () => {
'EPG.PROGRAM_DIALOG.ARCHIVE_URL_NOTICE'
);
Object.assign(component.dialogData, { archiveUrlAvailable: false });
fixture.changeDetectorRef.markForCheck();
componentView.markForCheck();
fixture.detectChanges();
expect(
fixture.nativeElement.querySelector(
@@ -38,7 +38,7 @@ export type EpgItemDialogData = EpgProgram & {
selector: 'app-epg-item-description',
templateUrl: './epg-item-description.component.html',
styleUrls: ['./epg-item-description.component.scss'],
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [DatePipe, MatDialogModule, MatIcon, TranslatePipe],
})
export class EpgItemDescriptionComponent {
@@ -32,7 +32,7 @@ interface EpgTrustConfirmDialogData {
@Component({
selector: 'app-epg-trust-confirm-dialog',
imports: [MatButtonModule, MatDialogModule, TranslatePipe],
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<h2 mat-dialog-title>{{ data.title }}</h2>
<mat-dialog-content class="mat-typography">
@@ -64,7 +64,7 @@ class EpgTrustConfirmDialogComponent {
TranslatePipe,
],
templateUrl: './epg-progress-panel.component.html',
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrl: './epg-progress-panel.component.scss',
})
export class EpgProgressPanelComponent {
@@ -30,7 +30,7 @@ type BadgeStatus =
TranslatePipe,
],
templateUrl: './epg-source-status.component.html',
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrl: './epg-source-status.component.scss',
})
export class EpgSourceStatusComponent implements OnInit {