Skip to content

Parallel Data Loading in Model Hooks

When fetching multiple independent data sources in a route's model hook, use Promise.all() or RSVP.hash() to load them in parallel instead of sequentially.

Incorrect (sequential loading, 3 round trips):

javascript
// app/routes/dashboard.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class DashboardRoute extends Route {
  @service store;

  async model() {
    const user = await this.store.request({ url: '/users/me' });
    const posts = await this.store.request({ url: '/posts?recent=true' });
    const notifications = await this.store.request({ url: '/notifications?unread=true' });

    return { user, posts, notifications };
  }
}

Correct (parallel loading, 1 round trip):

javascript
// app/routes/dashboard.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';
import { hash } from 'rsvp';

export default class DashboardRoute extends Route {
  @service store;

  model() {
    return hash({
      user: this.store.request({ url: '/users/me' }),
      posts: this.store.request({ url: '/posts?recent=true' }),
      notifications: this.store.request({ url: '/notifications?unread=true' })
    });
  }
}

Using hash() from RSVP allows Ember to resolve all promises concurrently, significantly reducing load time.