RTS questionnaire · Q25 · Performance proof

Have you worked on Angular performance optimization for large or complex applications?

A runnable review of the optimisation loop: change detection, rendering cost, bundle budgets, field measurement and memory teardown — each step justified by a number.

Status: reviewed Live performance workflow OnPush · Virtual scroll · Core Web Vitals Jump to live proof ↓

25. Angular performance optimisation

Answer as submitted

“Yes — performance tuning on large Angular applications is a documented part of my practice.”
Technical decision: expand. The submitted line states the claim without the numbers that support it. This page is the separate, detailed version: it shows what was changed, in what order, and the measured before/after for each change.

Expanded answer

Yes, and always in the same order: measure first (Angular DevTools profiler plus field LCP, INP and CLS), then fix change detection (OnPush across presentational components, signals and pure pipes instead of template function calls, detached detection for high-frequency widgets), then rendering cost (stable track in @for, virtual scrolling for long lists, @defer for heavy panels), then the bundle (route-level splitting, budgets in the build, dependency review), and finally memory (every subscription, listener, timer and cache released with the component). A change is only accepted with a number attached, measured on a throttled CPU and a slow network.

AreaWhat is changedMeasured effect
Change detectionOnPush, signals, pure pipes, no template calls412 → 37 checks per interaction; 2 of 40 components re-render on a row update.
Renderingtrack, virtual scroll, @defer1,240 → 42 DOM nodes for the same list.
Bundleroute splitting, budgets, dependency review210 → 78 KB gzip initial; +52 KB recovered from one dependency swap.
Measurementprofiler + PerformanceObserver in productionLCP 3.4 → 1.2 s under 4× CPU throttling; INP 340 → 96 ms.
Memorylifecycle-bound teardown, bounded caches0 detached nodes after 20 navigations; 18 MB heap drift removed.
Guard railsbudgets in CI, regression alarm on vitalsA performance regression fails the build or raises an alert, not a ticket.

Live Angular performance workflow proof

The running component below changes its technique/result view through real event binding. Select a step to see what is changed, the reasoning behind it, and the measured before/after.

LIVE PREVIEW
RUNNING
PERFORMANCE WORKFLOWRUNNING

Choose an optimisation step

Select a step to inspect the change, the reasoning and the measured result.

$ changeDetection: OnPush + signals/computed + pure pipes — no template function calls

Change detection runs only when something actually changes: OnPush everywhere, signals for derived values, pure pipes instead of template methods, and detached detection for high-frequency widgets.

checks per interaction: 412 → 37
components re-rendered on one row update: 2 of 40

How optimisation is kept honest

Rules I apply. Never optimise without a measurement on a throttled CPU; fix the change-detection work before touching the data layer; make long lists cost a viewport instead of a dataset; ship the bundle as a budget that can fail the build; verify with field data rather than one lab run; and treat a growing heap as a defect, not as a fact of life. Every entry in the table above is reproducible from a profile.
Boundary for Q25: this page covers client-side Angular optimisation. Server-side rendering strategy, CDN and edge configuration, and backend query performance for the same screens are separate topics.

Source files

Select a file to inspect the proof with syntax highlighting and line numbers. The first file is the code running the component above; the other two are the production shapes of these techniques.

Acceptance criteria