Add ember-best-practices skill

This commit is contained in:
2026-04-01 12:59:41 +04:00
parent 913d5c915c
commit ecbac12440
65 changed files with 19863 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
---
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.