All topics
Performancebeginner

Pure Pipes for Performance

Explain how pure (the default) pipes avoid unnecessary recomputation compared to impure pipes.

Angular pipes are, by default, "pure" — meaning Angular only re-invokes the pipe's transform() method when its input value actually changes by reference (or by value, for primitives), not on every single change detection cycle regardless of whether anything relevant changed. This default behavior is a meaningful, largely invisible performance optimization, and interviewers ask about it to check whether you understand why this matters and what happens if you deliberately opt out of it.

A pure pipe is like a calculator's memory function that only recalculates when you actually enter new numbers, instantly recalling the previous answer if you press equals again on the same input; an impure pipe recalculates from scratch every single time you glance at the display, whether or not the numbers changed.

Key Concepts

1
A pure pipe's memoization works the same way OnPush change detection's reference-equality check does: transforming the same array reference twice in a row, even if you mutated its contents in place between calls, produces the cached previous result rather than re-running transform(), since the pipe only compares by reference — this is exactly the kind of subtlety that trips developers up until they internalize the immutability discipline that both pure pipes and OnPush components rely on.
OnPushtransform()
2
pure: false (impure pipes) disables this optimization entirely, forcing transform() to re-run on every single change detection cycle regardless of whether the input actually changed — necessary for genuinely impure operations (like a pipe that needs to reflect the current time, or one that operates on a mutable array where you specifically want it to detect in-place mutations), but a real, measurable performance cost if used carelessly, especially inside a large, frequently-updated list where an impure pipe runs on every row on every single change detection pass.
pure: falsetransform()
3
A sharp interview answer connects this back to Angular's own built-in AsyncPipe, which is actually implemented as an impure pipe deliberately, since it needs to detect new emissions from its subscribed Observable on every change detection cycle, not just when the Observable reference itself changes — a good concrete example that "impure" isn't inherently bad, just a deliberate trade-off that should be made consciously rather than by accident.
AsyncPipe