← Back to Articles         
Eager loading vs lazy loading

Eager loading vs lazy loading

Published on 02 Oct 2026     8 min read Angular
Lazy Loading

1. What is Eager Loading in Angular?

What is Eager Loading?

Eager loading means loading application code as part of the initial application dependency graph, rather than waiting until the user navigates to a particular feature.

In routing, this commonly happens when a component is statically imported and referenced using component.

Eager Loading = Load upfront.
Lazy Loading = Load when needed.

For example:

import { Products } from './products/products';

export const routes: Routes = [
  {
    path: 'products',
    component: Products
  }
];

Here, Products is statically imported.

Conceptually:

Application starts
       ↓
Initial JavaScript
       ↓
Products code is eagerly reachable
       ↓
Application ready

The browser does not wait until /products is visited to fetch a route-specific lazy chunk for Products.


Full Simple Sample Program

Let's create:

  • Home → Eager loaded
  • Products → Eager loaded
  • Admin → Lazy loaded

Project Structure

src/app/
│
├── app.ts
├── app.html
├── app.routes.ts
│
├── home/
│   └── home.ts
├── products/
│   └── products.ts
└── admin/
    └── admin.ts

app.routes.ts

import { Routes } from '@angular/router';

import { Home } from './home/home';
import { Products } from './products/products';

export const routes: Routes = [
  {
    path: '',
    component: Home
  },
  {
    path: 'products',
    component: Products
  },
  {
    path: 'admin',
    loadComponent: () =>
      import('./admin/admin')
        .then(m => m.Admin)
  }
];

app.ts

import { Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    RouterLink,
    RouterOutlet
  ],
  templateUrl: './app.html'
})
export class App {
}

app.html

<h1>My Application</h1>

<nav>
  <a routerLink="/">Home</a> |
  <a routerLink="/products">Products</a> |
  <a routerLink="/admin">Admin</a>
</nav>

<hr>

<router-outlet></router-outlet>

home/home.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-home',
  standalone: true,
  template: `
    <h2>Home</h2>
    <p>Welcome to Home.</p>
  `
})
export class Home {
}

products/products.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-products',
  standalone: true,
  template: `
    <h2>Products</h2>

    <ul>
      <li>Laptop</li>
      <li>Keyboard</li>
      <li>Mouse</li>
    </ul>
  `
})
export class Products {
}

admin/admin.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-admin',
  standalone: true,
  template: `
    <h2>Admin</h2>
    <p>Admin page loaded.</p>
  `
})
export class Admin {
}

Program Explanation

Look at these imports:

import { Home } from './home/home';
import { Products } from './products/products';

And routes:

{
  path: '',
  component: Home
},
{
  path: 'products',
  component: Products
}

These components are statically imported.

They are therefore part of the eagerly reachable application code.

Conceptually:

Application starts
       ↓
Initial application code
       ├── Home
       └── Products

But Admin is different:

{
  path: 'admin',
  loadComponent: () =>
    import('./admin/admin')
      .then(m => m.Admin)
}

Admin uses a dynamic import().

Therefore:

Application starts
       ↓
Admin code deferred

User visits /admin
       ↓
Admin chunk loaded
       ↓
Admin displayed

Important: Eager Loading Doesn't Mean the Page Is Displayed

This is an important distinction.

Suppose:

import { Products } from './products/products';

{
  path: 'products',
  component: Products
}

When the application starts, the code for Products is eagerly included/reachable.

But Angular doesn't necessarily create and display the Products component immediately.

It is displayed when:

User → /products

So:

Eager Loading
    =
Code available upfront

NOT

Component necessarily displayed upfront

When Should We Use Eager Loading?

Eager loading makes sense for small, essential, frequently needed parts of the application.

For example:

Home
Login
Main Layout
Navigation
Small common pages

Lazy loading is usually more useful for larger feature areas:

Admin
Reports
Analytics
Management
Settings

2. Eager Loading vs Lazy Loading

The main difference is when the code becomes part of the browser's loaded application.

Eager Loading

import { Products } from './products/products';

{
  path: 'products',
  component: Products
}

Conceptually:

Application starts
       ↓
Products code available
       ↓
User visits /products
       ↓
Products displayed

Lazy Loading

{
  path: 'products',
  loadComponent: () =>
    import('./products/products')
      .then(m => m.Products)
}

Conceptually:

Application starts
       ↓
Products code deferred

Later...

User visits /products
       ↓
Products chunk requested
       ↓
Products code loaded
       ↓
Products displayed

Eager vs Lazy Loading — Side-by-Side

Eager Loading Lazy Loading
Loads code upfront Loads code when required
Uses static imports Commonly uses dynamic import()
component: Products loadComponent()
Can increase initial bundle/workload Can reduce initial bundle/workload
No first-navigation chunk fetch for that feature First navigation may require a chunk download
Good for core/small features Good for large/less frequently used features
Simpler for small applications Useful for scalable feature-based applications

Code Comparison

Eager

import { Products } from './products/products';

export const routes: Routes = [
  {
    path: 'products',
    component: Products
  }
];

Notice:

import { Products } from './products/products';

Static import.


Lazy

export const routes: Routes = [
  {
    path: 'products',
    loadComponent: () =>
      import('./products/products')
        .then(m => m.Products)
  }
];

Notice:

import('./products/products')

Dynamic import.

That's the key technical difference.


Visual Comparison

Eager Loading

Application starts
       ↓
┌─────────────────┐
│ Initial code    │
│                 │
│ Home            │
│ Products        │
│ Orders          │
└─────────────────┘
       ↓
Application runs

Even if the user only visits Home, those eagerly imported features are reachable from the initial application graph.


Lazy Loading

Application starts
       ↓
┌─────────────────┐
│ Initial code    │
│ Home            │
└─────────────────┘

Later:

User → Products
       ↓
products chunk
       ↓
Products

User → Orders
       ↓
orders chunk
       ↓
Orders

Relationship with Code Splitting

This connects directly to the previous concept.

Eager

import { Products } from './products/products';

Conceptually:

Static import
     ↓
Eager dependency
     ↓
Initial application graph

Lazy

import('./products/products')

Conceptually:

Dynamic import
      ↓
Code-splitting boundary
      ↓
Separate/deferred chunk
      ↓
Lazy loading

So remember:

Static import
     ↓
Usually Eager


Dynamic import
     ↓
Code Splitting
     ↓
Lazy Loading

Real-World Example

Imagine your Angular application contains:

Public
├── Home
├── Articles
└── Contact

Admin
├── Dashboard
├── Articles
├── Categories
├── Tags
└── Users

You might keep small/core routes eager:

import { Home } from './home/home';

export const routes: Routes = [
  {
    path: '',
    component: Home
  }
];

But lazy-load the Admin feature:

{
  path: 'admin',
  loadChildren: () =>
    import('./admin/admin.routes')
      .then(m => m.ADMIN_ROUTES)
}

Conceptually:

Application starts
       ↓
Public/Core code

User never visits Admin
       ↓
Admin feature not needed

OR

User visits /admin
       ↓
Admin routes/code loaded

This is a common reason to use lazy loading in larger Angular applications.


Advantages of Eager Loading

1. Simple

Straightforward routing:

{
  path: 'products',
  component: Products
}

2. No lazy-chunk fetch on first navigation

The feature code is already available.

3. Good for small/core features

If a feature is small and almost always needed, eager loading can be reasonable.


Disadvantages of Eager Loading

1. Larger initial JavaScript workload

If many large features are eagerly imported, more code must be handled during application startup.

2. Can slow startup

The browser may need to download, parse, compile, and execute more JavaScript initially.

3. Unnecessary code may be loaded

For example:

Normal User
    ↓
Never opens Admin

But if Admin is eagerly imported, its code may still contribute to the initial dependency graph.


Key Points

  1. Eager loading loads feature code upfront as part of the initial application dependency graph.

  2. A typical eager route is:

import { Products } from './products/products';

{
  path: 'products',
  component: Products
}
  1. A typical lazy route is:
{
  path: 'products',
  loadComponent: () =>
    import('./products/products')
      .then(m => m.Products)
}
  1. Eager loading commonly uses a static import.

  2. Lazy loading commonly uses a dynamic import().

  3. Eager loading doesn't mean every component is immediately rendered.

  4. Lazy loading is especially useful for larger, less frequently accessed features.

  5. Both can be used in the same Angular application.


Interview Questions and Answers

1. What is eager loading in Angular?

Eager loading means application code is loaded upfront as part of the initial application dependency graph rather than being deferred until the user accesses a feature.

import { Products } from './products/products';

{
  path: 'products',
  component: Products
}

2. What is the difference between eager and lazy loading?

Eager loading loads feature code upfront, while lazy loading defers feature code until the feature is needed.

Eager → Load upfront
Lazy  → Load when needed

3. How do you identify an eagerly loaded route?

A typical eager route statically imports the component:

import { Products } from './products/products';

{
  path: 'products',
  component: Products
}

4. How do you identify a lazy-loaded route?

It commonly uses a dynamic import with loadComponent():

{
  path: 'products',
  loadComponent: () =>
    import('./products/products')
      .then(m => m.Products)
}

5. Is eager loading bad?

No. Eager loading is appropriate for small, core, frequently required application functionality.

Lazy loading becomes especially valuable for larger or less frequently accessed features.


6. Can eager loading and lazy loading be used together?

Yes. This is common.

import { Home } from './home/home';

export const routes: Routes = [
  {
    path: '',
    component: Home
  },
  {
    path: 'products',
    loadComponent: () =>
      import('./products/products')
        .then(m => m.Products)
  },
  {
    path: 'admin',
    loadChildren: () =>
      import('./admin/admin.routes')
        .then(m => m.ADMIN_ROUTES)
  }
];

Here:

Home
   ↓
Eager

Products
   ↓
Lazy individual component

Admin
   ↓
Lazy feature routes

Quick Interview Revision

                Angular Loading
                      │
          ┌───────────┴───────────┐
          │                       │
       EAGER                    LAZY
          │                       │
    Load upfront           Load when needed
          │                       │
    Static import           Dynamic import()
          │                       │
 component: Products       loadComponent()
                                  or
                           loadChildren()
          │                       │
   Good for core/          Good for large/
   small features          optional features

One-line answer

Eager loading makes feature code available upfront as part of the initial application, whereas lazy loading uses code splitting to defer feature code until it is required.

← Back to Articles