Preloading is great. It lets us fetch parts of our application before it is even requested for. By doing this, our content is ready to be served when needed without any delay. There are many ways of doing this, I'll be touching upon some of the ways to do this in Angular and how we can create our own custom preloading strategy based on the user's network state.
Angular provides us with route-based preloading out of the box. There are two strategies namely
NoPreloading, as the name suggests does not preload any modules. This is the default behaviour.
PreloadAllModules, on the other hand, preloads all modules. A simple example adding a preloading strategy in a routing module file can be seen below
In the above code, the
ProductsModule is lazily loaded, which means, the bundle is downloaded only when the user lands on the
/products route. By passing the
preloadingStrategy property, we instruct Angular to preload all lazily loaded modules.
Angular also lets us provide custom preloading strategies where we can determine if a component needs to be preloaded or not. This can be done by providing our own custom class to the
Our custom class needs to extend
PreloadingStrategy class from
@angular/router and implement the
preload function in it. A simple custom preloading strategy class would look something like this.
CustomPreloadingStrategy class implements
PreloadingStrategy class and has the
preload function as well. The
preload function should either return the
load function or an empty observable. Returning the load function means the module can be loaded. As for the
shouldPreload function, that is where our custom logic goes in.
Now that we are familiar with setting up a custom preloading strategy, now we can move on to using our user's network connection information to make a decision for us. Let's say our user has a very slow bandwidth, so we wouldn't want to further tax our user by preloading all of our modules in the background. In that case, we can decide not to preload our modules. To do this, we rely on the navigator object in our browser and specifically the connection property in navigator.
If you're reading this in desktop/laptop, open the browser's console and type in
navigator.connection, you would see something like this.
We can leverage this information in our
shouldPreload function to let Angular know whether to preload the module or not.
In the example above, we're using the
saveData property to determine if the user has data-saver on, and we're using the
effectiveType property to see if the user is on
3g connections. If the user is on slower internet connections, we are returning false, which would in turn prevent preloading of the particular module
We can extend this idea of custom preloading strategies to make intelligent decisions based on our user's state. I have no idea if this method would even result in a tangible improvement in the user experience, but nevertheless a fun topic to explore.
You can find the source code here