How can I prevent Firebase from repeatedly triggering change detection in Angular 2?

拟墨画扇 提交于 2019-12-11 02:04:26

问题


Firebase uses a lot of internal asynchronous calls that trigger change detection because of Angular/Zone monkey-patching websockets and setInterval etc. Even when I'm not interacting with my app, I see a cascade of change detection happening all the time, which contributes to slowing things down especially on mobile.

This default behavior could be useful, but the way I'm using Firebase right now I have pretty tight control over when I need to update the view, so callbacks from Firebase are used in such a way that change detection will happen manually anyway.

I know setting change detector strategy to OnPush will help here, which I'm working on, but I want to attack this from every angle.

I'm familiar with zone's runOutsideAngular but not sure now to apply it here since all of the async calls are happening inside the Firebase module.

How can I get Firebase to do all its business outside the angular zone?


Edit: Example code that shows the problem:

import {Component} from '@angular/core';

@Component({
  selector: 'test-component',
  template: 'hello world'
})
export class TestComponent {
  ref: Firebase;

  constructor() {
    this.ref = new Firebase('<firebase URL>');
  }

  ngDoCheck() {
    console.log('Check the stack - this is being called continually via async functions used internally by Firebase.');
    debugger;
  }
}

回答1:


This is obvious in retrospect, but simply instantiating the Firebase reference outside of the zone did the trick. E.g.:

import {Injectable, NgZone} from '@angular/core';

// ...

@Injectable()
export class DataService {
  ref: Firebase;

  // ...

  constructor(
    private zone: NgZone
    // ...
  ) {
    // Instantiate Firebase ref outside the zone to prevent its continual internal operations from triggering change detection
    this.zone.runOutsideAngular(() => {
      this.ref = new Firebase('<firebase URL>');
    });

    this.ref.on('value', snapshot => {
      // Change detection will NOT automatically be triggered after this callback
    });
  }
}

By putting breakpoints in ngDoCheck in my components I was able to trace all the change detection cycles back to that line where I instantiate the Firebase reference, which hinted that running it outside the zone would prevent them.

Note that if you go this route you have to make sure to change detection is getting triggered when necessary. See https://stackoverflow.com/a/34829089/458614 for examples.



来源:https://stackoverflow.com/questions/41455969/how-can-i-prevent-firebase-from-repeatedly-triggering-change-detection-in-angula

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!