You Pick Which Angular Bundles to Preload
Tags: angular, webdev, typescript, javascript
Published: 2019-05-29 21:51:39

---
title: You Pick Which Angular Bundles to Preload
published: true
tags: angular, webdev, typescript, javascript
description: Learn how to create your own custom Angular preload strategy to choose which bundles to load in advance
cover_image: https://thepracticaldev.s3.amazonaws.com/i/f90dmphy8eny2zcwvx18.jpg
series: Angular Preload Strategies
canonical_url: https://johnpapa.net/you-pick-which-angular-bundles-to-preload/
---

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 articles in this series

- [Preload all Angular Bundles](https://dev.to/john_papa/preload-all-angular-bundles-1b6l)
- [You Pick Which Angular Bundles to Preload](https://dev.to/john_papa/you-pick-which-angular-bundles-to-preload-5l9)
- [Preload Angular Bundles When Good Network Connectivity is Detected](https://dev.to/azure/preload-angular-bundles-when-good-network-connectivity-is-detected-j3a)
- [Predictive Preloading Strategy for Your Angular Bundles](https://dev.to/john_papa/predictive-preloading-strategy-for-your-angular-bundles-4bgl)

## 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.

```typescript
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.

```typescript
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.

```typescript
@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](https://code.visualstudio.com/?wt.mc_id=devto-blog-jopapa)
- Get the VS Code [Angular Essentials](https://marketplace.visualstudio.com/items?itemName=johnpapa.angular-essentials&wt.mc_id=devto-blog-jopapa)
- Get the VS Code [Angular Snippets](https://marketplace.visualstudio.com/items?itemName=johnpapa.angular2&wt.mc_id=devto-blog-jopapa)