NgUpgrade with Lazy Loading

Published: Sun Apr 30 2017

In this post I will show how to optimize NgUpgrade through lazy loading.

NgUpgrade

NgUpgrade is the bridge that allows AngularJS and Angular code to coexist in the same application. It's meant to be a temporary measure while you are working on converting the entire application to the latest version of Angular.

One of the challenges when doing NgUpgrade is limiting the impact of running two versions of Angular in the same application.

In the following example I will show how to optimize an NgUpgrade application by doing lazy loading.

Lazy Loading

Using Webpack I will show how to isolate the AngularJS dependency. The goal is to not even load AngularJS unless you route to an AngularJS portion of your application.

I have put the code on Github if you are interested in checking it out.

The sample application combines Angular 4.1 and AngularJS 1.6.

Lazy loading is handled by the new Angular router, but there is also internal ui-router routing in the AngularJS portion.

The first step is to create an application shell in Angular. The shell consists of three parts: app.module.ts, app.component.ts and app-routing.module.ts.

A you can see the shell sets up some lazy routes, as well as a simple component with two sibling router outlets. We need two outlets to support the Angular router (router-outlet) and ui-router (ui-view).

The key part here is that the AngularJS part of the application will only be loaded if we route to the “empty” route. All other bundles omit the AngularJS dependencies.

If you follow along in the browser's network tab you will see the different bundles load on demand per lazy route.

In addition to the lazy loaded bundles, there is a “shared” core bundle with shared Angular resources (core, common, platform-browser, router).

If an Angular dependency is only needed by a single lazy route, it's pushed out to that specific bundle. Here, this is the case for the HttpModule, FormsModule and UpgradeModule.

The AngularJS portion has its own bundle with the AngularJS framework, ui-router and the ng-upgrade dependencies.

NgUpgradeModule

NgUpgradeModule is a proper Angular NgModule, but this is where I package up the AngularJS dependencies like AngularJS, ui-router and the AngularJS application code.

It's also where I bootstrap the AngularJS application.

Again, the AngularJS portion will only be bootstrapped if someone actually routes there.

Note

I have discovered one interesting side effect of this approach. It appears that something in Angular is adding a global click handler.

This handler causes digest cycles in the AngularJS part if you click anywhere on the view. I suspect this is zone related, but it requires more research to figure out why this global handler is needed.

In my example you can see this if you click anywhere in the “friends” view. I have a console log statement that fires on every digest. Clicking the view causes it to log.

If you liked this article, share it with your friends on social media: