angular是否有任何方法来计划dom的度量和变异?

Mat*_*ood 5 javascript performance dom angular angular-animations

我创建了一个Angular问题:https : //github.com/angular/angular/issues/20471

也在gist中启动了一项提案:https : //gist.github.com/matthewharwood/23ea18c8509b8056813d3c3e7df0d1b2

嘿,我在 Angular / cdk指令之外搞砸了,该指令在ngZones 和之外工作@angular/animations。我想知道您是否可以告诉我是否考虑了特定的布局颠簸优化?我提高性能的秘密武器一直是使用fastdom库来实现视差滚动等效果。我尚未测试性能,因为我感觉到角度已经有类似太快的方法,我只是不知道。

问题: Angular是否有任何方法来计划DOM的度量和变异?如果是这样,怎么办?如果不是,将快节奏实现到cdk和动画之类的库中是否明智?如果再次如此,您能给我一些例子来帮助我更好地与角度小组沟通吗?

无论如何,描述问题有点难以解释。但是,让我们看一下频率,然后我将调整角度。

Fastdom的工作方式如下:

fastdom.measure(() => {
  console.log('measure');
});

fastdom.mutate(() => {
  console.log('mutate');
});

fastdom.measure(() => {
  console.log('measure');
});

fastdom.mutate(() => {
  console.log('mutate');
});
Run Code Online (Sandbox Code Playgroud)

将输出:

measure
measure
mutate
mutate
Run Code Online (Sandbox Code Playgroud)

查看cdk时:https : //sourcegraph.com/github.com/angular/material2@master/-/blob/src/cdk/scrolling/scrollable.ts

除非是ngZones,否则似乎没有措施包装。

  ngOnInit() {
    this._scrollListener = this._ngZone.runOutsideAngular(() => {
      return this._renderer.listen(this.getElementRef().nativeElement, 'scroll', (event: Event) => {
        this._elementScrolled.next(event);
      });
    });

    this._scroll.register(this);
  }
Run Code Online (Sandbox Code Playgroud)

测试用例:假设您在页面上有一个元素,该元素可以根据当前滚动位置进行翻译。

您可以通过以下方式实现此功能:(伪代码)

// index.html
<body [cdkScrollable]>
    <some-component></some-component>
</body>


// some-component.ts
@Component({
  selector: 'some-component'
})
export class SomeComponent implement OnInit, AfterViewInit {
   @ViewChild(CdkScrollable) child: cdkScrollable;
    private _el: any;
     constructor(private _elementRef: ElementRef, private _renderer: Renderer2){}

    ngOnInit() {
      this._el = this._renderer.selectRootElement(this._elementRef);
     }

     ngAfterViewInit() {
        this._makeAnimation()
     }

   private _makeAnimation() {
    // first build the animation
    const myAnimation = this._builder.build([
      style({ top: 0 }),
      animate(1000, style({ top: `${cdkScrollable. elementScrolled(). scrollTop + 100}px` }))
    ]);

    // then create a player from it
    const player = myAnimation.create(this._el.nativeElement);

    player.play();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用快速dom,则需要执行以下操作:

// this should need optimization to run outside of angular too.
@Component({
  selector: 'some-other-component'
}) 
export class SomeOtherComponent {
  private _el: any;
  constructor(private _elementRef: ElementRef, private _renderer: Renderer2){}

  public ngOnInit() {
     this._el = this._renderer.selectRootElement(this._elementRef);
     this.renderLoop_();
  }

 private renderLoop_() {
    this.renderScrollBar_();
    fd.measure(() => this.renderLoop_());
  }

  private renderScrollBar() {
    fd.measure(() => {
      const scroll = window.scrollY + 100; 
      fd.mutate(() => {
         this._el.top = `${scroll}px`;
      });
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我敢肯定,除非this._ngZone.runOutsideAngular进行这种优化,否则不包括这种优化。是否有人对优化的存在有任何见识?