gpt4 book ai didi

javascript - 在 Angular 2 中应用频繁 CSS 更改的最有效方法

转载 作者:可可西里 更新时间:2023-11-01 01:43:45 25 4
gpt4 key购买 nike

我们有一个 Angular 2 站点,其中有一个 websocket 将数据从后端泵入我们的网格。为了指示最近的更新,我们使用 CSS 设置行的背景颜色和受影响的单元格上的粗体。

指示应该只持续很短的时间。

1) 我们的第一次尝试是在下一批从服务器到达时重置所有指标。这运行良好,但在某些 View 中很少有更新,这意味着指标可以保持很长时间,这有点令人困惑。

如果更新指示器在固定时间间隔(例如 4 秒)后消失会更加一致。

2) 我们的下一个尝试是使用 CSS 动画。但是过了一会儿,它就滞后了很多。给人的印象是运行过多的动画会使浏览器过载,无法处理请求的时间。也许每个动画在后台都有自己的计时器?

3) 第三种尝试是让一个计时器以固定的时间间隔运行,然后检查要重置哪些记录。我们创建了一个 TimerService,它将定期检查到期元素。将元素添加到计时器池时,可以配置任意等待时间。

这行得通,但是在日志窗口中经常出现违规警告:

[Violation] 'setInterval' handler took 56ms
[Violation] 'setInterval' handler took 74ms
[Violation] 'setInterval' handler took 63ms
[Violation] 'setInterval' handler took 88ms
...

但是当我们对 checkItems 方法内部发生的事情进行计时时,它只需要 0.03 毫秒!

  • 我们都有 C# 背景并且刚刚使用 Angular 几个月。也许我们正在实现后端方法?

  • 是否发生了我们错过的上下文切换?

  • 有没有更前端友好的替代方法?

  • 我们可以对我们的代码进行一些重要的优化吗?

感谢所有建议!

这是导致所有警告的建议 TimerService:

import { Injectable, OnInit } from "@angular/core";
import { Observable } from "rxjs/Rx";
import { Subject } from "rxjs/Subject";

@Injectable()
export class TimerService {
private timerItems: TimerItem[] = [];
private dueTimeReachedSubject: Subject<string> = new Subject<string>();
public dueTimeReached: Observable<string> = this.dueTimeReachedSubject.asObservable();

constructor() {
setInterval(() => this.checkItems(), 1000);
}

private checkItems() {
let now = Date.now();
let removeKeys: string[] = [];
this.timerItems.filter(t => t.dueTime <= now).forEach(t => {
this.dueTimeReachedSubject.next(t.key);
removeKeys.push(t.key);
});
this.timerItems = this.timerItems.filter(t => removeKeys.indexOf(t.key) < 0);
}

public add(key: string, delayInSeconds: number) {
let dueTime = Date.now() + delayInSeconds * 1000;
let timerItem = this.timerItems.find(t => t.key === key);
if (timerItem) {
timerItem.dueTime = dueTime;
}
else {
this.timerItems.push(new TimerItem(key, dueTime));
}
}

public remove(key: string) {
this.timerItems = this.timerItems.filter(t => t.key !== key);
}
}


class TimerItem {
constructor(public key: string, public dueTime: number) { }
}

编辑

我尝试使用 Observable.interval: Same result with exactly the same warning message: "[Violation] 'setInterval' handler take xx ms"

我尝试将 setTimeout 用于重复调用:相同的结果,但修改了警​​告消息:“[Violation] 'setTimeout' 处理程序占用了 xx 毫秒”

我什至尝试清空每一行的 checkItems,但我仍然收到警告。

警告是从 zone.js 内部抛出的,似乎是 Angular 内部推荐。我知道我可以在 Chrome 开发者工具中关闭详细日志记录,但我经常将 console.debug 用于开发目的,这意味着它们也会消失。

我猜对于慢速函数来说警告是可以的,但在这种情况下它只是触发一个 setInterval 函数。为什么会这么慢?

最佳答案

在这样的站点中可以做很多事情。

第一个是将 ChangeDetectionStrategy 更改为 ChangeDetectionStrategy.onPush ,然后仅在需要时激活检测,在您的情况下,在 checkItems 的末尾添加和删除.这将大大减少脚本编写,因为只有在被询问时,angular 才需要评估您的 html

你可以做的第二件事是检查你的寺庙是否有一个函数调用在 *ngIf*ngFor,如果你这样做,angular 将无法缓存此函数返回的值,并且必须为每次检查处理它们

您应该考虑的第三件事是优化 checkItems,在 O(n^2) 中运行 checkItems 并执行许多不必要的循环。你可以减少它

checkItems() {
this.timerItems = this.timerItems.filter(t => {
if(t.dueTime <= now){
this.dueTimeReachedSubject.next(t.key);
return false;
}
return true;
});
}

对于小型阵列,它不会有太大帮助,但越大,这个变化就会开始生效..

我想还有更多事情可以做,但这 3 件事帮助我解决了类似的性能问题

关于javascript - 在 Angular 2 中应用频繁 CSS 更改的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44043151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com