hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Angular
  • Học lập trình
  • Lập trình Javascript
Lazy Loading Modules

Lazy Loading Modules

  • 14-01-2024
  • Toanngo92
  • 0 Comments

Hãy làm một bản ôn tập nhẹ, trong bài trước, chúng ta đã tìm hiểu cách cấu hình một feature module có tên là ArticleModule như sau:

// ArticleModule
@NgModule({
  imports: [CommonModule, ArticleRoutingModule],
  declarations: [
    ArticleComponent,
    ArticleListComponent,
    ArticleDetailComponent,
  ],
})
export class ArticleModule {}

Với cấu hình routing trong ArticleRoutingModule như sau:

// ArticleRoutingModule
const routes: Routes = [
  {
    path: "article",
    component: ArticleComponent,
    children: [
      {
        path: "",
        component: ArticleListComponent,
      },
      {
        path: ":slug",
        component: ArticleDetailComponent,
      },
    ],
  },
];
@NgModule({
  imports: [CommonModule, RouterModule.forChild(routes)],
  declarations: [],
  exports: [RouterModule],
})
export class ArticleRoutingModule {}

Cuối cùng, chúng ta import module này vào AppModule:

// AppModule
@NgModule({
  imports: [BrowserModule, FormsModule, ArticleModule, AppRoutingModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

Sau khi chúng ta chạy lệnh npm run build để build ra file JS và sử dụng source-map-explorer để phân tích bundle JS đã được build, bạn có thể mở thư mục dist và kiểm tra bundle main.js bằng cách chạy lệnh source-map-explorer main.js. Điều quan trọng là khi main.js được load, cả AppModule và ArticleModule đều được load, điều này là như mong đợi của chúng ta.

Sau khi thực hiện lệnh trên, bạn sẽ thấy chi tiết của bundle main.js bao gồm những gì. Tóm tắt là khi main.js được load, cả AppModule và ArticleModule đều được tải. Điều này làm cho chúng ta rất hài lòng.

Mục lục

  • Thêm một feature module nữa.
  • Lazy load module
  • Lazy load syntax
  • Preloading Lazy Module

Thêm một feature module nữa.

Bây giờ chúng ta sẽ thêm một feature module mới là AdminModule, với ý định hiển thị danh sách bài viết dưới dạng bảng và có khả năng chỉnh sửa/xóa bài viết. Cho tiện mục đích minh họa, mình chỉ đặt một nút button mà không thực hiện các chức năng này.

Giao diện sẽ tương tự như sau:

Bây giờ chúng ta bắt đầu với mã nguồn. Mình sẽ tạo một AdminModule gồm hai thành phần chính:

  • AdminComponent: Phần layout, tương tự như ArticleComponent.
  • AdminArticleListComponent: Phần hiển thị danh sách bài viết dưới dạng bảng để thực hiện các tác vụ.

Dưới đây là AdminRoutingModule:

// AdminRoutingModule
const routes: Routes = [
  {
    path: "admin",
    component: AdminComponent,
    children: [
      {
        path: "",
        component: AdminArticleListComponent,
      },
    ],
  },
];
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class AdminRoutingModule {}

Tuy nhiên, vì mình sẽ cần render một bảng và sửa Article, nên mình đã import thêm ReactiveFormsModule trong AdminModule:

// AdminModule
@NgModule({
  declarations: [AdminComponent, AdminArticleListComponent],
  imports: [
    CommonModule,
    ReactiveFormsModule, // <-- Import thêm để sử dụng forms sau này
    AdminRoutingModule,
  ],
})
export class AdminModule {}

Sau đó, mình import AdminRoutingModule vào AdminModule và AdminModule vào AppModule:

// AppModule
@NgModule({
  imports: [BrowserModule, AdminModule, ArticleModule, AppRoutingModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

Khi chúng ta chạy npm start, bạn sẽ thấy giao diện như trong hình động ở trên. Mình sẽ không hiển thị lại ở đây nữa. Phần thú vị bây giờ liên quan đến JS Bundle. Tiếp tục sử dụng source-map-explorer để kiểm tra file main.js, bạn sẽ thấy AdminModule đã được thêm vào trong bundle. Vậy còn Angular Core và ReactiveFormsModule thì ở đâu? Đáp án là chúng được đặt trong một file có tên là vendor.js. Hãy kiểm tra file này bằng cách chạy lệnh source-map-explorer vendor.js và bạn sẽ nhận được kết quả như sau:

Các module như Forms nằm ở đây, được đánh dấu bằng phần bôi đỏ.

Tóm lại, nếu bạn sử dụng Feature Module, khi ứng dụng được tải, tất cả thư viện và component bạn sử dụng trong TẤT CẢ các Feature Module sẽ được Angular tải. Đối với ứng dụng nhỏ, điều này có lẽ không quá ảnh hưởng, nhưng với ứng dụng lớn, chắc chắn sẽ tác động đáng kể đến trải nghiệm người dùng. Giờ, chúng ta sẽ chuyển sang phần quan trọng của bài viết – Lazy Load Module. Khi đã áp dụng kỹ thuật này, AdminModule và ReactiveFormsModule sẽ chỉ được tải khi bạn mở URL /admin.

Lazy load module

Để hỗ trợ lazy loading module trong Angular, trước tiên, chúng ta cần thực hiện một số bước.

Bước 1: Xóa AdminModule khỏi mảng import của AppModule. Việc này giúp tránh tình trạng tải toàn bộ mã nguồn của AdminModule cùng với AppModule, như đã thấy ở trên. Đồng thời, nhớ xóa cả phần import liên quan ở trên nữa.

// AppModule
@NgModule({
  imports: [BrowserModule, ArticleModule, AppRoutingModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

Bước 2: Cấu hình lại route cho AdminModule. Loại bỏ phần path admin trong AdminRoutingModule. Lý do cho bước này có thể xem ở bước 3.

// AdminRoutingModule
const routes: Routes = [
  {
    path: "",
    component: AdminComponent,
    children: [
      {
        path: "",
        component: AdminArticleListComponent,
      },
    ],
  },
];
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class AdminRoutingModule {}

Bước 3: Trong AppRoutingModule, chúng ta cần cấu hình để load AdminModule theo cú pháp lazy loading module khi mở ứng dụng ở path có dạng /admin.

// AppRoutingModule
const routes: Routes = [
  {
    path: "admin",
    loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule),
  },
  // ...other routes
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Lưu ý rằng cú pháp lazy-loading sử dụng loadChildren tiếp theo là một hàm sử dụng cú pháp import('...') tích hợp trong trình duyệt để tải module động. Đường dẫn import là đường dẫn tương đối đến module.

Sau khi thực hiện bước này, chúng ta chạy npm run build một lần nữa. CLI sẽ tạo ra một file JS mới được dành riêng cho AdminModule có tên là admin-admin-module.js.

Bước 4: Mở ứng dụng để kiểm tra. Bạn sẽ thấy một sự khác biệt lớn.

Khi tải trang lần đầu, ứng dụng sẽ chỉ tải các file cần thiết và main.js. Tuy nhiên, khi bạn nhấp vào Admin để chuyển đến /admin, lúc đó mới có tải admin-admin-module.js. Lazy load chính là điều này, tức là không tải ngay từ đầu, mà chỉ tải khi cần.

Bước 5: Chúng ta cùng xem phân tích của main.js và admin-admin-module.js.

source-map-explorer main.js
source-map-explorer admin-admin-module.js

Bundle của main.js giờ không chứa AdminModule nữa, chỉ còn ArticleModule.

Đây là phân tích của admin-admin-module.js. Phần import của Form và các component của AdminModule đã nằm trong bundle này. Rất xuất sắc.

Vậy là đã xong. Lazy load module giúp chúng ta tối ưu hóa việc tải module chỉ khi cần thiết, giúp ứng dụng hoạt động hiệu quả hơn.

Lazy load syntax

Cú pháp import('...') được khuyến khích sử dụng từ phiên bản Angular 8 trở đi. Trước đó, từ phiên bản Angular 7 và thấp hơn, có một cách sử dụng khác như sau: loadChildren: './admin/admin.module#AdminModule'. Đây là một chuỗi “magic”, chỉ định đường dẫn tệp đến tệp chứa NgModule cùng với Router cần tải.

Preloading Lazy Module

Việc chia thành các lazy loading module mang lại nhiều lợi ích cho trải nghiệm của người dùng khi tải trang. Với việc giảm kích thước file JS cần phải tải, thời gian chờ đợi để tương tác với trang web giảm đi. Tuy nhiên, đôi khi các lazy loading module có thể có kích thước lớn, dẫn đến việc mất thời gian khi người dùng chuyển đến một trang mới. Ví dụ như việc lazy loading AdminModule, giả sử mạng của người dùng giả định là mạng di động, hãy xem tình hình thế nào.

![Bước 13] – Thời gian chờ khi tải AdminModule Người dùng phải đợi lâu, có thể lên đến vài giây từ khi bấm vào liên kết Admin cho đến khi giao diện người dùng hiện ra. Quá trình này quá chậm.

Để giải quyết vấn đề này, chúng ta có thể sử dụng kỹ thuật “Preloading” để tải các bundle trong nền.

Để kích hoạt preloading cho tất cả các lazy loaded modules, bạn cần import PreloadAllModules từ gói @angular/router và cấu hình nó trong AppRoutingModule, trong phần forRoot.

import { PreloadAllModules } from "@angular/router";

const routes: Routes = [
  {
    path: "admin",
    loadChildren: () =>
      import("./admin/admin.module").then((m) => m.AdminModule),
  },
  {
    path: "",
    redirectTo: "article",
    pathMatch: "full",
  },
];

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

Chạy lại ứng dụng để kiểm tra.

![Bước 14] – Kết quả khi sử dụng Preloading Tuyệt vời! Nếu bạn quay trở lại trang chủ, bạn sẽ thấy rằng ngay sau khi trang chủ được tải, ứng dụng đã tự động tải về admin-admin-module.js. Do mình không sử dụng lệnh ng build với cờ --prod=true, nên kích thước file hơi lớn. Tuy nhiên, khi bạn xây dựng với cờ --prod, kích thước file sẽ nhẹ hơn nhiều.

Để preload các module theo ý muốn thay vì toàn bộ các lazy loading module, bạn có thể tìm hiểu thêm tại đây. Tuy bài viết có giới hạn, nhưng mình hy vọng rằng nó sẽ giúp bạn hiểu rõ hơn về cách sử dụng kỹ thuật Preloading trong Angular.

Bài viết liên quan:

Sắp xếp sủi bọt – Bubble Sort
TypeScript với Kiểu Dữ Liệu Cơ Bản – 3
TypeScript với Kiểu Dữ Liệu Cơ Bản – 2
TypeScript với Kiểu Dữ Liệu Cơ Bản – 1
Typescript cơ bản và cách cài đặt cho người mới
Thực Hành Micro Frontends
Dynamic Component trong Angular
Async Validator trong Angular Form
Reactive Forms Trong Angular (Phần 2)
Reactive Forms Trong Angular (Phần 1)
Template-driven Forms Trong Angular (Phần 2)
Template-driven Forms Trong Angular (Phần 1)

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

2. PHÂN TÍCH VÀ ĐẶC TẢ HỆ THỐNG

1. TỔNG QUAN KIẾN THỨC THỰC HÀNH TRIỂN KHAI DỰ ÁN CÔNG NGHỆ THÔNG TIN

Hướng dẫn tự cài đặt n8n comunity trên CyberPanel, trỏ tên miền

Mẫu prompt tạo mô tả chi tiết bối cảnh

Một số cải tiến trong ASP.NET Core, Razor Page, Model Binding, Gabbage collection

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×