Files
marco/.agents/skills/ember-best-practices/rules/bundle-lazy-dependencies.md

72 lines
2.0 KiB
Markdown

---
title: Lazy Load Heavy Dependencies
impact: CRITICAL
impactDescription: 30-50% initial bundle reduction
tags: bundle, lazy-loading, dynamic-imports, performance
---
## Lazy Load Heavy Dependencies
Use dynamic imports to load heavy libraries only when needed, reducing initial bundle size.
**Incorrect (loaded upfront):**
```javascript
import Component from '@glimmer/component';
import Chart from 'chart.js/auto'; // 300KB library loaded immediately
import hljs from 'highlight.js'; // 500KB library loaded immediately
class Dashboard extends Component {
get showChart() {
return this.args.hasData;
}
}
```
**Correct (lazy loaded with error/loading state handling):**
```glimmer-js
import Component from '@glimmer/component';
import { getPromiseState } from 'reactiveweb/promise';
class Dashboard extends Component {
// Use getPromiseState to model promise state for error/loading handling
chartLoader = getPromiseState(async () => {
const { default: Chart } = await import('chart.js/auto');
return Chart;
});
highlighterLoader = getPromiseState(async () => {
const { default: hljs } = await import('highlight.js');
return hljs;
});
loadChart = () => {
// Triggers lazy load, handles loading/error states automatically
return this.chartLoader.value;
};
highlightCode = (code) => {
const hljs = this.highlighterLoader.value;
if (hljs) {
return hljs.highlightAuto(code);
}
return code;
};
<template>
{{#if this.chartLoader.isLoading}}
<p>Loading chart library...</p>
{{else if this.chartLoader.isError}}
<p>Error loading chart: {{this.chartLoader.error.message}}</p>
{{else if this.chartLoader.isResolved}}
<canvas {{on "click" this.loadChart}}></canvas>
{{/if}}
</template>
}
```
**Note**: Always model promise state (loading/error/resolved) using `getPromiseState` from `reactiveweb/promise` to handle slow networks and errors properly.
Dynamic imports reduce initial bundle size by 30-50%, improving Time to Interactive.