1.7 KiB
1.7 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Parallel Data Loading in Model Hooks | CRITICAL | 2-10× improvement | routes, data-fetching, parallelization, performance |
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.
export default in these route examples is intentional because route modules are discovered through resolver lookup. In hybrid .gjs/.hbs codebases, keep route defaults and add named exports only when you need explicit imports elsewhere.
Incorrect (sequential loading, 3 round trips):
// 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):
// 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.