当我研究这个问题时,我发现an issue与FirebaseListObservable
执行时preserveSnapshot
was false
- 默认行为。每次可观察对象发出一组展开的快照时,数组元素都是不同的实例 - 即使元素本身没有改变。这导致变更检测的效率大大降低。
A 修复已合并并将包含在 AngularFire2 的下一个版本中(即随后的版本)2.0.0-beta.7
) - 哪个应该很快.
修复后,如果 Angular 的OnPush
使用变化检测,AngularFire2的FirebaseListObservable
对于 DOM 更新来说非常快速和高效。
我通常将组件分为容器和展示组件,容器组件保存可观察的内容,展示组件使用OnPush
变化检测。
容器组件看起来像这样:
import { Component } from "@angular/core";
import { AngularFire, FirebaseListObservable } from "angularfire2";
@Component({
selector: "items-container",
template: `<items-component [items]="items | async"></items-component>`
})
export class ItemsContainer {
private items: FirebaseListObservable<any>;
constructor(private angularFire: AngularFire) {
this.items = angularFire.database.list("some/fast-changing/data", {
query: {
limitToLast: 1000
}
});
}
}
展示组件看起来像这样:
import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "items-component",
template: `
<ul>
<li *ngFor="let item of items">{{ item | json }}</li>
</ul>
`
})
export class ItemsComponent {
@Input() items: any[];
}
通过这种组件排列,Angular 的OnPush
更改检测将确保只有实际更改的元素才会影响 DOM 更新。因此,即使很长,滚动列表也将高效且快速。
另一个提示:FirebaseListObserable
当基础数据发生变化时,使用限制查询有时会发出两个值。例如,当一个新项目添加到数据库中时,会生成一个查询最近 10 个项目的列表(使用limitToLast: 10
)将发出一个删除了最近的项目的数组,然后立即发出另一个添加了最近的项目的数组。如果您不想发出这两个数组中的第一个,可以使用auditTime操作员:
import "rxjs/add/operator/auditTime";
this.items = angularFire.database.list("some/fast-changing/data", {
query: {
limitToLast: 10
}
})
.auditTime(0);