如何防止 Firebase 在 Angular 2 中重复触发更改检测?
How can I prevent Firebase from repeatedly triggering change detection in Angular 2?
Firebase 使用大量内部异步调用触发更改检测,因为 Angular/Zone monkey-patching websockets 和 setInterval
等。即使我没有与我的应用交互,我也会看到级联变化检测一直在发生,这有助于减慢速度,尤其是在移动设备上。
此默认行为可能很有用,但我现在使用 Firebase 的方式可以非常严格地控制何时需要更新视图,因此使用来自 Firebase 的回调,以便更改检测无论如何手动发生。
我知道将更改检测器策略设置为 OnPush
会有所帮助,我正在努力,但我想从各个角度解决这个问题。
我熟悉区域的 runOutsideAngular
但现在不确定是否要在这里应用它,因为所有异步调用都发生在 Firebase 模块内。
如何让 Firebase 在 angular 区域之外开展所有业务?
编辑:显示问题的示例代码:
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;
}
}
回想起来这很明显,但只需在区域外实例化 Firebase 引用就可以了。例如:
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
});
}
}
通过在我的组件的 ngDoCheck
中放置断点,我能够将所有更改检测周期追溯到我实例化 Firebase 引用的那一行,这暗示 运行 它在区域之外会阻止他们。
请注意,如果您走这条路,您必须确保在必要时触发更改检测。有关示例,请参阅 。
Firebase 使用大量内部异步调用触发更改检测,因为 Angular/Zone monkey-patching websockets 和 setInterval
等。即使我没有与我的应用交互,我也会看到级联变化检测一直在发生,这有助于减慢速度,尤其是在移动设备上。
此默认行为可能很有用,但我现在使用 Firebase 的方式可以非常严格地控制何时需要更新视图,因此使用来自 Firebase 的回调,以便更改检测无论如何手动发生。
我知道将更改检测器策略设置为 OnPush
会有所帮助,我正在努力,但我想从各个角度解决这个问题。
我熟悉区域的 runOutsideAngular
但现在不确定是否要在这里应用它,因为所有异步调用都发生在 Firebase 模块内。
如何让 Firebase 在 angular 区域之外开展所有业务?
编辑:显示问题的示例代码:
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;
}
}
回想起来这很明显,但只需在区域外实例化 Firebase 引用就可以了。例如:
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
});
}
}
通过在我的组件的 ngDoCheck
中放置断点,我能够将所有更改检测周期追溯到我实例化 Firebase 引用的那一行,这暗示 运行 它在区域之外会阻止他们。
请注意,如果您走这条路,您必须确保在必要时触发更改检测。有关示例,请参阅