iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use Angular’s injectAsync when you want to defer a service dependency until a feature requests it. Use loadComponent or loadChildren when you want to defer route code. These are separate loading boundaries: neither changes the other’s job, and the service’s provider scope still determines which parts of the app can inject it.
How do I lazy load a service in Angular?
Angular’s service-specific API is injectAsync. It accepts a loader that imports the service module and returns a function you call when the feature needs the service. Calling that function triggers the load by default; after loading, Angular resolves the service through normal dependency injection.
The service must be auto-provided, for example with @Injectable({ providedIn: 'root' }) or Angular’s @Service() shorthand. See Angular’s lazy loading services guide for the API and prefetch options.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchconst getExporter = injectAsync(
() => import('./report-exporter').then((m) => m.ReportExporter),
);
// Call this when the user requests an export:
const exporter = await getExporter();
For example, this can defer an exporter that is used only when someone requests a report download. The import creates a separate JavaScript chunk when the build supports the split; invoking getExporter() requests and resolves the dependency. The example assumes ReportExporter is auto-provided.
#1 Best Overall
Start the download earlier with prefetching
Angular’s guide also documents a prefetch trigger, such as onIdle, to begin downloading when that trigger resolves. Prefetching does not make the service synchronous or guarantee it is ready: if the user requests it before the trigger runs or the download completes, the request still initiates or awaits the load.
What is different from lazy-loaded routes?
injectAsync defers a service dependency until its loader function is invoked. Router lazy loading defers a component or child-route definition until its route becomes relevant. The boundaries can be used independently; lazy-loading a route does not by itself mean every service it uses is separately deferred.
Rank #2
| Approach | What is deferred | When loading begins | Provider implications |
|---|---|---|---|
injectAsync |
A service dependency and its imported module | When the returned loader function is invoked, or earlier if a configured prefetch trigger runs | The service must be auto-provided; its provider scope still controls availability |
loadComponent |
A route component | When the router needs the corresponding route | The loader runs in that route’s injection context |
loadChildren |
Child-route configuration and associated route code | When the router needs the corresponding route | The loader runs in that route’s injection context |
Angular documents loadComponent and loadChildren as loader functions that return promises; dynamic imports are a common way to supply the code. The router runs these loaders in the current route’s injection context, so inject() can access providers on that route, inherited from parent routes, or available globally. See Angular’s lazy-loaded routes guidance.
Free tools Windows power users keep installed
One-click scans. No signup required.
Should I use route providers or providedIn: 'root'?
Choose scope based on where the service must be available, not just on when its code should load. Angular’s provider guidance distinguishes application-wide providers from route-level providers; a route provider belongs to that route’s injector and is visible within that route subtree, including its components, directives, guards, and resolvers.
Rank #3
| Provider scope | Who can inject it | When it fits | Lifetime consideration |
|---|---|---|---|
Root: @Injectable({ providedIn: 'root' }) or @Service() |
Application-wide consumers | Services shared across feature areas or where a shared instance is intended | Angular describes a root-provided service as a shared singleton |
| Route-level providers | That route and its descendants | Feature-specific services, dependencies, or route-specific configuration | By default, the route injector persists after navigating away until the application closes |
A service provided only on a route is not available to eager application areas outside that route’s injector. For instance, a root-level component cannot inject a route-only service simply because the service’s code was downloaded after navigating to that route. If both the route and app-wide consumers need the same service, provide it at an appropriate shared scope instead. Angular explains the persistence behavior in its dependency-injection troubleshooting guide; route providers are not automatically a memory-cleanup mechanism.
Choosing between Angular’s service decorators
Angular’s services guide describes @Service() as an ergonomic shorthand for root-provided @Injectable({ providedIn: 'root' }). Use @Injectable when you need constructor injection, advanced provider options, or a non-root scope. Root provision also lets Angular tree-shake an unused service from a production bundle; this is documented behavior, not a promise of a particular bundle-size reduction. See Creating and using services and the Injectable API reference.
Rank #4
When does lazy loading improve performance?
Lazy loading can reduce JavaScript requested for the initial load, but it moves some network work to a later moment. That tradeoff helps when code is costly and used infrequently; it may be a poor fit when the deferred feature is needed immediately or when the added request delays a key interaction.
Recommended Free Tools
- Consider eager loading primary landing pages, which users need as soon as the application opens.
- Use lazy loading for other pages or infrequent features when deferring their code makes the initial load leaner.
- Avoid assuming that deeper or nested lazy loading is always faster; Angular warns that multiple levels of nested lazy loading may affect performance.
There is no universal bundle-size or speed improvement: the result depends on the application’s code, when the feature is used, and the cost of later requests. Angular’s route performance guidance discusses the initial-load and later-request tradeoff.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

