title: Angular - Speed up filtering and display of *ngFor
body: <p>I have a list of users (at the moment about 450) which I filter using a onValueChanges subscription and javascript filter method. It seems pretty slow. I believe it should be quicker but am unsure if it is the actual filtering of the object or the rerendering the html that is slow.</p>
  <p>When I recreated it in stackBlitz it is super fast so am not sure why it is slow to show the filtered items in my project.</p>
  <p>The actual object is little different but not by much</p>
  <pre><code>address: null
  emailAddress: &quot;fred.bloggs@example.com&quot;
  employeeId: 1
  extraPhoneNumber: null
  fullName: &quot;Administrator Account&quot;
  jobTitle: &quot;Learning Administrator&quot;
  personId: 52
  phoneNumber: &quot;01234567890&quot;
  photograph: null
  searchTerms: &quot;Administrator Account, 1, Learning Administrator&quot;
  totalAlerts: 0
  totalCompleted: 0
  totalMandatory: 0
  totalOverdue: 0
  totalToDo: 0
  </code></pre>
  <p>My Html</p>
  <pre><code>&lt;form class=&quot;&quot; [formGroup]=&quot;myForm&quot;&gt;
     &lt;input type=&quot;text&quot; class=&quot;input learningItemsSearch&quot; placeholder=&quot;Search My Team&quot;
       name=&quot;searchString&quot; formControlName=&quot;searchString&quot; /&gt;
  &lt;/form&gt;
   
  &lt;cdk-virtual-scroll-viewport itemSize=&quot;70&quot; class=&quot;viewport&quot;&gt;
   &lt;div *ngFor=&quot;let user of filteredUsers&quot;&gt;
              &lt;table&gt;
                  &lt;tbody&gt;
                      &lt;tr&gt;
                          &lt;td colspan=&quot;3&quot;&gt;
                              {{ user.fullName }}
                          &lt;/td&gt;
                          &lt;td colspan=&quot;3&quot;&gt;
                              {{ user.jobTitle }}
                          &lt;/td&gt;
                          &lt;td colspan=&quot;3&quot;&gt;
                                  {{ user.emailAddress }}
                          &lt;/td&gt;
                          &lt;td colspan=&quot;3&quot;&gt;
                                 {{ user.phoneNumber }}
                         &lt;/td&gt;      
                    &lt;/tr&gt;
               &lt;/tbody&gt;
           &lt;/table&gt;
      &lt;/div&gt;
   &lt;/cdk-virtual-scroll-viewport&gt;
  </code></pre>
  <p>My Component</p>
  <pre><code>this.myForm.valueChanges.pipe(
    debounceTime(400),
    distinctUntilChanged(),
    tap((value: any) =&gt; {
        let searchTerm = value.searchString;
        this.filteredUsers = this.users.filter((userName) =&gt;
          userName.searchTerms
            .toLowerCase()
            .indexOf(searchTerm.toLowerCase()) !== -1)
    })
  ).subscribe( );
  </code></pre>
  <p>Is this the most efficient way to filter an array of objects? Is there another reason why it appears to take some time to display on the screen? There is nothing too complicated in the html. I am using a cdk-virtual-scroll to see if it would load quicker but it is slow without it too.</p>
  <p><a href="https://stackblitz.com/edit/angular-ivy-filterngfor?file=src/app/app.component.ts" rel="nofollow noreferrer">StackBlitz here</a></p>
  <p><strong>EDIT:</strong> I forgot to use *cdkVirtualFor instead of *ngFor. It is a lot quicker now. I think adding the trackby mentioned below has also helped.</p>