How do pure and impure pipes differ?
Angular pipes are a powerful feature that allows you to transform data in your templates. They can be categorized into two types: pure and impure pipes, each with distinct behaviors regarding change detection and re-execution.
Pure Pipes
A pure pipe is the default type for an Angular pipe. Pure pipes are optimized for performance as they only re-execute when their input values change, or when the pipe itself is instantiated. They are memoized, meaning Angular caches the output and returns the cached value if the inputs haven't changed.
- Re-execute only when the input reference changes (for objects) or the primitive value changes.
- Assumes that the pipe's internal state and output depend only on the input parameters.
- Generally more performant due to memoization.
- Cannot detect changes within mutable objects (e.g., adding an item to an array without changing its reference).
Impure Pipes
An impure pipe is one that marks itself as pure: false in its decorator. Unlike pure pipes, impure pipes are executed during every change detection cycle, regardless of whether their input values have changed. This makes them suitable for detecting changes within mutable objects or for operations that rely on external state.
- Re-execute on every change detection cycle.
- Can detect changes within mutable objects or asynchronous updates.
- Can have internal state that affects the output independently of input changes.
- Potentially less performant due to frequent re-execution, especially in large applications.
Key Differences
| Feature | Pure Pipe | Impure Pipe |
|---|---|---|
| Re-execution | Only when input reference changes | On every change detection cycle |
| Performance | Generally high (memoized) | Potentially lower (no memoization) |
| State | Stateless, output depends only on input | Can be stateful, output can depend on external factors |
| Change Detection | Shallow comparison of input reference | Deep comparison (or always re-executes) |
| Use Cases | Immutable data transformations (e.g., `DatePipe`, `CurrencyPipe`) | Mutable data transformations (e.g., `AsyncPipe`, custom filters on mutable arrays) |
When to Use Which?
You should use pure pipes whenever possible, especially for performance-critical applications. They are ideal for transformations of primitive values or objects where you can guarantee that a new object reference is created if its content changes.
Impure pipes should be used sparingly due to their performance implications. They are necessary when you need to detect changes within mutable objects (e.g., an array where items are added/removed without changing the array reference) or when working with asynchronous data streams that update frequently, like the AsyncPipe.