Angular 9: Lazy Loading Components
Tags: angular, webdev, typescript, html
Published: 2020-02-16 20:29:59

---
title: Angular 9: Lazy Loading Components
published: true
description: Have you ever wanted to lazy load an Angular component? Here is a technique you can use with Angular 9.
tags: angular, webdev, typescript, html
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ck942tzser1sc7wb2h8l.png
canonical_url: https://johnpapa.net/angular-9-lazy-loading-components/
---

Angular 9 has some pretty awesome new features. The runtime, code-name Ivy, opens the doors to things like making lazy load Angular components more straightforward than ever.

This article shows you how to lazy load with Angular 9 and provides the code and resources along the way.

![Lazy Loading Components in Angular 9](https://media.giphy.com/media/XGVL02j72WvYFQd4v1/giphy.gif)


### 1 - Create a New App

Create a new Angular app using the Angular CLI command below. The following code will generate an app with as few files as you can get. 

```bash
ng new lazy-demo 
  --minimal 
  --inline-template 
  --inline-style 
  --routing=false 
  --style=css
```

This command will create a new angular app in a folder named **lazy-demo**

  - `--minimal` removes removes testing frameworks
  - `--inline-template` puts all component templates in the `.ts` file
  - `--inline-styles` puts all component styles in the `.ts` file
  - `--routing=false` does not add any routing
  - `--style=css` specifies to use CSS

### 2 - Create Lazy Components


Create two new components named `lazy1` and `lazy2`. 

```bash
ng g c lazy1 --flat --skip-import --skip-selector
ng g c lazy2 --flat --skip-import --skip-selector
```

These commands will create the two new components in files named `lazy1.component.ts` and `lazy2.component.ts`, respectively. We won't want either component to be declared in a module, since we want to lazy load them. If we declare them in a module, then Angular will eagerly load them.

We're also not creating the selectors since we won't be referring to them in a template directly. Instead, we'll load them dynamically.

### 3 - Lazy Load the Components

Add the following code to the file **app.component.ts**. Notice the constructor injects a `ViewContainerRef` (a place to put our components) and a `ComponentFactoryResolver` (this creates our components in code).

```typescript
export class AppComponent {
  title = 'lazy-comp';

  constructor(
    private viewContainerRef: ViewContainerRef,
    private cfr: ComponentFactoryResolver
  ) {}

  async getLazy1() {
    this.viewContainerRef.clear();
    const { Lazy1Component } = await import('./lazy1.component');
    this.viewContainerRef.createComponent(
      this.cfr.resolveComponentFactory(Lazy1Component)
    );
  }

  async getLazy2() {
    this.viewContainerRef.clear();
    const { Lazy2Component } = await import('./lazy2.component');
    this.viewContainerRef.createComponent(
      this.cfr.resolveComponentFactory(Lazy2Component)
    );
  }
}
```

The `getLazy1` function clears the container. This is important is we only want to show one of the lazy-loaded components at a time. If we did not clear the container, every time we lazy load components, they would be displayed one after another.

Next, we import the components, lazily, using the `await import` syntax. 

Finally, we create the component in the container.

### 4 - Adding Buttons to Lazy Load

Modify the template in `app.component.ts`, as shown below. This adds buttons that will lazy load each component when clicked.

```html
  template: `
    <div>
      <div>Hello World! This is the {{ title }} app.</div>
      <button (click)='getLazy1()'>lazy 1</button>
      <button (click)='getLazy2()'>lazy 2</button>
    </div>
  `
```

### 5 - Watch it Lazy Load

Now run the app with `ng serve` and browser to <http://localhost:4200>. After the app loads, open the browser's developer tools. Then clear the network traffic, so we can see when the components are lazy-loaded.

When you click one of the buttons, notice that the associated component I displayed and the network traffic shows the component is lazy loaded.

### 6 - What if Lazy Loaded Components Have Children

This is cool, but what if a lazy-loaded component has child components of its own? Imagine that `Lazy2Component` needs to show two other components named `Lazy2aComponent` and `Lazy2bComponent`. We'll need to generate these two components, and once again, make sure we do not declare them in a module.

```bash
ng g c lazy2a --flat --skip-import --skip-selector
ng g c lazy2b --flat --skip-import --skip-selector
```

Now modify the `Lazy2Component` to load it's two child components. We'll once again use the `ViewContainerRef` and `ComponentFactoryResolver`. 

However, this time we will not lazy-load the children. Instead, we'll create the child components in the `ngOnInit` and import them synchronously. 

What's the difference? Well, in this example, these child components will load in the same bundle as their parent, `Lazy2Component`.

Modify your `Lazy2Component` code, as shown below.

```typescript
import {
  Component,
  ViewContainerRef,
  ComponentFactoryResolver,
  OnInit
} from '@angular/core';
import { Lazy2aComponent } from './lazy2a.component';
import { Lazy2bComponent } from './lazy2b.component';

@Component({
  template: `
    <p>lazy2 component</p>
  `
})
export class Lazy2Component implements OnInit {
  constructor(
    private viewContainerRef: ViewContainerRef,
    private cfr: ComponentFactoryResolver
  ) {}

  ngOnInit() {
    const componentFactorya = this.cfr.resolveComponentFactory(Lazy2aComponent);
    const componentFactoryb = this.cfr.resolveComponentFactory(Lazy2bComponent);
    this.viewContainerRef.createComponent(componentFactorya);
    this.viewContainerRef.createComponent(componentFactoryb);
  }
}

```

### 7 - Run the App

Now run the app again and browse to <http://localhost:4200>. Or go back to the browser if you never stopped serving it.

Open the browser's developer tools, go to the Network tab, and clear the network traffic.

Notice that when you click on the button to load the **Lazy 1** component that the bundle for that component is passed, and Lazy 1 is displayed.

When you click the button to load **Lazy 2** its bundle is passed, and Lazy 2, Lazy 2a, and Lazy 2b are all displayed.

The bundle sizes for Lazy 1 and 2 are different, too. Lazy 1 only has a single component, so it is smaller than Lazy 2 (which contains three components).

### Should You?

So now you know how to lazy load a component with Angular 9. You can lazy load a component and have its children in turn lazily load or eagerly load. But you could also do this with a module (specifically an `NgModule`). So what do you do? Lazy loading a component helps support scenarios where you want to access features without routing. Lazy loading of modules helps when you want to access features with routing. But should that line be so distinct? Perhaps that line will blur as time moves forward. There are no warning signs here, just things to consider before entering this arena.

Another scenario might be when you want to load component dynamically based on user profile or a workflow. You could dynamically load (eagerly or lazily) one or more components. 

### Learn More

These examples should be able to help you get started with lazy loading components dynamically, with or without children. If you want to learn more, check out these resources:

1. [Dynamic Component Loader](https://angular.io/guide/dynamic-component-loader) 
1. [7 new features in Angular 9](https://auth0.com/blog/angular-9-whats-new/).
1. [VS Code](https://code.visualstudio.com/?wt.mc_id=devto-blog-jopapa) editor
1. [Angular Essentials Extension](https://marketplace.visualstudio.com/items?itemName=johnpapa.angular-essentials&wt.mc_id=devto-blog-jopapa) for VS Code
1. [Angular Language Service](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template&wt.mc_id=devto-blog-jopapa) for VS Code
1. [Angular Lazy Load Demo source code](https://github.com/johnpapa/angular-lazy-load-demo)