injectAsync: Angular's Native Solution for Lazy-Loading Services
Angular 22 ships injectAsync — a first-party helper that lets you lazily load services through the DI system.
If you’ve used ngxtension/inject-lazy, this will feel familiar. But the API is different, and the trade-offs matter.
The Problem
Bundle size. You have a ChartService that pulls in D3, a PdfService that imports pdfjs, or an AnalyticsService that loads a heavy SDK. These services aren’t needed on initial render — maybe they’re triggered by a button click, a route guard, or a conditional feature flag.
With providedIn: 'root', the service class and its dependencies end up in the main bundle regardless of whether the user ever triggers the code path that uses them.
Lazy routes solve this for route-level code splitting. But what about services used within a component that’s already loaded?
Before injectAsync: The Manual Approach
@Component({
selector: 'app-report',
template: `<button (click)="generate()">Generate PDF</button>`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ReportComponent {
private _injector = inject(EnvironmentInjector);
async generate(): Promise<void> {
const { PdfService } = await import('./pdf.service');
const pdfService = this._injector.get(PdfService);
pdfService.createReport();
}
}


