loading...

Lazy Loaded Components in Angular

negue profile image negue ・Updated on ・2 min read

Back in the old AngularJS Days I had a little playground app where I could lazy load nearly everything.

Ever since Angular 2 came out, I searched every few months about lazy loading components.

Some time after release, it got quite easy to lazy load angular modules based on your routes, and also got easier with simple npm packages / files, but there weren't any "easy"(-ish) ways to lazy load a component, but thankfully Ivy will finally change that. 🎉

1. Wait, before you continue reading...

I suggest you to read Artur's Post about Asynchronous modules and components in Angular Ivy first, great introduction and explanation!

This component loader is based on his example, loading the components based on a fixed import()-path.

2. Refactoring the example Component Link

I added a simple map which holds all my lazy loadable components.

// list of lazy loaded components
const lazyComponents = {
  'lazy-comp': () => import('../lazy-comp/lazy-comp.component'),
  'other-comp': () => import('../lazy-comp/other-comp.component')
};

With each import line, the angular-cli (or rather webpack) marks those imports as lazy and those will be extracted to a separate chunk.

chunk {lazy-comp-lazy-comp-component} lazy-comp-lazy-comp-component.js, lazy-comp-lazy-comp-component.js.map (lazy-comp-lazy-comp-component) 1.55 kB  [rendered]
chunk {lazy-comp-other-comp-component} lazy-comp-other-comp-component.js, lazy-comp-other-comp-component.js.map (lazy-comp-other-comp-component) 1.57 kB  [rendered]

Now you only need to set

<my-dynamic-loader component="lazy-comp"></my-dynamic-loader>

And your component is lazy loaded 🎉

3. Refactoring continues..

Now lets register the lazy-components outside the loader-component itself, so that its a bit more dynamic. (Now DynamicLoaderComponent can be used from a library and additional lazy-components can be added from everywhere else)

DynamicLoaderComponent.LazyComponents = {
  'lazy-comp': () => import('./lazy-comp/lazy-comp.component'),
  'other-comp': () => import('./lazy-comp/other-comp.component')
};

Refactored Version

to be continued / tried / tested:

  • Inject services into lazy components
  • @Input()/@Output()
  • prevent loading the same component multiple times / loaded component cache
  • events on Component loaded / created / others
  • example repo / project

Any thoughts / suggestions / ideas ?

Discussion

pic
Editor guide