{"id":824,"date":"2025-05-02T11:44:04","date_gmt":"2025-05-02T11:44:04","guid":{"rendered":"https:\/\/www.cmarix.com\/qanda\/?p=824"},"modified":"2026-02-05T12:06:38","modified_gmt":"2026-02-05T12:06:38","slug":"angular-17-lazy-loading-preloading","status":"publish","type":"post","link":"https:\/\/www.cmarix.com\/qanda\/angular-17-lazy-loading-preloading\/","title":{"rendered":"How does Angular 17 handle preloading strategies with lazy-loaded routes?"},"content":{"rendered":"\n<p>Angular 17 is improving its routing capabilities with strategies for preloading, lazy-loading modules and other such best practices for optimizing load times and performance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is Preloading in Angular?<\/h2>\n\n\n\n<p>When using lazy loading, Angular loads feature modules on demand (when the route is accessed). However, this can cause delays. Preloading addresses this by loading these modules in the background after the application is bootstrapped, reducing future navigation delays.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Angular 17 and Preloading Strategies<\/h3>\n\n\n\n<p>Angular provides built-in preloading strategies and also allows custom strategies. Here&#8217;s how it works in Angular 17:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No Preloading \u2013 Modules are only loaded when the route is visited.<\/li>\n\n\n\n<li>PreloadAllModules \u2013 All lazy modules are loaded after the app is initialized.<\/li>\n\n\n\n<li>Custom PreloadingStrategy \u2013 You define which modules to preload based on your logic (like network condition, user roles, etc.).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use Preloading Strategies?<\/h2>\n\n\n\n<p><strong>Directory structure:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">app\/<br>\u2502<br>\u251c\u2500\u2500 app-routing.module.ts<br>\u251c\u2500\u2500 feature\/<br>\u2502   \u2514\u2500\u2500 feature.module.ts<br>\u2514\u2500\u2500 admin\/<br>    \u2514\u2500\u2500 admin.module.ts<\/pre>\n\n\n\n<p><strong>Example: Using PreloadAllModules<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ app-routing.module.ts\nimport { NgModule } from '@angular\/core';\nimport { RouterModule, Routes, PreloadAllModules } from '@angular\/router';\n\nconst routes: Routes = &#91;\n  {\n    path: 'feature',\n    loadChildren: () =>\n      import('.\/feature\/feature.module').then(m => m.FeatureModule),\n  },\n  {\n    path: 'admin',\n    loadChildren: () =>\n      import('.\/admin\/admin.module').then(m => m.AdminModule),\n  }\n];\n\n@NgModule({\n  imports: &#91;\n    RouterModule.forRoot(routes, {\n      preloadingStrategy: PreloadAllModules, \/\/  All lazy-loaded modules will be preloaded\n    }),\n  ],\n  exports: &#91;RouterModule],\n})\nexport class AppRoutingModule {}<\/code><\/pre>\n\n\n\n<p>Now, even though feature and admin are lazy-loaded, they\u2019ll be preloaded in the background right after app load.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Custom Preloading Strategy Example<\/h2>\n\n\n\n<p>Let&#8217;s say you only want to preload modules that have a data: { preload: true } flag.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Create a custom strategy:<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ selective-preloading.strategy.ts\nimport { PreloadingStrategy, Route } from '@angular\/router';\nimport { Observable, of } from 'rxjs';\nimport { Injectable } from '@angular\/core';\n\n@Injectable({ providedIn: 'root' })\nexport class SelectivePreloadingStrategy implements PreloadingStrategy {\n  preload(route: Route, load: () => Observable&lt;any>): Observable&lt;any> {\n    return route.data?.&#91;'preload'] ? load() : of(null);\n  }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Use it in routing module:<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ app-routing.module.ts\nimport { SelectivePreloadingStrategy } from '.\/selective-preloading.strategy';\n\nconst routes: Routes = &#91;\n  {\n    path: 'feature',\n    loadChildren: () => import('.\/feature\/feature.module').then(m => m.FeatureModule),\n    data: { preload: true }, \/\/ \u2705 Will be preloaded\n  },\n  {\n    path: 'admin',\n    loadChildren: () => import('.\/admin\/admin.module').then(m => m.AdminModule),\n    data: { preload: false }, \/\/ \u274c Won\u2019t preload\n  }\n];\n\n@NgModule({\n  imports: &#91;\n    RouterModule.forRoot(routes, {\n      preloadingStrategy: SelectivePreloadingStrategy,\n    }),\n  ],\n  exports: &#91;RouterModule],\n})\nexport class AppRoutingModule {}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Testing Lazy Loading + Preloading<\/h3>\n\n\n\n<p><strong>To observe:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Run ng serve &#8211;verbose<\/li>\n\n\n\n<li>Watch Network tab in DevTools.<\/li>\n\n\n\n<li>The module chunks should load after app load (with PreloadAllModules) or conditionally (with custom strategy).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quick Tabular Summary<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Strategy<\/strong><\/td><td><strong>Behavior<\/strong><\/td><\/tr><tr><td><strong>No preloading (default)<\/strong><\/td><td>Modules load on demand only<\/td><\/tr><tr><td><strong>PreloadAllModules<\/strong><\/td><td>All lazy modules preload after app init<\/td><\/tr><tr><td><strong>Custom strategy<\/strong><\/td><td>You define preload logic per route<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">What are the Angular 17 Tips?<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Combine preloading with Quicklink strategy (from external libs) for link-based preloading.<\/li>\n\n\n\n<li>Preloading is ideal for frequently visited modules, but not for rarely used admin or settings sections.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Angular 17 is improving its routing capabilities with strategies for preloading, lazy-loading modules and other such best practices for optimizing load times and performance. What is Preloading in Angular? When using lazy loading, Angular loads feature modules on demand (when the route is accessed). However, this can cause delays. Preloading addresses this by loading these [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":931,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7,3],"tags":[],"class_list":["post-824","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-web"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/824","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/comments?post=824"}],"version-history":[{"count":10,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/824\/revisions"}],"predecessor-version":[{"id":932,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/824\/revisions\/932"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media\/931"}],"wp:attachment":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media?parent=824"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/categories?post=824"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/tags?post=824"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}