Angular — lazy load single component

Ryan Hoffnan
3 min readSep 25, 2020

--

Building an Angular app with scale in mind is tricky. We are already accustomed to lazy loading routes and by that decreasing bundle size and decreasing initial load times and letting the user interact with our web/app quicker.
With in time our Web-App will have to do more and more, which will effect the page load time and this can become extremely noticeable when building very large and dynamic forms with dynamic changing parts.
If we could just load the components that are needed in the current form and not all of them at once, load time will decrease and also we haven’t exposed unnecessary code to the client (Its still there in the js files, just the UI doesn’t render it).

So now that we have gone through with the examples and some benefits how is this done? Angular is primary a very closed framework, no easy workarounds which ensures the validity of the framework and to ensure build quality at all times.
But there is a still a way, an Angular way even.

CompoentFactoryResolver is the a class Angular exports in order to create components in run time. It has some quirky behaviors but lets continue with the example.

We have the object with the relative path of the component we want to load and as you can see in the snippet above there is the type {default: any} of the variable loadFile. This will not have a value at first. In order to do so in the component you are lazy loading at the bottom of the component (outside of it though) add :
####This is extremely important

export default MockComponent

Now comes the tricky part which I will explain more on

Lets go over that last snippet

lazyTab(In the html) : This is template reference variable which we will use in order to tell angular where to insert that lazyLoaded component

@ViewChild(‘lazyTab’ …. : Here we giving access to typescript to work with the template reference variable

loadFile: a variable created to save the created RAW component

actualComponent : The Angular component that we have created in runtime

Now that we have our component loaded we might want to add INPUTs or OUTPUTs to the component to keep it in sync with our entire app.
Before continuing I feel the need to talk about Angular change detection and how NgZone is the main black magic in all of Angular’s Magic.
NgZone is what makes the app react to changes and update it self. It works in a way matter of scopes. and if you are working outside of the Angular scope, your changes won’t be detected and therefor no UI update.

the zone.run… will make it so that the changes in side the lazyLoaded component will be detectedrun ngOnChanges when you set/reset those INPUTs.

So now how about OUTPUTS ? well OUTPUTS are functions we pass on so how will that be done ?

So the OUTPUT is of type Emitter which means we can subscribe to it and get the data which is emitted from the lazyLoaded component.

This is amazing , we have a fully living component that was loaded in runtime by the app.

Lets talk about the downsides first

1. This requires a lot of overhead and ability write maintainable code.
2. Doing this for a number of components that can change will require more overhead and a way to keep things updated when the user changes between components
3. This is not a very Angular way of doing things
4. Components are still loaded in the module.
5. Bundle size is not decreased

upsides:

1. Decrease load time on extremely large forms or pages.
2. Ability to load a component in reference to the type of user that is signed in
3. When you want to have the option to load components from a server
4. running A/B testing
5. Super cool idea that has been tested in production for a very large scale application.

Hope you enjoyed this small tutorial.
For any questions or comments feel free to comment and I will be happy to reply

--

--