55 lines
1.7 KiB
Markdown
55 lines
1.7 KiB
Markdown
---
|
||
title: Parallel Data Loading in Model Hooks
|
||
impact: CRITICAL
|
||
impactDescription: 2-10× improvement
|
||
tags: 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):**
|
||
|
||
```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.
|