Javascript 在Angular 2中应用频繁CSS更改的最有效方法
我们有一个Angular 2站点,它有一个websocket,将数据从后端泵入网格。为了指示最近的更新,我们使用CSS为受影响的行和单元格设置背景色和粗体字体 指示只能持续很短的时间 1) 我们的第一次尝试是在下一批服务器到达时重置所有指示器。这是工作得很好,但在一些观点,很少有更新,这意味着指标可以停留很长时间,这是一种混乱 如果更新指示器在固定的时间间隔(如4秒)后消失,则会更加一致 2) 我们的下一个尝试是使用CSS动画。但过了一段时间,它落后了很多。给人的印象是,运行过多的动画会使浏览器过载,无法处理请求的时间。也许每个动画在背景中都有自己的计时器 3) 第三种尝试是让一个计时器以固定的间隔运行,然后检查要重置的记录。我们已经创建了一个TimerService,它将定期检查到期项目。将项目添加到计时器池时,可以将其配置为任意等待时间 这是可行的,但在日志窗口中经常出现违规警告:Javascript 在Angular 2中应用频繁CSS更改的最有效方法,javascript,css,angular,animation,Javascript,Css,Angular,Animation,我们有一个Angular 2站点,它有一个websocket,将数据从后端泵入网格。为了指示最近的更新,我们使用CSS为受影响的行和单元格设置背景色和粗体字体 指示只能持续很短的时间 1) 我们的第一次尝试是在下一批服务器到达时重置所有指示器。这是工作得很好,但在一些观点,很少有更新,这意味着指标可以停留很长时间,这是一种混乱 如果更新指示器在固定的时间间隔(如4秒)后消失,则会更加一致 2) 我们的下一个尝试是使用CSS动画。但过了一段时间,它落后了很多。给人的印象是,运行过多的动画会使浏览器
[Violation] 'setInterval' handler took 56ms
[Violation] 'setInterval' handler took 74ms
[Violation] 'setInterval' handler took 63ms
[Violation] 'setInterval' handler took 88ms
...
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) { }
}
但是当我们计算checkItems方法内部发生的时间时,只需要0.03毫秒
- 我们都有C#背景,刚刚与Angular合作了几个月。也许我们正在实施后端方法
- 是否存在我们错过的上下文转换
- 是否有其他更为前端友好的方法
- 我们可以对代码进行一些关键的优化吗
[Violation] 'setInterval' handler took 56ms
[Violation] 'setInterval' handler took 74ms
[Violation] 'setInterval' handler took 63ms
[Violation] 'setInterval' handler took 88ms
...
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) { }
}
从“@angular/core”导入{Injectable,OnInit};
从“rxjs/Rx”导入{Observable};
从“rxjs/Subject”导入{Subject};
@可注射()
导出类TimerService{
私有timerItems:TimerItem[]=[];
private dueTimeReachedSubject:Subject=new Subject();
public dueTimeReached:Observable=this.dueTimeReachedSubject.asObservable();
构造函数(){
setInterval(()=>this.checkItems(),1000);
}
私人支票项目(){
让现在=Date.now();
让removeKeys:字符串[]=[];
this.timerItems.filter(t=>t.dueTime{
this.dueTimeReachedSubject.next(t.key);
移除按键。按下(t键);
});
this.timerItems=this.timerItems.filter(t=>removeKeys.indexOf(t.key)<0);
}
public add(key:string,delayUnseconds:number){
让dueTime=Date.now()+delayInSeconds*1000;
让timerItem=this.timerItems.find(t=>t.key==key);
if(timerItem){
timerItem.dueTime=dueTime;
}
否则{
this.timerItems.push(new TimerItem(key,dueTime));
}
}
公共删除(键:字符串){
this.timerItems=this.timerItems.filter(t=>t.key!==key);
}
}
类时间序列{
构造函数(公钥:字符串,公钥:数字){}
}
编辑
我尝试使用Observable.interval:相同的结果,但警告消息完全相同:“[Violation]‘setInterval’处理程序花费了xx毫秒”
我尝试对重复调用使用setTimeout:结果相同,但警告消息已修改:“[违规]‘setTimeout’处理程序花费了xx毫秒”
我甚至尝试清空每行的checkItems,但仍然收到警告
警告是从zone.js中抛出的,似乎是一个有角度的内部建议。我知道我可以在Chrome开发者工具中关闭详细日志记录,但我经常使用console.debug进行开发,这意味着它们也会消失
我想对于慢速函数,警告是可以的,但在这种情况下,它只是触发了一个setInterval函数。为什么会很慢?您确定在清除checkItems中的代码后重新构建了项目吗 据我所知,它抱怨checkItems函数花费的时间太长。 也以防万一,, 我确实设置了一个 无法重新创建您的代码
如果您仍然有问题,也许您可以进行StackBlitz,并尝试在那里重新创建问题?我会放弃setInterval,只在必要时使用setTimeout
import { Injectable, OnInit } from "@angular/core";
import { Observable } from "rxjs/Rx";
import { Subject } from "rxjs/Subject";
let timer = null
@Injectable()
export class TimerService {
private timerItems: TimerItem[] = [];
private dueTimeReachedSubject: Subject<string> = new Subject<string>();
public dueTimeReached: Observable<string> = this.dueTimeReachedSubject.asObservable();
constructor() {
this.checkItems();
}
private checkItems() {
// clear the timeout
clearTimeout(timer)
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);
// only use the timer if there are timerItems
if(this.timerItems.length) {
timer = setTimeout(() => this.checkItems(), 1000)
}
}
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));
}
// check for items and engage the timer if necessary
this.checkItems()
}
public remove(key: string) {
this.timerItems = this.timerItems.filter(t => t.key !== key);
}
}
class TimerItem {
constructor(public key: string, public dueTime: number) { }
}
从“@angular/core”导入{Injectable,OnInit};
从“rxjs/Rx”导入{Observable};
从“rxjs/Subject”导入{Subject};
设定时器为空
@可注射()
导出类TimerService{
私有timerItems:TimerItem[]=[];
private dueTimeReachedSubject:Subject=new Subject();
public dueTimeReached:Observable=this.dueTimeReachedSubject.asObservable();
构造函数(){
这是checkItems();
}
私人支票项目(){
//清除超时
清除超时(计时器)
让现在=Date.now();
让removeKeys:字符串[]=[];
this.timerItems.filter(t=>t.dueTime{
this.dueTimeReachedSubject.next(t.key);
移除按键。按下(t键);
});
this.timerItems=this.timerItems.filter(t=>removeKeys.indexOf(t.key)<0);
//只有在有计时器时才使用计时器
如果(此时间毫秒长度){
timer=setTimeout(()=>this.checkItems(),1000)
}
}
public add(key:string,delayUnseconds:number){
让dueTime=Date.now()+delayInSeconds*1000;
让timerItem=this.timerItems.find(t=>t.key==key);
if(timerItem){
timerItem.dueTime=dueTime;
}
否则{
this.timerItems.push(new TimerItem(key,dueTime));
}
//检查有无物品,必要时接合计时器
这是checkItems()
}
公共删除(键:字符串){
this.timerItems=this.timerItems.filter(t=>t.key!==key);
transition(':enter', [
style({ backgroundColor: 'green' }),
animate('1s 4s ease-in', style({ backgroundColor: 'white' })),
])