代码之家  ›  专栏  ›  技术社区  ›  MortenMoulder

许多元素上的ngClass使得站点非常慢

  •  1
  • MortenMoulder  · 技术社区  · 6 年前

    我现在正在Angular 6应用程序中创建一个树视图,这个应用程序正在运行(嵌套的和所有的)。我遇到的一个问题是,当我的页面有很多元素(几千个)而它们都有 [ngClass] 在它们上面(根据所选节点显示不同的颜色),页面往往会挂起很多。我创建了一个StackBlitz来显示我的问题: https://stackblitz.com/edit/angular-atveai

    要测试它,只需按住右输出屏幕上的向上/向下箭头键。应该很慢。如果将循环设置为仅显示100个元素而不是10000个元素,那么它将完美地工作(因为元素较少)。

    为了捕捉keydown事件(我想在我的文档中看到),我执行以下操作:

    @Component({
      host: {
        '(document:keydown)': 'handleKeyboardEvent($event)'
      }
    })
    

    handleKeyboardEvent() $event 对象。

    *ngFor [ngClass]="GetClass(item)" . 基本上,它返回一个包含所有应该应用的类的对象。在我的例子中,如果所选节点等于元素,它将 obj["selected"] = true ,这样一个元素将得到 selected

    我可以想象,这要求很高,因为每个元素都会多次调用此方法。这就是我的猜测,为什么这是缓慢的。

    我的页面可以很容易地拥有5000到10000个节点(如果有办法解决这个问题的话,我们真的不想改变这一点)。但是,根节点的数量可能在10到30之间。许多节点都是作为子节点嵌套的(基本上99%的节点是嵌套的)。

    如果父节点 不是 扩大。Not expanded=仍不显示在页面上。

    因此,真正的问题是:如果满足某个条件,是否有可能阻止元素监听更改?如果是这样的话,会有帮助吗?因为这基本上会引入另一个侦听器,这并不能真正解决任何问题。

    1 回复  |  直到 6 年前
        1
  •  5
  •   Roberto Zvjerković sabithpocker    6 年前

    所以我明白了 有点 像这样工作:

    1) 使用更改检测OnPush

    @Component({
          selector: 'my-app',
          templateUrl: './app.component.html',
          styleUrls: ['./app.component.css'],
          host: {
            '(document:keydown)': 'handleKeyboardEvent($event)'
          },
          changeDetection: ChangeDetectionStrategy.OnPush
        })
    

    2) 使用模板插值而不是函数调用

    <span class="{{item.state === 'failed' ? 'failed' : 'completed'}} {{item.ordering === selected ? 'selected' : ''}}">{{item.name}}</span>
    

    它的速度很快,有5000行,但仍然很慢,有10000行。

    https://stackblitz.com/edit/angular-1sg1mh?file=src%2Fapp%2Fapp.component.ts