0
0
Angularframework~8 mins

filter operator for selection in Angular - Performance & Optimization

Choose your learning style9 modes available
Performance: filter operator for selection
MEDIUM IMPACT
This affects how quickly the UI updates when filtering data streams, impacting interaction responsiveness and rendering speed.
Filtering a list of items based on user input in an Angular component
Angular
import { Component } from '@angular/core';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';

@Component({
  selector: 'app-filter',
  template: `<input (input)="onInput($event)" aria-label="Filter items" />
             <ul><li *ngFor="let item of filteredItems">{{item}}</li></ul>`
})
export class FilterComponent {
  items = ['apple', 'banana', 'cherry', 'date'];
  filteredItems = this.items;
  input$ = new Subject<string>();

  constructor() {
    this.input$.pipe(
      map(value => value.trim()),
      debounceTime(300),
      distinctUntilChanged(),
      filter(value => value.length > 0)
    ).subscribe(value => {
      this.filteredItems = this.items.filter(item => item.includes(value));
    });
  }

  onInput(event: Event) {
    const input = (event.target as HTMLInputElement).value;
    this.input$.next(input);
  }
}
Debouncing and filtering empty inputs reduce the number of filter operations and UI updates, improving responsiveness.
📈 Performance GainReduces reflows and repaints to one per pause in typing, improving input responsiveness and lowering CPU load.
Filtering a list of items based on user input in an Angular component
Angular
import { Component } from '@angular/core';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-filter',
  template: `<input (input)="onInput($event)" />
             <ul><li *ngFor="let item of filteredItems">{{item}}</li></ul>`
})
export class FilterComponent {
  items = ['apple', 'banana', 'cherry', 'date'];
  filteredItems = this.items;
  input$ = new Subject<string>();

  constructor() {
    this.input$.subscribe(value => {
      this.filteredItems = this.items.filter(item => item.includes(value));
    });
  }

  onInput(event: Event) {
    const input = (event.target as HTMLInputElement).value;
    this.input$.next(input);
  }
}
Subscribing directly without debounce causes filtering on every keystroke, triggering many UI updates and reflows.
📉 Performance CostTriggers multiple reflows and repaints per keystroke, causing input lag and higher CPU usage.
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Immediate filter on every keystrokeMultiple updates per inputMultiple reflows per keystrokeHigh paint cost due to frequent changes[X] Bad
Filter with debounce and distinctUntilChangedSingle update after typing pauseSingle reflow per filterLower paint cost with fewer updates[OK] Good
Rendering Pipeline
The filter operator controls when the component updates its displayed list. Frequent updates cause repeated style recalculations, layouts, and paints. Optimizing the filter timing reduces these expensive steps.
Style Calculation
Layout
Paint
⚠️ BottleneckLayout and Paint stages due to frequent DOM updates on each filter change.
Core Web Vital Affected
INP
This affects how quickly the UI updates when filtering data streams, impacting interaction responsiveness and rendering speed.
Optimization Tips
1Avoid filtering on every keystroke; use debounce to limit updates.
2Use distinctUntilChanged to skip redundant filter operations.
3Filter out empty or invalid inputs before updating the UI.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance problem when filtering data on every keystroke without debounce in Angular?
AIt causes layout shifts affecting CLS.
BIt increases bundle size significantly.
CIt causes many reflows and repaints, slowing input responsiveness.
DIt blocks the main thread for several seconds.
DevTools: Performance
How to check: Record a performance profile while typing in the filter input. Look for frequent Layout and Paint events triggered on each keystroke.
What to look for: High frequency of Layout and Paint events indicates inefficient filtering; fewer events after debounce show improved performance.