Есть ли у angular какой-либо метод планирования мер и мутаций dom?

Я создал задачу Angular: https://github.com/angular/angular/issues/20471< /а>

Также начал предложение в gist: https://gist.github.com/matthewharwood/23ea18c8509b8056813d3c3e7df0d1b2

Эй, я возился с Angular/cdk, которая работает за пределами ngZones и @angular/animations. Мне было интересно, не могли бы вы сказать мне, учитывается ли конкретная оптимизация перебора макета? Моим секретным оружием для повышения производительности всегда было использование библиотеки fastdom для таких эффектов, как параллаксная прокрутка. Мне еще предстоит проверить производительность, потому что у меня такое ощущение, что в angular уже есть методы, похожие на слишком быстрые, о которых я просто не знаю.

Вопрос. Есть ли в Angular какой-либо метод планирования измерений и изменений DOM? Если да, то как? Если нет, было бы разумно реализовать fastdom в библиотеках, таких как cdk и анимации, если да, то не могли бы вы привести несколько примеров, которые помогут мне лучше сообщить об этом команде angular?

В любом случае описание проблемы немного сложно объяснить; тем не менее, давайте посмотрим на fastdom, а потом я перейду к angular.

Fastdom работает следующим образом:

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

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

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

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

Будет вывод:

measure
measure
mutate
mutate

При просмотре 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);
  }

Тестовый пример: представьте, что у вас есть элемент на странице, который будет переводиться в зависимости от текущей позиции прокрутки.

Вы можете реализовать это примерно так: (Псевдокод)

// 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();
  }
}

Что-то вроде этого, если вы использовали быстрый дом:

// 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`;
      });
    });
  }
}

Я почти уверен, что такого рода оптимизация не включена, если только this._ngZone.runOutsideAngular не является этой оптимизацией. У кого-нибудь есть инфа по наличию оптимизации?


person Armeen Harwood    schedule 16.11.2017    source источник