Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular lazy loading duplicate modules

Tags:

angular

I am trying to integrate lazy loading into my Angular application.

I have 4 modules. Each module is lazy loaded.

  • FirstPageWithTitleModule
  • SecondPageWithTileModule
  • ThirdPageWithTitleModule
  • RandomModule

The first 3 modules are importing my custom TitleModule.

My question: what happens with the TitleModule if all routes are lazyLoaded? Will it be generated 3 times and add its size to the lazyLoadedModule? Or will it be generated only 1 time with a single file size and used across all three modules?

like image 455
gertridg Avatar asked Mar 17 '19 10:03

gertridg


1 Answers

Here's a working project of this example: stackblitz.

I'm answering those two questions:

1. How many times TitleModule(title.module.ts) will appear in the bundles?

Answer: 1.

Since TitleModule is imported in multiple dependency graphs,

(one for each LazyLoaded module. e.g: loadChildren: () => import('app/first-page-with-title-module.module').then(m =>m.FirstPageWithTitleModule) )

Webpack is smart enough to detect those multiple references and he'll create a separate chunk for the shared modules(files). (Angular runs as a plugin inside webpack)

Here is a small example from webpack documentation that correlates with this scenario.

In the demo: You can see in the console that title-module.ts is parsed by webpack 1 time. Since webpack pushed the module(file) only once to the bundle, it only needs to read it once, and then its on its cache.

2. How many times TitleModule will be instantiate?

Answer: 3

Each loadChildren callback eventually ends up here in angular source code and executes factory.create(parentInjector) which means a new NgModule is created as a child of the parent route.

So now we have 3 new lazy loaded modules:

  • FirstPageWithTitleModule
  • SecondPageWithTileModule
  • ThirdPageWithTileModule

Each one creates TitleModule object when he tries to decipher the import array of its NgModule decorator. TitleModule object doesn't exists in the parentInjector and lazy modules do not share Modules, InjectionTokens(providers) unless they are in a shared ancestor injector.

In the demo: You can see in the console.log that TitleModule is instantiate 3 times(each time you enter a route it'll instantiate - unless it was already created in this route) - max number of 3.

like image 129
Raz Ronen Avatar answered Nov 13 '22 09:11

Raz Ronen