angularangular-moduleangular-lazyloading

How many instances of a module end up in the final bundle if it's referenced by several modules?


I'm wondering what's the best strategy between

I suppose that the case against putting all the reusable codes in a shared module is that it will be huge and will slow down the loading of the application because not every module need all the code in the share module.

Both GalleryModule and ProfileModule import CardModule. They are both lazy loaded as well.

@NgModule({
    declarations: [...],
    imports: [
        ...,
        CardModule, 
        ...
    ]
})
export class GalleryModule { }

@NgModule({
    declarations: [...],
    imports: [
        ...,
        CardModule, 
        ...
    ]
})
export class ProfileModule { }

Let's say the user visits the gallery page. The galleryModule will be loaded along with its dependency, i.e. the CardModule. Let's say, after that, the user decides to go to the profile page, which will result in the ProfileModule being loaded.

Will the CardModule be loaded for the second time or will Angular just reuse the CardModule that was loaded along with GallelryModule?

Edit

It seems like someone else asked the same question here. However, it doesn't seem like anybody responded clearly to the question.

Thanks for helping.


Solution

  • No, the CardModule will not be loaded for the second time. Angular has its internal mechanism to detect if a module is already loaded. If so, it doesn't load the module again, and uses the already loaded instance.

    Note that lazy modules are not put in the final bundle, they are loaded only when the corresponding lazy route is accessed.

    At development time, following is what you'll see after running your application with CLI 11.x -

    āˆš Browser application bundle generation complete.
    
    Initial Chunk Files       | Names                  |      Size
    vendor.js                 | vendor                 |   7.52 MB
    polyfills.js              | polyfills              | 484.59 kB
    styles.css, styles.js     | styles                 | 419.34 kB
    main.js                   | main                   |  79.30 kB
    runtime.js                | runtime                |   9.08 kB
    
                              | Initial Total          |   8.49 MB
    
    Lazy Chunk Files          | Names                  |      Size
    gallery-gallery-module.js | gallery-gallery-module |   7.36 kB
    profile-profile-module.js | profile-profile-module |   7.35 kB
    common.js   
    

    and following are some information on how the loading works -

    1. the Initial Chunk Files comprise the final bundle and main.js is where all your eager modules (app module, shared module, etc) are put.

    2. the Lazy Chunk Files comprise the list of lazy modules that Angular keeps, and the CardModule is put in common.js.

    3. if you access the profile page, the profile-profile-module.js and common.js are loaded. When you access the gallery page later, only gallery-gallery-module.js is loaded. You can check this on your browser's Network tab when you access the lazy routes.

    4. if you had other modules which are used by multiple lazy modules, those too would be put in the common.js.

    5. if you had modules which are used only by a single lazy module, then those would be bundled with that lazy module rather than putting them in the common.js. For example, if you had an XyzModule module that is used only by the GalleryModule, then it would be bundled with the GalleryModule and put in the gallery-gallery-module.js.

    EDIT:
    You can use the ng build command and check the generated physical files listed above in the dist directory to get a better picture of which modules get bundled with which.