You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中能否实现组件级懒加载而非仅模块级懒加载?

Component-Level Lazy Loading in Angular: Yes, It's Possible!

Great question! You're right that most tutorials fixate on module-level lazy loading, but component-level lazy loading is totally achievable in Angular—perfect for exactly the scenario you described: loading a specific component only when the user navigates to its route, with a loading state displayed while the browser fetches the necessary files.

Let me break down how to implement this, depending on your Angular version:

For Angular 14+ (Using Standalone Components)

Angular 14 introduced standalone components, which let you lazy-load components directly without wrapping them in a module. This is the cleanest, most straightforward approach:

Step 1: Define the Lazy-Loaded Route

Update your route configuration to use loadComponent instead of the module-focused loadChildren:

// app-routing.module.ts
import { Routes } from '@angular/router';

const routes: Routes = [
  // Your existing routes here
  {
    path: 'invoice/list',
    // Lazy-load the component only when this route is accessed
    loadComponent: () => import('./invoice-list/invoice-list.component').then(m => m.InvoiceListComponent)
  }
];

Make sure your InvoiceListComponent is marked as standalone (this is required for direct component lazy loading):

// invoice-list.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-invoice-list',
  standalone: true, // Critical flag for standalone components
  imports: [CommonModule], // Include any required modules here (e.g., FormsModule)
  templateUrl: './invoice-list.component.html',
  styleUrls: ['./invoice-list.component.css']
})
export class InvoiceListComponent {}

Step 2: Add Loading State (Progress Bar)

To show a progress bar while the component loads, listen to Angular's router events in your root component:

// app.component.ts
import { Component } from '@angular/core';
import { Router, RouterEvent, NavigationStart, NavigationEnd, NavigationError, NavigationCancel } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  isLoading = false;

  constructor(private router: Router) {
    this.router.events.subscribe((event: RouterEvent) => {
      this.handleRouterEvents(event);
    });
  }

  private handleRouterEvents(event: RouterEvent): void {
    if (event instanceof NavigationStart) {
      this.isLoading = true; // Show progress bar when navigation starts
    }
    // Hide progress bar when navigation finishes, cancels, or errors
    if (event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) {
      this.isLoading = false;
    }
  }
}

Then add a progress bar to your root template (use any UI library's progress bar or a custom one):

<!-- app.component.html -->
<div *ngIf="isLoading" class="loading-bar">
  <!-- Example: Angular Material progress bar -->
  <mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
<router-outlet></router-outlet>

For Angular <14 (Using a Lightweight Module)

If you're on an older Angular version, you'll need to wrap your component in a minimal module (since lazy loading was module-only pre-Angular 14). This module will be tiny—just enough to enable lazy loading:

Step 1: Create a Minimal Module for the Component

// invoice-list.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { InvoiceListComponent } from './invoice-list.component';

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

@NgModule({
  declarations: [InvoiceListComponent],
  imports: [CommonModule, RouterModule.forChild(routes)]
})
export class InvoiceListModule {}

Step 2: Lazy-Load the Module in Your Route

// app-routing.module.ts
const routes: Routes = [
  // Other routes
  {
    path: 'invoice/list',
    loadChildren: () => import('./invoice-list/invoice-list.module').then(m => m.InvoiceListModule)
  }
];

The loading state implementation is identical to the Angular 14+ example above.

Key Notes

  • You don't need to manually "dynamically register the component to the main module"—Angular handles component registration and rendering in the router outlet automatically when the lazy-loaded component/module finishes loading.
  • The browser will only download the component's JS, HTML, and CSS when the user navigates to /invoice/list, exactly as you requested.

内容的提问来源于stack exchange,提问作者mohammad rostami siahgeli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:26:41