Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 许多元素上的ngClass使站点速度非常慢_Angular_Listener_Angular6 - Fatal编程技术网

Angular 许多元素上的ngClass使站点速度非常慢

Angular 许多元素上的ngClass使站点速度非常慢,angular,listener,angular6,Angular,Listener,Angular6,目前,我正在Angular 6应用程序中创建一个树视图,我正在使用它(嵌套的和所有东西)。我遇到的一个问题是,当我的页面有许多元素(几千个)并且它们上面都有[ngClass](根据所选节点显示不同的颜色)时,页面往往会挂起很多。我创建了一个StackBlitz来显示我的问题: 要测试它,只需按住右输出屏幕上的向上/向下箭头键。应该很慢。如果将循环设置为仅显示100个元素,而不是10000个元素,则它可以完美地工作(因为元素较少) 要捕获keydown事件(我希望在文档中看到),我执行以下操作:

目前,我正在Angular 6应用程序中创建一个树视图,我正在使用它(嵌套的和所有东西)。我遇到的一个问题是,当我的页面有许多元素(几千个)并且它们上面都有
[ngClass]
(根据所选节点显示不同的颜色)时,页面往往会挂起很多。我创建了一个StackBlitz来显示我的问题:

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

要捕获keydown事件(我希望在文档中看到),我执行以下操作:

@Component({
  host: {
    '(document:keydown)': 'handleKeyboardEvent($event)'
  }
})
这将使用
$event
对象调用
handleKeyboardEvent()

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

我想,这是相当苛刻的,因为每个元素都多次调用这个方法。这是我的猜测,为什么这是缓慢的

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

我的想法是,如果父节点未展开,则阻止
[ngClass]
侦听更改。未展开=页面上仍不显示

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

所以我的工作原理是这样的:

1) 在推送上使用更改检测

@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>
{{item.name}
它在5000行时运行得很快,但在10000行时仍然很慢。不幸的是,我已经尽力了


它对我来说并不慢,所以我无法测试它。尝试1)每次返回相同的对象,而不是实例化一个新对象。2) 根本不要调用函数,在模板中计算内容。3) 尝试使用getter而不是普通函数。这两种方法中的任何一种都可以让它跑得更快。Angular将在每个更改检测周期调用函数,并每次实例化和垃圾收集这些对象。4)在handleKeyboardEvent方法中设置样式,这样您对文档只有一个函数调用。@ritaj只是确保:您确实按住箭头键几秒钟,然后放手,对吗?在我的电脑(i7-7700k和32GB RAM)和办公室里的其他电脑上,它不像100个元素那样滚动。哦,对了,我把它设置为1000,它工作了,但在3000左右它开始工作缓慢。是的,这似乎不是一个好的解决方案。我尝试在handleKeyboardEvent中处理样式设置,但由于document.querySelector的原因,它仍然很慢。现在我将尝试使用ViewChildren。使用ChangeDetectionStragety.OnPush肯定会大大提高性能!简单地根据状态在类中进行相应的解析,也比[ngClass]快得多。非常感谢-它现在可以与5000多个元素配合使用!我想说的是,用
class
+模板插值替换
ngClass
对我来说是个赢家。我只是将一个速度慢得离谱的模板(将UI线程锁定一分钟)的渲染时间降低到15毫秒:)更改检测已经设置为
OnPush
,没有太大帮助,所以我惊讶并高兴地发现插值如此有效!谢谢