Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.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
Javascript 角度性能:如果组件不在视口中,则更改检测分离_Javascript_Angular_Intersection Observer - Fatal编程技术网

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;
}