Files
marco/.agents/skills/ember-best-practices/rules/service-ember-data-optimization.md

2.7 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Optimize WarpDrive Queries MEDIUM-HIGH 40-70% reduction in API calls warp-drive, performance, api, optimization

Optimize WarpDrive Queries

Use WarpDrive's request features effectively to reduce API calls and load only the data you need.

Incorrect (multiple queries, overfetching):

// app/routes/posts.js
export default class PostsRoute extends Route {
  @service store;

  async model() {
    // Loads all posts (could be thousands)
    const response = await this.store.request({ url: '/posts' });
    const posts = response.content.data;

    // Then filters in memory
    return posts.filter((post) => post.attributes.status === 'published');
  }
}

Correct (filtered query with pagination):

// app/routes/posts.js
export default class PostsRoute extends Route {
  @service store;

  queryParams = {
    page: { refreshModel: true },
    filter: { refreshModel: true },
  };

  model(params) {
    // Server-side filtering and pagination
    return this.store.request({
      url: '/posts',
      data: {
        filter: {
          status: 'published',
        },
        page: {
          number: params.page || 1,
          size: 20,
        },
        include: 'author', // Sideload related data
        fields: {
          // Sparse fieldsets
          posts: 'title,excerpt,publishedAt,author',
          users: 'name,avatar',
        },
      },
    });
  }
}

Use request with includes for single records:

// app/routes/post.js
export default class PostRoute extends Route {
  @service store;

  model(params) {
    return this.store.request({
      url: `/posts/${params.post_id}`,
      data: {
        include: 'author,comments.user', // Nested relationships
      },
    });
  }
}

For frequently accessed data, use cache lookups:

// app/components/user-badge.js
class UserBadge extends Component {
  @service store;

  get user() {
    // Check cache first, avoiding API call if already loaded
    const cached = this.store.cache.peek({
      type: 'user',
      id: this.args.userId,
    });

    if (cached) {
      return cached;
    }

    // Only fetch if not in cache
    return this.store.request({
      url: `/users/${this.args.userId}`,
    });
  }
}

Use request options for custom queries:

model() {
  return this.store.request({
    url: '/posts',
    data: {
      include: 'author,tags',
      customParam: 'value'
    },
    options: {
      reload: true // Bypass cache
    }
  });
}

Efficient WarpDrive usage reduces network overhead and improves application performance significantly.

Reference: WarpDrive Documentation