Users want fast apps. Getting your JavaScript bundles to your browser as quickly as possible and before your user needs them can make a huge and positive impact on their user experience. Knowing how you can improve that experience is important.
One way you can improve user experience with your Angular apps is to strategically decide which bundles to preload. You control when your bundles load and which bundles load. This is why you should explore choosing a built-in or creating your own custom Angular preload strategy.
In this series we'll explore a few of your options for preloading Angular bundles.
Here are the other articles in this series
- Preload all Angular Bundles
- You Pick Which Angular Bundles to Preload
- Preload Angular Bundles When Good Network Connectivity is Detected
- Predictive Preloading Strategy for Your Angular Bundles
Opting in
The "opt in" strategy is like a buffet. You pick what you want to preload, and leave the rest to load as needed.
Creating custom preload strategies is a great way to control the manner in which the bundles preload. The custom OptInPreloadStrategy
preload strategy let's you indicate which lazy loaded bundles should be preloaded.
You can do this by creating a new class that implements that PreloadingStrategy
interface, and providing it in the root. Then you must implement the preload
function and return the load()
function when you want to tell Angular to preload the function.
Notice the preload
function in the class OptInPreloadStrategy
checks the route definition for a data
property that contains a preload
property. If that data.preload
property exists and is a truthy value, then the load()
function will be returned. When the load()
function is returned, the router listens to this Observable and will make the network call to load the route's bundle.
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, EMPTY } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class OptInPreloadStrategy implements PreloadingStrategy {
preload(route: Route, load: () => Observable<any>): Observable<any> {
return route.data && route.data['preload'] ? load() : EMPTY;
}
}
Route Definitions
This strategy requires that you indicate which routes should be preloaded. You can do this by adding the data.preload
property and set it to true
in your route definition, as shown below.
export const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'heroes' },
{
path: 'dashboard',
loadChildren: () =>
import('app/dashboard/dashboard.module').then(m => m.DashboardModule),
data: { preload: true }
},
{
path: 'heroes',
loadChildren: () =>
import('app/heroes/heroes.module').then(m => m.HeroesModule),
data: { preload: true }
},
{
path: 'villains',
loadChildren: () =>
import('app/villains/villains.module').then(m => m.VillainsModule)
},
{ path: '**', pathMatch: 'full', component: PageNotFoundComponent }
];
Notice that the dashboard and heroes routes both have the preload.data
property set to true
. However, the villains route does not have this property set. In this scenario the heroes and dashboard would preload, but the villains would only load when the user navigates to this route.
Setting the Custom OptInPreloadStrategy
Then when setting up your RouterModule
, pass the router options including the preloadingStrategy
to the forRoot()
function.
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: OptInPreloadStrategy })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
Try It
After applying this strategy and setting some of the route definition's routes data.preload = true
, rebuild and run your app with ng serve
. Open your browser, open your developer tools, and go to http://localhost:4200
. When you inspect the Network tab in your browser you will see all of your bundles already preloaded.
Notice that the dashboard and heroes are already preloaded, but villains are not. If you wish to really see this make a difference, enable throttling in your developer tools to a slower connection such as 3G, then refresh the page. The preloading will be much more visible now in the Network tab.
Deciding What Is Right For Your App
Now that you know how to create your own preload strategy such as OptInPreloadStrategy
, how do you evaluate if this is the right strategy for your app?
It might make sense to consider which bundles would help improve your users' experience by being preloaded first. You could talk to your business users (the stakeholders in your app) and discover what they feel are the most frequented areas of your app. You could use analytics from existing apps or perform user studies to determine this, as well.
In the end the decision is up to you. I recommend before choosing this options, or any preload strategy, that you test at various network speeds under various valid and common user workflows. This data will help you decide if this is the right strategy for you, or if another may be more beneficial for users of your app.
Resources
- Get VS Code
- Get the VS Code Angular Essentials
- Get the VS Code Angular Snippets