为什么 ng-select 提前输入会导致性能问题?

why is ng-select type ahead causing performance issues?

我正在使用 ng-select 对 select 列表中的项目进行提前输入过滤。当您键入过滤列表中第一项的结果时,性能快如闪电。然而,在你 select 第一项之后,一切都变得 非常 慢。我不太了解 rxjs,无法理解瓶颈是什么。

我的模板:

<label>Select Employees:</label>
<ng-select [items]="people$ | async"
           bindLabel="full_name"
           [multiple]="true"
           [addTag]="addCustomItem"
           [hideSelected]="true"
           [trackByFn]="trackByFn"
           [minTermLength]="2"
           [loading]="peopleLoading"
           typeToSearchText="Please enter 2 or more characters (of first OR last name)"
           [typeahead]="peopleInput$"
           [(ngModel)]="selectedPersons">
</ng-select>
<br>
<div style="margin-bottom:100px">Selected persons: {{selectedPersons | json}}</div>

我的 Typescript 组件:

import { Component, OnInit } from '@angular/core';
import { concat, Observable, of, Subject } from 'rxjs';
import { Person, Employee } from './data.service';
import { catchError, distinctUntilChanged, switchMap, tap } from 'rxjs/operators';
import { NodeHTTPService } from '../../node-http.service';

@Component({
    selector: 'app-employee-picker',
    templateUrl: './employee-picker.component.html',
    styleUrls: ['./employee-picker.component.css']
})
export class EmployeePickerComponent implements OnInit {

people$: any/*Observable<Employee[]>*/;  // you can see I had an issue here.
peopleLoading = false;
peopleInput$ = new Subject<string>();
selectedPersons: Employee[];
addCustomItem: boolean = false;  // setting this to true allows users to add custom items not in the select list.

constructor(private _nodeHTTPService: NodeHTTPService) {
    }

ngOnInit() {
        this.loadPeople();
    }

trackByFn(item: Person) {
        return item.id;
    }

private loadPeople() {
        this.people$ = concat(
            of([]), // default items
            this.peopleInput$.pipe(
                distinctUntilChanged(),
                tap(() => this.peopleLoading = true),
                switchMap(term => this._nodeHTTPService.getUsers(term).pipe(
                    catchError(() => of([])), // empty list on error
                    tap(() => this.peopleLoading = false)
                ))
            )
        );
        console.log('this.people$: ', this.people$)
        }
    }

NodeHttpService:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { CdfServiceService } from "./cdf-service.service";

@Injectable({
  providedIn: 'root'
})

export class NodeHTTPService {
  constructor(private http: HttpClient, private _cdfServiceService: CdfServiceService) { }

  getUsers(i) {
    if (!i) { i = ''};
    let users = this.http.get(`https://chq-smscqa01.chq.ei/db/users?user=${i}`)
    return users;
  }
}

非常感谢您对这个问题的任何意见!谢谢。

您可以立即做两件事来提高性能

1) 通过启用虚拟滚动实现 DOM 回收。

documentation所述,您可以将virtualScroll输入属性设置为true,这样只会加载指定数量的DOM ] 元素,它基于 ng-select 下拉列表的当前滚动容器的高度。

2) 在服务器端实现分页。这将减少每个 HTTP 请求的负载,从而使其在前端和后端都更快。

您可以将 virtualScroll 添加到您的 <ng-select>[virtualScroll]="true"