2017-09-28 8 views
0

Je rencontre des problèmes avec la sélection d'éléments (entre 1.000 et 4.000) via une requête de mon IndexedDB avec Dexie dans une application Angular 4.Dexie & Angular 4: lenteur lors de la sélection des articles

Il n'y a que 20.000 articles max dans les tableaux, mais la sélection de ces prend plusieurs secondes (5 secondes sur Chrome 61, jusqu'à (et plus) que 20 ans sur iOS 10 & iOS 11)

Ci-dessous mon un service qui récupère deux tables différentes et renvoie une observable via 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()); 
    } 
} 

le résultat observable est manipulé de manière asynchrone avec un effet NGRX, qui distribue une action qui écrit les données sur l'état, de sorte que le composant peut rendre l'information.

@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))); 

J'ai essayé de « charge paresseux » les articles en morceaux par https://github.com/raphinesse/dexie-batch, mais les lots résultants ont pris plus de 500 ms pour arriver.

Où ai-je un goulot d'étranglement possible? J'ai déjà essayé d'exécuter cette requête en dehors des zones d'Angular, mais cela n'a pas donné d'améliorations et de performances.

+0

Vous voulez mettre 4000 articles en même temps sur la page? – alexKhymenko

+0

Créer un plunker – Aravind

+0

@alexKhymenko - non, l'information est dans le magasin et via une directive de défilement j'ajoute seulement 50 articles à la vue une fois que l'utilisateur a atteint le fond. Je ai essayé de charger les éléments directement à partir de la base de données lorsque l'utilisateur a touché le fond, mais même c'est trop lent sur les iPads. – timbru31

Répondre

0

Avec beaucoup de temps et le débogage, j'ai identifié les éléments suivants Dexie PR qui brise la IndexedDB 2.0 getAll fonctionnalité dans Chrome et Safari: https://github.com/dfahlander/Dexie.js/pull/579

Avec un retour à leurs Dexie 2.0.0-beta.11 la performance est augmentée d'environ 10x fois (requêtes de base de données brutes par curseur sur getAll est passé de 600-700ms retour à 60ms)

Modifier: Dexie 2.0.1 a été libéré avec une solution correcte pour cette question