许多元素上的 ngClass 使网站速度非常慢 [英] ngClass on many elements makes site very slow

查看:25
本文介绍了许多元素上的 ngClass 使网站速度非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在我的 Angular 6 应用程序中制作树视图,我开始工作(嵌套和所有内容).我遇到的一个问题是,当我的页面有很多元素(几千个)并且它们都有 [ngClass] 时(根据所选节点显示不同的颜色),页面往往挂了很多.我创建了一个 StackBlitz 来显示我的问题:https://stackblitz.com/edit/angular-atveai

I'm currently making a tree-view in my Angular 6 application, which I got working (nested and everything). One of the problems I encounter, is that when my page has many elements (a couple of thousand) and they all have [ngClass] on them (to show different colors depending on the selected node), the page tends to hang a lot. I've created a StackBlitz to show my problem: https://stackblitz.com/edit/angular-atveai

要测试它,只需按住右侧输出屏幕上的向上/向下箭头键.它应该很慢.如果您将循环设置为仅显示 100 个元素而不是 10000 个,则它可以完美运行(因为元素较少).

To test it out, simply hold down the arrow up/down keys on the right output screen. It should be very slow. If you set the loop to only show 100 elements instead of 10000, it works flawlessly (because less elements).

为了捕捉 keydown 事件(我想要在我的文档上),我这样做:

To catch the keydown event (which I want on my document), I do this:

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

这会使用 $event 对象调用 handleKeyboardEvent().

This calls the handleKeyboardEvent() with the $event object.

在 HTML 文件中,我有一个非常简单的 *ngFor,其中每个元素都有一个 [ngClass]="GetClass(item)".基本上这会返回一个包含所有应该应用的类的对象.在我的例子中,如果所选节点等于元素,它会设置 obj["selected"] = true,这样一个元素将获得 selected 类.

In the HTML file, I have a very simple *ngFor, where each element has a [ngClass]="GetClass(item)". Basically this returns an object that contains all the classes that should be applied. In my case, if the selected node equals the element, it sets obj["selected"] = true, so that one element will get the selected class.

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

This is quite demanding, I would imagine, because each element calls this method a lot of times. That would be my guess as to why this is slow.

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

My page can easily have between 5000 and 10000 nodes (something we really don't want to change, if there's a way to fix this). However, the amount of root nodes are probably between 10 and 30. Many of the nodes are nested as children (basically 99% of them are nested).

我的想法是阻止 [ngClass] 监听更改,如果父节点 NOT 展开.未展开 = 无论如何都未显示在页面上.

My thought would be to stop [ngClass] from listening to changes, if the parent node is NOT expanded. Not expanded = not shown on the page anyway.

所以真正的问题是:如果满足条件,是否可以阻止元素监听变化?如果是这样,它甚至会有所帮助吗?因为这基本上会引入另一个侦听器,这不会真正解决任何问题.

So the real question is: Is it possible to stop elements from listening to changes, if a condition is met? And if so, would it even help? As that would basically introduce another listener, which wouldn't really solve anything.

推荐答案

所以我得到它有点像这样工作:

So I got it kinda working like this:

1) 使用变更检测 OnPush

1) Use change detection OnPush

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

2) 使用模板插值代替函数调用

2) Use template interpolation instead of function calls

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

它处理 5000 行时运行速度很快,但处理 10000 行时仍然很慢.不幸的是,我能做到的最好.

It works fast with 5000 rows, but it's still sluggish with 10000. Best I could do, unfortunately.

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

这篇关于许多元素上的 ngClass 使网站速度非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆