Angular does not prohibit function calls in templates. The real concern is expensive or side-effecting work in an expression that Angular may evaluate repeatedly during change detection. Keep straightforward display logic in the template; move complex derived state into TypeScript, and profile before rewriting code for performance.
Why expensive template functions can hurt performance
Angular evaluates template expressions synchronously during change-detection checks. A costly computation in a binding can therefore add work whenever that expression is checked, delaying the rest of the check. The exact effect depends on the calculation, component detection strategy, data size, and how often checks occur; parentheses alone do not make a call a performance problem. Angular explains this in its guide to slow computations.
A cheap lookup or simple formatting expression may be perfectly reasonable. More caution is warranted when a template call performs substantial filtering or sorting, repeatedly processes a large collection, creates new objects, or causes side effects. Side effects also make behavior harder to reason about because a template expression can be evaluated as part of change detection.
Keep simple expressions; extract complex logic
Angular’s Style Guide recommends judgment rather than a blanket ban: “When the code in a template gets too complex, though, refactor logic into the TypeScript code (typically with a computed).” Bind directly to available state or use a short, straightforward expression for simple display logic. Put complex derivation somewhere its dependencies and recalculation behavior are easier to understand.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
Choose an alternative that fits the work
| Pattern | Best fit | Recalculation and caveats |
|---|---|---|
| Plain field or simple template expression | Displaying existing state or expressing genuinely straightforward logic. | Template expressions are evaluated during relevant change-detection checks; avoid hiding costly work in them. |
computed() signal |
Derived state in a signal-based component. | Computed signals are lazy and memoized, and update when tracked dependencies change. Model derived state with computed rather than an effect that propagates state; effects can cause unnecessary change-detection cycles. See Angular’s signals guide. |
| Pure pipe | A reusable transformation driven by explicit template arguments. | Runs again when a primitive input changes or an object reference changes. Mutating an array or object in place does not count as a reference change. See Angular’s pipes guide. |
| Memoization | An expensive pure computation where retaining results for multiple argument combinations is useful. | Can use significant memory when many distinct combinations are cached; choose it only when its cache behavior suits the workload. |
| Algorithm improvement | Any confirmed slow path. | Reducing the underlying work is often more effective than changing syntax; profile first to identify the actual bottleneck. |
Example: derive a filtered list once
Suppose a template calls getVisibleItems() to filter a large collection. If the call repeats the same expensive derivation during checks, a computed signal can express the result as state derived from its dependencies:
readonly query = signal('');
readonly items = signal<Item[]>([]);
readonly visibleItems = computed(() => {
const query = this.query().toLowerCase();
return this.items().filter(item => item.name.toLowerCase().includes(query));
});
The template can then read visibleItems(). This is an illustrative pattern, not a measured performance result. It is useful when the inputs are signals and the derivation is more complex than a simple display expression; it does not guarantee a particular speedup. For a reusable transformation with explicit inputs, a pipe may be a better fit.
Rank #2
Account for pure-pipe mutation behavior
Pure pipes respond to changed primitive values or changed object references. If code modifies an existing array in place, a pure pipe may not run because the array reference is unchanged. Prefer updating data immutably when that matches the application design, or use another approach when mutation is required. An impure pipe runs more often and can be costly, so it is not a default workaround for a pure-pipe cache miss.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Measure before refactoring broadly
Use the Angular DevTools profiler to inspect time spent in change detection and identify components whose checks or template evaluation take substantial time. Angular’s performance guidance recommends optimizing the underlying algorithm first and considering pure pipes or memoization where appropriate. Memoization has a memory trade-off, so weigh cache size as well as computation time.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallRank #3
The profiler documentation includes example readings of 573 ms for a recorded change-detection cycle and more than 297 ms for one component’s template evaluation. Those figures describe an illustrative profiler capture, not a benchmark or typical Angular performance. Use your own application profile to decide whether a template call is the cause worth addressing.
Quick Recap
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

