0
0
Angularframework~15 mins

Pure vs impure pipes in Angular - Trade-offs & Expert Analysis

Choose your learning style9 modes available
Overview - Pure vs impure pipes
What is it?
In Angular, pipes are simple functions that transform data in templates. Pure pipes run only when their input changes, making them efficient. Impure pipes run on every change detection cycle, even if inputs stay the same. This difference affects performance and when updates appear in the UI.
Why it matters
Without understanding pure and impure pipes, apps can become slow or show outdated data. Pure pipes help keep apps fast by avoiding unnecessary work. Impure pipes allow updates when inputs are complex or change internally. Knowing when to use each keeps apps responsive and efficient.
Where it fits
Before this, learners should know Angular templates and basic pipes. After this, they can learn about custom pipes, change detection, and performance optimization in Angular.
Mental Model
Core Idea
Pure pipes run only when inputs change by reference, while impure pipes run every time Angular checks for changes, regardless of input changes.
Think of it like...
Imagine a mail sorter who only checks new mail (pure pipe) versus one who checks every single letter repeatedly even if nothing new arrived (impure pipe). The first is efficient, the second ensures nothing is missed but wastes time.
┌───────────────┐       ┌───────────────┐
│   Input Data  │──────▶│   Pure Pipe   │
│ (reference)   │       │(runs if input │
└───────────────┘       │ changes only) │
                        └──────┬────────┘
                               │
                               ▼
                        ┌───────────────┐
                        │ Transformed   │
                        │   Output      │
                        └───────────────┘


┌───────────────┐       ┌───────────────┐
│   Input Data  │──────▶│  Impure Pipe  │
│ (any change)  │       │(runs every   │
└───────────────┘       │ change check) │
                        └──────┬────────┘
                               │
                               ▼
                        ┌───────────────┐
                        │ Transformed   │
                        │   Output      │
                        └───────────────┘
Build-Up - 7 Steps
1
FoundationWhat is an Angular pipe?
🤔
Concept: Introduce the basic idea of pipes as data transformers in Angular templates.
Pipes take input data and transform it to a desired output format inside Angular templates. For example, the built-in 'date' pipe formats dates nicely. You use pipes with the | symbol, like {{ birthday | date:'shortDate' }}.
Result
You see formatted data in the UI without changing the original data in the component.
Understanding pipes as simple, reusable data formatters helps you separate display logic from business logic.
2
FoundationHow Angular detects changes
🤔
Concept: Explain Angular's change detection and how it decides when to update the UI.
Angular runs change detection frequently to check if data changed. It compares object references to detect changes quickly. If a reference changes, Angular updates the UI. If not, it assumes data is the same.
Result
Angular efficiently updates only parts of the UI that need refreshing.
Knowing Angular uses reference checks helps understand why some updates appear and others don't.
3
IntermediatePure pipes run only on input change
🤔Before reading on: do you think pure pipes run every time Angular checks for changes or only when inputs change? Commit to your answer.
Concept: Pure pipes run only when their input reference changes, not on every change detection cycle.
By default, pipes are pure. Angular calls a pure pipe only if the input value's reference changes. For example, if you pass a string or number that changes, the pipe runs. But if you pass an object or array and only mutate it without changing the reference, the pipe won't run again.
Result
Pure pipes improve performance by avoiding unnecessary recalculations.
Understanding pure pipes rely on reference changes explains why some UI updates may not appear if data is mutated instead of replaced.
4
IntermediateImpure pipes run every change detection
🤔Before reading on: do you think impure pipes run less often, the same, or more often than pure pipes? Commit to your answer.
Concept: Impure pipes run on every Angular change detection cycle, regardless of input changes.
You mark a pipe as impure by setting pure: false in its decorator. Angular then calls it every time change detection runs, even if inputs are the same. This is useful when inputs are complex objects that change internally without changing reference, like arrays with added items.
Result
Impure pipes ensure UI updates for internal changes but can hurt performance if overused.
Knowing impure pipes run often helps you decide when to use them carefully to balance correctness and speed.
5
IntermediateDetecting pure vs impure pipe behavior
🤔Before reading on: if you mutate an array passed to a pure pipe, will the pipe run again? Commit to your answer.
Concept: Show how pure pipes ignore internal mutations, while impure pipes detect them.
Example: Pass an array to a pure pipe that formats it. If you add an item by pushing to the array, the pure pipe won't run because the array reference is unchanged. But if you replace the array with a new one, the pure pipe runs. An impure pipe runs on every change detection, so it notices the push without replacing the array.
Result
Pure pipes miss internal mutations; impure pipes catch them.
Understanding this difference prevents bugs where UI doesn't update after data changes.
6
AdvancedPerformance trade-offs of pipe purity
🤔Before reading on: do you think impure pipes always slow down apps significantly? Commit to your answer.
Concept: Explore how pipe purity affects app speed and when impure pipes are acceptable.
Pure pipes run less often, so they save CPU time. Impure pipes run every change detection, which can slow down apps if the pipe logic is heavy or the app is large. However, impure pipes are necessary when inputs change internally without new references. Developers must balance correctness and performance by choosing pipe purity wisely.
Result
Using impure pipes unnecessarily can degrade performance; using pure pipes incorrectly can cause stale UI.
Knowing the cost of impure pipes guides better design decisions for scalable apps.
7
ExpertHow Angular internally manages pipe calls
🤔Before reading on: do you think Angular stores pipe results or recreates pipes every time? Commit to your answer.
Concept: Reveal Angular's internal caching and lifecycle of pure and impure pipes.
Angular creates one instance of each pipe per component and caches the last input and output for pure pipes. It compares new inputs by reference to decide if it should call the transform method again. For impure pipes, Angular calls transform every change detection without caching results. This internal design optimizes performance and memory use.
Result
Angular efficiently reuses pipe instances and avoids unnecessary work for pure pipes.
Understanding Angular's caching explains why pure pipes depend on immutable inputs and why impure pipes are more costly.
Under the Hood
Angular creates one pipe instance per component and stores the last input and output for pure pipes. During change detection, Angular compares the current input reference with the cached one. If different, it calls the pipe's transform method and updates the cache. For impure pipes, Angular calls transform every cycle without caching. This mechanism relies on JavaScript's reference equality to detect changes efficiently.
Why designed this way?
This design balances performance and correctness. Pure pipes optimize by avoiding repeated work when inputs don't change, leveraging immutable data patterns. Impure pipes exist to handle cases where inputs mutate internally without changing references, which pure pipes can't detect. Alternatives like always running pipes would waste CPU, while never running impure pipes would cause stale UI. This approach fits Angular's reactive and template-driven model.
┌───────────────────────────────┐
│       Angular Component       │
│ ┌───────────────────────────┐ │
│ │       Pipe Instance       │ │
│ │ ┌───────────────────────┐ │ │
│ │ │  Cached Input Ref     │ │ │
│ │ │  Cached Output Value  │ │ │
│ │ └─────────┬─────────────┘ │ │
│ └───────────┼───────────────┘ │
└─────────────┼─────────────────┘
              │
    Change Detection Cycle
              │
    ┌─────────▼─────────┐
    │ Compare Input Ref  │
    ├─────────┬─────────┤
    │ Equal?  │ Not Equal│
    │         │          │
    ▼         ▼          ▼
  Skip    Call transform  Update cache
  pipe    method          with new input
  call

For impure pipes:
Every cycle calls transform without caching.
Myth Busters - 4 Common Misconceptions
Quick: Do pure pipes detect changes inside objects or arrays if their reference stays the same? Commit to yes or no.
Common Belief:Pure pipes detect any change in input data, even inside objects or arrays.
Tap to reveal reality
Reality:Pure pipes only detect changes if the input reference changes, not internal mutations.
Why it matters:Believing this causes bugs where UI does not update after mutating data, confusing developers.
Quick: Do impure pipes always cause severe performance problems? Commit to yes or no.
Common Belief:Impure pipes always make Angular apps slow and should be avoided.
Tap to reveal reality
Reality:Impure pipes can impact performance but are necessary for some cases; used carefully, they don't always cause problems.
Why it matters:Avoiding impure pipes entirely can lead to stale UI when data changes internally.
Quick: Does Angular create a new pipe instance every time it runs change detection? Commit to yes or no.
Common Belief:Angular creates new pipe instances on every change detection cycle.
Tap to reveal reality
Reality:Angular creates one pipe instance per component and reuses it, caching results for pure pipes.
Why it matters:Thinking pipes are recreated wastes mental energy and leads to misunderstanding performance.
Quick: Can you make any pipe impure by just changing its code? Commit to yes or no.
Common Belief:Any pipe can be impure simply by writing different code inside it.
Tap to reveal reality
Reality:Impurity is controlled by the pipe's decorator setting (pure: false), not by pipe code alone.
Why it matters:Misunderstanding this causes confusion about how Angular decides when to run pipes.
Expert Zone
1
Pure pipes rely heavily on immutable data patterns; using mutable data structures can silently break UI updates.
2
Impure pipes can cause subtle bugs if their transform method has side effects, as they run frequently and unpredictably.
3
Angular's change detection strategy (Default vs OnPush) interacts with pipe purity, affecting when pipes run.
When NOT to use
Avoid impure pipes in large or complex apps where performance is critical; instead, use pure pipes with immutable data or manual change detection triggers. For complex transformations, consider using Observables with async pipes or memoization techniques.
Production Patterns
In real apps, developers use pure pipes for formatting and simple transformations. Impure pipes are reserved for cases like filtering or sorting arrays that mutate internally. Teams often combine OnPush change detection with pure pipes to maximize performance.
Connections
Immutable Data Structures
Pure pipes depend on immutable data to detect changes by reference.
Understanding immutable data helps grasp why pure pipes only run on new references, preventing stale UI.
React useMemo Hook
Both optimize expensive computations by caching results based on dependencies.
Knowing React's useMemo clarifies how Angular caches pure pipe outputs to avoid unnecessary recalculations.
Cache Invalidation in Web Browsers
Both involve deciding when to refresh data based on changes to avoid stale content or wasted work.
Understanding cache invalidation helps appreciate Angular's strategy of running pipes only when inputs change.
Common Pitfalls
#1Mutating an array passed to a pure pipe expecting UI update.
Wrong approach:this.items.push(newItem); // UI does not update because pure pipe input reference unchanged
Correct approach:this.items = [...this.items, newItem]; // new array reference triggers pure pipe
Root cause:Pure pipes detect changes by reference, so mutating the same array does not trigger re-run.
#2Marking all pipes as impure to fix update issues without considering performance.
Wrong approach:@Pipe({name: 'filter', pure: false}) export class FilterPipe { ... } // used everywhere
Correct approach:Use pure pipes with immutable data or manual triggers; reserve impure pipes for special cases only.
Root cause:Impure pipes run every change detection, causing performance degradation if overused.
#3Assuming Angular recreates pipe instances every change detection.
Wrong approach:Writing code that relies on pipe constructor running multiple times per cycle.
Correct approach:Understand Angular creates one pipe instance per component and reuses it.
Root cause:Misunderstanding Angular's pipe lifecycle leads to incorrect assumptions about state and performance.
Key Takeaways
Angular pipes transform data in templates and can be pure or impure based on how often they run.
Pure pipes run only when input references change, making them efficient but requiring immutable data patterns.
Impure pipes run every change detection cycle, ensuring updates for internal mutations but potentially hurting performance.
Choosing between pure and impure pipes balances UI correctness and app speed; use impure pipes sparingly.
Understanding Angular's internal caching and change detection clarifies why pipe purity matters for app behavior.