Preload Angular Bundles When Good Network Connectivity is Detected

John Papa - May 31 '19 - - Dev Community

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

Check out Suguru Inatomi's post here for a similar network-aware preloading strategy

Checking for a Good Connection

The "network aware" strategy uses the browser's Network Information API to detect the connection and speed. If the speed qualifies as good, then it preloads the bundles. If not, it leaves them alone.

You can check browser compatibility for the Network Information API here.

You can create the custom NetworkAwarePreloadStrategy by creating a class that implements the 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 NetworkAwarePreloadStrategy checks the navigator.connection object's saveData property first. Some mobile devices have a setting for "data saver". When this is enabled, this property will be true. Therefore, if the user has decided to save their data, they did so by choice and we should not be preloading bundles (which consumes data).

Next the code checks if the connection's effectiveType is one of the connection speeds that you feel are too slow to then preload the bundles. The code below decides that 2g and slow-2g don;t qualify for preloading, but 3g and better do. Therefore, as long as the saveData is true and the connection speed is 3g or better, the bundle will be preloaded.

export declare var navigator;

@Injectable({ providedIn: 'root' })
export class NetworkAwarePreloadStrategy implements PreloadingStrategy {
  preload(route: Route, load: () => Observable<any>): Observable<any> {
    return this.hasGoodConnection() ? load() : EMPTY;
  }

  hasGoodConnection(): boolean {
    const conn = navigator.connection;
    if (conn) {
      if (conn.saveData) {
        return false; // save data mode is enabled, so dont preload
      }
      const avoidTheseConnections = ['slow-2g', '2g' /* , '3g', '4g' */];
      const effectiveType = conn.effectiveType || '';
      console.log(effectiveType);
      if (avoidTheseConnections.includes(effectiveType)) {
        return false;
      }
    }
    return true;
  }
}

Setting the Custom NetworkAwarePreloadStrategy

Then when setting up your RouterModule, pass the router options including the preloadingStrategy to the forRoot() function.

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      preloadingStrategy: NetworkAwarePreloadStrategy
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}

Try It

After applying this strategy, 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 likely see all of your bundles already preloaded.

Then toggle your throttling to 2g speeds in your browser, then refresh the page. Then the routes will no longer be preloaded.

Deciding What Is Right For Your App

Now that you know how to create your own preload strategy such as NetworkAwarePreloadStrategy, how do you evaluate if this is the right strategy for your app?

If mobile and low bandwidth / low WiFi scenarios are likely for your users, this could be a beneficial preload strategy. You could talk to your business users (the stakeholders in your app) to discover this, if you are not sure.

You could also combine this strategy with one of the other custom strategies.

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .