Step 13: Change Detection Issue

The Problem

Even with OnPush change detection, poor component design can lead to unnecessary re-renders. In this example, typing in the search input causes all cards to re-render.

Issues:

  • Every keystroke triggers change detection for all cards
  • OnPush doesn't help because the parent component updates
  • Performance degrades with more items
  • Unnecessary DOM updates

Problematic Code:


          @Component({
  template:
    <input [(ngModel)]="searchTerm">
    <div *ngFor="let card of filteredCards">
       { card.title }
    </div>

})
export class ProblematicComponent {
  searchTerm = '';
  cards: Card[] = [];

  get filteredCards() {
    return this.cards.filter(card =>
      card.title.toLowerCase().includes(this.searchTerm.toLowerCase())
    );
  }
}
          

Type in the search box below and watch the console. Even though filtering only happens when you press Enter, notice how every card gets re-rendered on each keystroke.

Try typing and watch the render counts increase, even though the list hasn't filtered yet!

Card 1

Card 1

Renders: 2

Component rendered due to typing:

Card 2

Card 2

Renders: 2

Component rendered due to typing:

Card 3

Card 3

Renders: 2

Component rendered due to typing:

Card 4

Card 4

Renders: 2

Component rendered due to typing:

Card 5

Card 5

Renders: 2

Component rendered due to typing:

Card 6

Card 6

Renders: 2

Component rendered due to typing:

Card 7

Card 7

Renders: 2

Component rendered due to typing:

Card 8

Card 8

Renders: 2

Component rendered due to typing:

Card 9

Card 9

Renders: 2

Component rendered due to typing:

Card 10

Card 10

Renders: 2

Component rendered due to typing:

Card 11

Card 11

Renders: 2

Component rendered due to typing:

Card 12

Card 12

Renders: 2

Component rendered due to typing:

Card 13

Card 13

Renders: 2

Component rendered due to typing:

Card 14

Card 14

Renders: 2

Component rendered due to typing:

Card 15

Card 15

Renders: 2

Component rendered due to typing:

Card 16

Card 16

Renders: 2

Component rendered due to typing:

Card 17

Card 17

Renders: 2

Component rendered due to typing:

Card 18

Card 18

Renders: 2

Component rendered due to typing:

Card 19

Card 19

Renders: 2

Component rendered due to typing:

Card 20

Card 20

Renders: 2

Component rendered due to typing:

Card 21

Card 21

Renders: 2

Component rendered due to typing:

Card 22

Card 22

Renders: 2

Component rendered due to typing:

Card 23

Card 23

Renders: 2

Component rendered due to typing:

Card 24

Card 24

Renders: 2

Component rendered due to typing:

Card 25

Card 25

Renders: 2

Component rendered due to typing:

Card 26

Card 26

Renders: 2

Component rendered due to typing:

Card 27

Card 27

Renders: 2

Component rendered due to typing:

Card 28

Card 28

Renders: 2

Component rendered due to typing:

Card 29

Card 29

Renders: 2

Component rendered due to typing:

Card 30

Card 30

Renders: 2

Component rendered due to typing:

Card 31

Card 31

Renders: 2

Component rendered due to typing:

Card 32

Card 32

Renders: 2

Component rendered due to typing:

Card 33

Card 33

Renders: 2

Component rendered due to typing:

Card 34

Card 34

Renders: 2

Component rendered due to typing:

Card 35

Card 35

Renders: 2

Component rendered due to typing:

Card 36

Card 36

Renders: 2

Component rendered due to typing:

Card 37

Card 37

Renders: 2

Component rendered due to typing:

Card 38

Card 38

Renders: 2

Component rendered due to typing:

Card 39

Card 39

Renders: 2

Component rendered due to typing:

Card 40

Card 40

Renders: 2

Component rendered due to typing:

Card 41

Card 41

Renders: 2

Component rendered due to typing:

Card 42

Card 42

Renders: 2

Component rendered due to typing:

Card 43

Card 43

Renders: 2

Component rendered due to typing:

Card 44

Card 44

Renders: 2

Component rendered due to typing:

Card 45

Card 45

Renders: 2

Component rendered due to typing:

Card 46

Card 46

Renders: 2

Component rendered due to typing:

Card 47

Card 47

Renders: 2

Component rendered due to typing:

Card 48

Card 48

Renders: 2

Component rendered due to typing:

Card 49

Card 49

Renders: 2

Component rendered due to typing:

Card 50

Card 50

Renders: 2

Component rendered due to typing: