mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
perf(ui): enable OnPush across hot list-rendering components
Audit found 10 list-rendering components (each >150 lines, all using signal-based state) on default change detection. Default CD re-checks every binding on every parent CD cycle (mouse moves, EPG progress ticks, etc.); under OnPush these only re-check when their own signals change or when explicitly markedForCheck. All 10 use signals exclusively for state (no manual subscribe-and-mutate patterns), so the conversion is straightforward and safe. Components: - recent-playlists (740L) — homepage playlist list with drag-drop - vod-details-route (552L) — Xtream VOD detail page - playlist-switcher (509L) — workspace shell playlist switcher - season-container (444L) — Stalker/Xtream series episodes (DoCheck preserved) - stalker-search (362L) — Stalker search results - search-results (350L) — Xtream search results - category-management-dialog (199L) — manage Xtream categories - recently-added (162L) — Xtream recently-added rail - category-content-view (Catalog) — category browse page - grid-list (shared) — generic grid renderer used across portals Tests: 124 passed across all touched lib projects. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 2e1a36e2f0f6
This commit is contained in:
1 parent
c44e4e6f83
commit
2f7406054d
10 files changed
+33
-3
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { DatePipe, DOCUMENT } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
DestroyRef,
|
||||
@@ -53,6 +54,7 @@ const DEFAULT_PLAYLIST_TYPE_FILTERS: Record<PlaylistFilterType, boolean> = {
|
||||
selector: 'app-playlist-switcher',
|
||||
templateUrl: './playlist-switcher.component.html',
|
||||
styleUrls: ['./playlist-switcher.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
DatePipe,
|
||||
FormsModule,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
moveItemInArray,
|
||||
} from '@angular/cdk/drag-drop';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
effect,
|
||||
inject,
|
||||
@@ -62,6 +63,7 @@ type PlaylistBusyOperation = {
|
||||
selector: 'app-recent-playlists',
|
||||
templateUrl: './recent-playlists.component.html',
|
||||
styleUrls: ['./recent-playlists.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
DragDropModule,
|
||||
EmptyStateComponent,
|
||||
|
||||
+2
@@ -1,5 +1,6 @@
|
||||
import { NgComponentOutlet } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
DestroyRef,
|
||||
@@ -44,6 +45,7 @@ interface CategoryContentItem {
|
||||
selector: 'app-category-content-view',
|
||||
templateUrl: './category-content-view.component.html',
|
||||
styleUrls: ['./category-content-view.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
GridListComponent,
|
||||
MatIcon,
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { Component, computed, input, output } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
output,
|
||||
} from '@angular/core';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatPaginatorModule, PageEvent } from '@angular/material/paginator';
|
||||
@@ -177,6 +183,7 @@ export function resolveGridRating(
|
||||
ProgressCapsuleComponent,
|
||||
WatchedBadgeComponent,
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class GridListComponent {
|
||||
readonly items = input<GridListItem[]>();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
effect,
|
||||
@@ -71,6 +72,7 @@ interface StalkerSearchResponse {
|
||||
],
|
||||
templateUrl: './stalker-search.component.html',
|
||||
styleUrl: './stalker-search.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class StalkerSearchComponent {
|
||||
private readonly activatedRoute = inject(ActivatedRoute);
|
||||
|
||||
+9
-1
@@ -1,4 +1,11 @@
|
||||
import { Component, computed, inject, OnInit, signal } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
inject,
|
||||
OnInit,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import {
|
||||
@@ -35,6 +42,7 @@ interface CategoryWithSelection extends XCategoryFromDb {
|
||||
],
|
||||
templateUrl: './category-management-dialog.component.html',
|
||||
styleUrl: './category-management-dialog.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CategoryManagementDialogComponent implements OnInit {
|
||||
private readonly dbService = inject(DatabaseService);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, computed, inject } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
@@ -33,6 +33,7 @@ const SKELETON_CARDS_PER_RAIL = [1, 2, 3, 4, 5, 6] as const;
|
||||
selector: 'app-recently-added',
|
||||
templateUrl: './recently-added.component.html',
|
||||
styleUrls: ['./recently-added.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ContentCardComponent, ContentRailShellComponent, TranslatePipe],
|
||||
})
|
||||
export class RecentlyAddedComponent {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { KeyValuePipe } from '@angular/common';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
effect,
|
||||
@@ -58,6 +59,7 @@ function groupResultsByPlaylistName(
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-results',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
ContentCardComponent,
|
||||
FormsModule,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Location, SlicePipe } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
@@ -44,6 +45,7 @@ import {
|
||||
'../../../../../../ui/components/src/lib/styles/detail-view.scss',
|
||||
'./vod-details-route.component.scss',
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
ContentHeroComponent,
|
||||
MatIcon,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { KeyValuePipe } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
DoCheck,
|
||||
OnInit,
|
||||
@@ -67,6 +68,7 @@ function parseDuration(duration: string | number | undefined): number {
|
||||
selector: 'app-season-container',
|
||||
templateUrl: './season-container.component.html',
|
||||
styleUrls: ['./season-container.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
KeyValuePipe,
|
||||
MatButtonModule,
|
||||
|
||||
Reference in new issue
Block a user