Skip to content

perf(frontend): fix slow UI rendering after /api/view response#36

Merged
wcypierre merged 1 commit into
masterfrom
perf/angular-change-detection
May 2, 2026
Merged

perf(frontend): fix slow UI rendering after /api/view response#36
wcypierre merged 1 commit into
masterfrom
perf/angular-change-detection

Conversation

@wcypierre
Copy link
Copy Markdown
Owner

Summary

  • OnPush change detection on AppComponent and TorrentComponent — Angular now only re-evaluates components when @Input references change or markForCheck() is called, instead of on every mouse move, timer tick, and click event across the full component tree
  • Eliminate duplicate torrentSearch pipe call — the footer torrent count was re-running the O(n) filter independently of the main list render; a filteredCount property is now computed once in TypeScript whenever torrents update or the search term changes
  • Fix orderBy pipe in-place mutationvalues.sort() was silently mutating this.torrents when no search term was active; changed to [...values].sort()
  • mergeMapswitchMap for polling — cancels in-flight /api/view requests when a new poll fires before the previous response returns

Root cause

The /api/view API call was fast. The bottleneck was Angular's default change detection: without OnPush, the entire component tree (including all N torrent cards and their 7 pipes each) was re-evaluated on every browser event and every 2-second timer tick. The duplicate pipe call compounded this by running the array filter twice per cycle.

Test plan

  • Run ng serve and open the app with 10+ torrents active
  • Open DevTools → Performance tab, record a few seconds — verify CD runs fire only on 2-second poll ticks, not on mouse moves
  • Verify the footer torrent count matches the visible list count, including when typing a search term
  • Change sort field and verify list re-orders correctly (no mutation side-effects)
  • Pause/resume a torrent and verify its state updates correctly (tests the markForCheck() in refreshAfter)

🤖 Generated with Claude Code

- Add ChangeDetectionStrategy.OnPush to AppComponent and TorrentComponent
  so change detection only runs when @input references change, not on
  every mouse move or timer tick
- Track filteredCount in AppComponent to replace the duplicate
  torrentSearch pipe call in the footer (was filtering the full array
  twice per CD cycle)
- Fix orderBy pipe mutating the input array in-place via values.sort();
  use [...values].sort() to avoid corrupting this.torrents
- Switch polling mergeMap to switchMap to cancel in-flight requests when
  a new poll fires before the previous response returns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@wcypierre wcypierre merged commit 342c8b0 into master May 2, 2026
4 checks passed
@wcypierre wcypierre deleted the perf/angular-change-detection branch May 2, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant