Javascript 角度性能:如果组件不在视口中,则更改检测分离
我想分离当前视口中所有组件的更改检测Javascript 角度性能:如果组件不在视口中,则更改检测分离,javascript,angular,intersection-observer,Javascript,Angular,Intersection Observer,我想分离当前视口中所有组件的更改检测 import{Component,Input,ChangeDetectionStrategy,ChangeDetectorRef,ElementRef,ViewChild,OnInit,ondestory,AfterViewInit}从'@angular/core'导入; @组成部分({ 选择器:“你好”, 模板:`[{index}}]{{count}}`, 样式:[`div{border:1px纯红;padding:5px 5px 5px;}`], ch
import{Component,Input,ChangeDetectionStrategy,ChangeDetectorRef,ElementRef,ViewChild,OnInit,ondestory,AfterViewInit}从'@angular/core'导入;
@组成部分({
选择器:“你好”,
模板:`[{index}}]{{count}}`,
样式:[`div{border:1px纯红;padding:5px 5px 5px;}`],
changeDetection:ChangeDetectionStrategy.OnPush,
})
导出类HelloComponent实现OnInit,AfterViewInit{
@ViewChild('counter',{static:false})计数器:ElementRef;
@Input()索引:数字;
公共计数=0;
公共可见=真实;
构造函数(私有cdr:ChangeDetectorRef){}
恩戈尼尼特(){
设置间隔(()=>{
这个.count++;
this.cdr.markForCheck();
}, 1000);
}
ngAfterViewInit(){
const hidewhenboxiview=新的IntersectionObserver((条目)=>{
如果(条目[0]。intersectionRatio您正在为每个组件调用setInterval()
,包括那些不在视图中的组件。更改检测未运行,但您仍然每秒调用setInterval()
1000次函数,这解释了延迟
顺便说一句,渲染一个包含1000个项目的滚动列表也会影响性能。浏览器会渲染所有内容,并且在不在视口中的情况下滚动列表时需要计算各种绘制。您应该延迟渲染如此长的列表,请参阅
您也在对看不见的组件调用.markForCheck()
,请在调用该组件之前检查该组件是否可见
看
ngOnInit(){
此文件为.subscriptions.add(
间隔(1000)。订阅(()=>{
这个.count++;
如果(这个可见){
this.cdr.markForCheck();
}
})
);
}
恩贡德斯特罗(){
此为.subscriptions.unsubscribe();
}
ngAfterViewInit(){
const hideWhenBoxInView=新的IntersectionObserver(条目=>{
如果(条目[0]。intersectionRatio可能使用trackBy
可以避免检查它是否在视口中
<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
一个函数,用于定义如何跟踪中项目的更改
难以忍受
在iterable中添加、移动或删除项时,指令
必须重新呈现适当的DOM节点。要最大限度地减少
在DOM中,仅重新渲染已更改的节点
默认情况下,更改检测器假定对象实例
标识iterable中的节点。提供此函数时,
指令使用调用此函数的结果来标识
项节点,而不是对象本身的标识
该函数接收两个输入:迭代索引和节点
对象ID
ngOnInit() {
this.subscriptions.add(
interval(1000).subscribe(() => {
this.count++;
if (this.visible) {
this.cdr.markForCheck();
}
})
);
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
ngAfterViewInit() {
const hideWhenBoxInView = new IntersectionObserver(entries => {
if (entries[0].intersectionRatio <= 0) {
// If not in view
this.cdr.detach();
this.visible = false;
} else {
this.visible = true;
this.cdr.reattach();
this.cdr.markForCheck();
}
});
hideWhenBoxInView.observe(this.counter.nativeElement);
}
<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
trackByFn(index, item) {
return item.someUniqueIdentifier;
// return index(if id is not unique) or unique id;
}