Dexie & Angular 4: 选择项目时性能低下
Dexie & Angular 4: slow performance when selecting items
我在 Angular 4 应用程序中使用 Dexie 通过查询从我的 IndexedDB 中选择项目(1.000 到 4.000 之间)时遇到问题。
表中最多只有 20.000 个项目,但选择这些项目需要数秒(Chrome 61 上的 5 秒,iOS 10 上最多(和更多)20 秒 & iOS 11)
下面是我的服务,它通过 loadItems()
获取两个不同的表和 returns 一个 Observable
@Injectable()
export class ItemService {
private buildings: Dexie.Table<Building, string>;
private people: Dexie.Table<Person, string>;
private activeZip: string;
constructor(
private db: IndexeddbService,
) {
this.buildings = this.db.table('buildings');
this.people = this.db.table('people');
}
loadItems(): Observable<{
buildings: Building[],
people: Person[]
}> {
return Observable.combineLatest(
this.loadBuildings(),
this.loadPeople(),
).map(([buildings, people]) => {
return {
buildings,
people
};
});
}
private loadBuildings(): Observable<Building[]> {
return Observable.from(this.buildings.where('zip').equals(this.activeZip).toArray());
}
private loadPeople(): Observable<Person[]> {
return Observable.from(this.people.where('zip').equals(this.activeZip).toArray());
}
}
生成的 Observable 使用 ngrx 效果进行异步处理,它会分派一个将数据写入状态的 Action,因此组件可以呈现信息。
@Effect()
loadItems$: Observable<Action> = this.actions$
.ofType(actions.ActionTypes.LOAD_ITEMS)
.map(_ => this.itemService.setActiveZip(this.localStorageService.getActiveZip()))
.switchMap(_ => this.itemService.loadItems())
.map(items => new actions.LoadItemsSuccessAction(items))
.catch(error => Observable.of(new actions.LoadItemsFailAction(error)));
我已经尝试通过 https://github.com/raphinesse/dexie-batch 将项目 "lazy-load" 成块,但生成的批次需要超过 500 毫秒才能到达。
我可能在哪里遇到性能瓶颈?我已经尝试 运行 在 Angular 的区域之外进行此查询,但这并没有产生效果和性能改进。
经过大量时间和调试,我确定了以下 Dexie PR,它破坏了 Chrome 和 Safari 中的 IndexedDB 2.0 getAll 功能:https://github.com/dfahlander/Dexie.js/pull/579
恢复到 Dexie 2.0.0-beta.11 后,性能提高了大约 10 倍(通过游标到 getAll 的原始数据库查询从 600-700 毫秒回到 60 毫秒)
编辑:Dexie 2.0.1 已发布,并正确修复了此问题
我在 Angular 4 应用程序中使用 Dexie 通过查询从我的 IndexedDB 中选择项目(1.000 到 4.000 之间)时遇到问题。
表中最多只有 20.000 个项目,但选择这些项目需要数秒(Chrome 61 上的 5 秒,iOS 10 上最多(和更多)20 秒 & iOS 11)
下面是我的服务,它通过 loadItems()
@Injectable()
export class ItemService {
private buildings: Dexie.Table<Building, string>;
private people: Dexie.Table<Person, string>;
private activeZip: string;
constructor(
private db: IndexeddbService,
) {
this.buildings = this.db.table('buildings');
this.people = this.db.table('people');
}
loadItems(): Observable<{
buildings: Building[],
people: Person[]
}> {
return Observable.combineLatest(
this.loadBuildings(),
this.loadPeople(),
).map(([buildings, people]) => {
return {
buildings,
people
};
});
}
private loadBuildings(): Observable<Building[]> {
return Observable.from(this.buildings.where('zip').equals(this.activeZip).toArray());
}
private loadPeople(): Observable<Person[]> {
return Observable.from(this.people.where('zip').equals(this.activeZip).toArray());
}
}
生成的 Observable 使用 ngrx 效果进行异步处理,它会分派一个将数据写入状态的 Action,因此组件可以呈现信息。
@Effect()
loadItems$: Observable<Action> = this.actions$
.ofType(actions.ActionTypes.LOAD_ITEMS)
.map(_ => this.itemService.setActiveZip(this.localStorageService.getActiveZip()))
.switchMap(_ => this.itemService.loadItems())
.map(items => new actions.LoadItemsSuccessAction(items))
.catch(error => Observable.of(new actions.LoadItemsFailAction(error)));
我已经尝试通过 https://github.com/raphinesse/dexie-batch 将项目 "lazy-load" 成块,但生成的批次需要超过 500 毫秒才能到达。
我可能在哪里遇到性能瓶颈?我已经尝试 运行 在 Angular 的区域之外进行此查询,但这并没有产生效果和性能改进。
经过大量时间和调试,我确定了以下 Dexie PR,它破坏了 Chrome 和 Safari 中的 IndexedDB 2.0 getAll 功能:https://github.com/dfahlander/Dexie.js/pull/579
恢复到 Dexie 2.0.0-beta.11 后,性能提高了大约 10 倍(通过游标到 getAll 的原始数据库查询从 600-700 毫秒回到 60 毫秒)
编辑:Dexie 2.0.1 已发布,并正确修复了此问题