【问题标题】:Dexie & Angular 4: slow performance when selecting itemsDexie & Angular 4:选择项目时性能下降
【发布时间】:2018-03-10 13:36:08
【问题描述】:

我在使用 Angular 4 应用程序中的 Dexie 从我的 IndexedDB 查询选择项目(1.000 到 4.000 之间)时遇到问题。

表格中最多只有 20.000 个项目,但选择这些项目需要几秒钟(Chrome 61 上为 5 秒,iOS 10 和 iOS 11 上最多(甚至更多)20 秒)

下面是我的服务,它获取两个不同的表并通过loadItems()返回一个 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 以块的形式“延迟加载”项目,但生成的批次需要 500 多毫秒才能到达。

哪里可能存在性能瓶颈?我已经尝试在 Angular 的区域之外运行此查询,但这并没有提高性能和性能。

【问题讨论】:

  • 您想在页面上同时放置 4000 个项目?
  • 创建一个插件
  • @alexKhymenko - 不,信息在商店中,并且通过滚动指令,一旦用户到达底部,我只会将 50 个项目添加到视图中。尝试在用户触底时直接从数据库加载项目,但即使这样在 iPad 上也太慢了。
  • 有了这么多的行,别忘了将trackBy 函数添加到*ngFor 中,也就是你搞砸的那个时间,是从你提出请求的那一刻到数据是在 UI 中加载的,还是从您发出请求到收到响应的时间?
  • @camaron 感谢 trackBy 的提示,还不知道这个功能。通过 console.time() 进行的测量表明 Observable 需要很长时间才能完成,Chrome 性能分析显示,问题不是渲染,而是脚本。

标签: angular observable indexeddb ngrx-effects dexie


【解决方案1】:

经过大量时间和调试,我发现以下 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 已发布,并对此问题进行了正确修复

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2016-01-18
    • 2016-04-26
    • 2023-03-13
    相关资源
    最近更新 更多