4

From what i have read online the Angular team recommends that you should always call requestAnimationFrame() outside of the Angular zone like this:

this.ngZone.runOutsideAngular(() => {
  requestAnimationFrame(timestamp => {
    let timerStart = timestamp || new Date().getTime();
    this.myAnimeMethod(timestamp);
  });
});

But what about the loop ...

this.ngZone.runOutsideAngular(() => {
  requestAnimationFrame(timestamp => {
    let timerStart = timestamp;
    this.myAnimeMethod(timestamp, timerStart);
  });
});

myAnimeMethod(timestamp, timerStart) {
  let time = timestamp || new Date().getTime();
  let runtime = time - timerStart;

  /// animation logic here

  if(runtime < 10000) {

    // ------- continue to animate for 10 seconds -- //

    requestAnimationFrame(timestamp => {
      this.myAnimeMethod(timestamp, timerStart);
    });
  }
}

Was it enough to call this.ngZone.runOutsideAngular() on the first request or should i be calling it again this.ngZone.runOutsideAngular() inside myAnimeMethod() like this?

this.ngZone.runOutsideAngular(() => {
  requestAnimationFrame(timestamp => {
    let timerStart = timestamp;
    this.myAnimeMethod(timestamp, timerStart);
  });
});

myAnimeMethod(timestamp, timerStart) {
  let time = timestamp || new Date().getTime();
  let runtime = time - timerStart;

  /// animation logic here

  if(runtime < 10000) {

    // ------- request to run outside of Angular again while continuing to animate for 10 seconds -- //

    this.ngZone.runOutsideAngular(() => {
      requestAnimationFrame(timestamp => {
        this.myAnimeMethod(timestamp, timerStart);
      });
    });

  }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
DevMike
  • 1,630
  • 2
  • 19
  • 33

2 Answers2

1

Short answer: You don't need to continue to call NgZone.runOutsideAngular from a requestAnimationFrame handler that came from a call outside Angular.

Long answer: Once you're in the "root" zone (which is what you get when you call NgZone.runOutsideAngular), any requestAnimationFrame callbacks will also run from that zone unless you explicitly request a different zone, e.g. via NgZone.run.

To check this, try calling the static function NgZone.isInAngularZone() from your requestAnimationFrame handler.

Note that I tested this with Angular 4.4.4 and Zone.js 0.8.18.

fr0
  • 1,048
  • 2
  • 9
  • 16
0

You can also make a ngzon-flags.ts where you put all your exceptions for change detection.

// All events inside the BLACK-LIST Array will not trigger updates anymore from angular
// requestAnimationFrame wont trigger change detection
(window as any).__Zone_disable_requestAnimationFrame = true; 
// Same for scroll and mousemove or any other event youll add
(window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove'];

Import that file to your polyfills.ts:

import './ngzone-flags'
Fluqz
  • 349
  • 1
  • 4
  • 17