Hãy cải thiện hiệu suất của ứng dụng bằng cách sử dụng tính năng phân tách mã cấp tuyến đường!
Bài đăng này giải thích cách thiết lập tính năng phân tách mã cấp tuyến trong ứng dụng Angular. Cách này có thể làm giảm kích thước gói JavaScript và cải thiện đáng kể Thời gian tương tác.
Bạn có thể tìm thấy mã mẫu trong bài viết này trên GitHub. Ví dụ định tuyến mong muốn có trong nhánh eager. Ví dụ về phân tách mã cấp tuyến nằm trong nhánh từng phần (lazy Branch).
Tại sao việc chia tách mã lại quan trọng
Tính phức tạp ngày càng tăng của các ứng dụng web đã dẫn đến sự gia tăng đáng kể về lượng JavaScript được gửi đến người dùng. Các tệp JavaScript lớn có thể làm chậm trễ đáng kể khả năng tương tác, vì vậy đây có thể là một tài nguyên tốn kém, đặc biệt là trên thiết bị di động.
Cách hiệu quả nhất để thu gọn các gói JavaScript mà không làm giảm tính năng trong ứng dụng của bạn là triển khai tính năng chia tách mã linh hoạt.
Tính năng phân tách mã cho phép bạn chia JavaScript của ứng dụng thành nhiều phần được liên kết với các tuyến hoặc tính năng khác nhau. Phương pháp này chỉ gửi cho người dùng JavaScript họ cần trong quá trình tải ứng dụng ban đầu, giúp duy trì thời gian tải thấp.
Kỹ thuật phân tách mã
Bạn có thể phân tách mã ở hai cấp: cấp thành phần và cấp định tuyến.
- Trong quá trình phân tách mã cấp thành phần, bạn sẽ di chuyển các thành phần vào các phân đoạn JavaScript của riêng chúng và tải từng phần khi cần thiết.
- Trong quá trình phân tách mã cấp tuyến đường, bạn đóng gói chức năng của mỗi tuyến thành một đoạn riêng. Khi người dùng điều hướng đến ứng dụng của bạn, họ sẽ tìm nạp các đoạn được liên kết với các tuyến riêng lẻ và nhận chức năng liên quan khi cần.
Bài đăng này tập trung vào việc thiết lập chế độ phân chia cấp tuyến trong Angular.
Ứng dụng mẫu
Trước khi tìm hiểu cách sử dụng tính năng phân tách mã cấp tuyến đường trong Angular, hãy xem một ứng dụng mẫu:
Xem cách triển khai các mô-đun của ứng dụng. Có hai tuyến bên trong AppModule
được xác định: tuyến mặc định liên kết với HomeComponent
và tuyến nyan
liên kết với NyanComponent
:
@NgModule({
...
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'nyan',
component: NyanComponent
}
])
],
...
})
export class AppModule {}
Phân tách mã cấp tuyến đường
Để thiết lập chế độ phân tách mã, bạn cần tái cấu trúc tuyến mong muốn nyan
.
Phiên bản 8.1.0 của Angular CLI có thể làm mọi thứ cho bạn bằng lệnh này:
ng g module nyan --module app --route nyan
Thao tác này sẽ tạo ra:
– Một mô-đun định tuyến mới có tên là NyanModule
– Một tuyến trong AppModule
có tên là nyan
. Tuyến này sẽ tải NyanModule
một cách linh động
– Tuyến mặc định trong NyanModule
– Một thành phần có tên là NyanComponent
sẽ xuất hiện khi người dùng nhấn vào tuyến mặc định
Hãy xem các bước này theo cách thủ công để hiểu rõ hơn về cách triển khai quá trình phân tách mã bằng Angular!
Khi người dùng chuyển đến tuyến nyan
, bộ định tuyến sẽ kết xuất NyanComponent
tại ổ cắm của bộ định tuyến.
Để sử dụng tính năng phân tách mã cấp tuyến trong Angular, hãy đặt thuộc tính loadChildren
trong phần khai báo tuyến đường và kết hợp thuộc tính đó với tính năng nhập động:
{
path: 'nyan',
loadChildren: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}
Có hai điểm khác biệt chính so với tuyến mong muốn:
- Bạn đã đặt
loadChildren
thay vìcomponent
. Khi sử dụng tính năng phân tách mã cấp tuyến, bạn cần trỏ đến các mô-đun được tải động thay vì các thành phần. - Trong
loadChildren
, sau khi giải quyết lời hứa, bạn sẽ trả vềNyanModule
thay vì trỏ đếnNyanComponent
.
Đoạn mã ở trên chỉ định rằng khi người dùng chuyển đến nyan
, Angular sẽ tải động nyan.module
từ thư mục nyan
và kết xuất thành phần liên kết với tuyến mặc định đã khai báo trong mô-đun.
Bạn có thể liên kết tuyến mặc định với một thành phần bằng cách sử dụng nội dung khai báo sau:
import { NgModule } from '@angular/core';
import { NyanComponent } from './nyan.component';
import { RouterModule } from '@angular/router';
@NgModule({
declarations: [NyanComponent],
imports: [
RouterModule.forChild([{
path: '',
pathMatch: 'full',
component: NyanComponent
}])
]
})
export class NyanModule {}
Mã này hiển thị NyanComponent
khi người dùng chuyển đến https://example.com/nyan
.
Cách kiểm tra xem bộ định tuyến Angular có tải từng phần nyan.module
xuống trong môi trường cục bộ của bạn hay không:
- Nhấn tổ hợp phím "Control + Shift + J" (hoặc "Command+Option+J" trên máy Mac) để mở Công cụ cho nhà phát triển.
Nhấp vào thẻ Mạng.
Nhấp vào NYAN trong ứng dụng mẫu.
Xin lưu ý rằng tệp
nyan-nyan-module.js
xuất hiện trong thẻ mạng.
Tìm ví dụ này trên GitHub.
Hiển thị vòng quay
Hiện tại, khi người dùng nhấp vào nút NYAN, ứng dụng này không cho biết đang tải JavaScript ở chế độ nền. Để cung cấp cho người dùng phản hồi trong khi tải tập lệnh, bạn có thể thêm một vòng quay.
Để làm việc này, hãy bắt đầu bằng cách thêm mã đánh dấu cho chỉ báo bên trong phần tử router-outlet
trong app.component.html
:
<router-outlet>
<span class="loader" *ngIf="loading"></span>
</router-outlet>
Sau đó, hãy thêm một lớp AppComponent
để xử lý các sự kiện định tuyến. Lớp này sẽ thiết lập cờ loading
thành true
khi nghe thấy sự kiện RouteConfigLoadStart
và thiết lập cờ thành false
khi nghe thấy sự kiện RouteConfigLoadEnd
.
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
loading: boolean;
constructor(router: Router) {
this.loading = false;
router.events.subscribe(
(event: RouterEvent): void => {
if (event instanceof NavigationStart) {
this.loading = true;
} else if (event instanceof NavigationEnd) {
this.loading = false;
}
}
);
}
}
Trong ví dụ bên dưới, chúng tôi đã giới thiệu độ trễ nhân tạo 500 mili giây để bạn có thể thấy vòng quay hoạt động.
Kết luận
Bạn có thể thu nhỏ kích thước gói của các ứng dụng Angular bằng cách áp dụng chế độ phân tách mã ở cấp tuyến đường:
- Sử dụng trình tạo mô-đun tải từng phần của Angular CLI để tự động sắp xếp một tuyến đường được tải động.
- Thêm chỉ báo đang tải khi người dùng di chuyển đến một tuyến từng phần để cho biết là có một hành động đang diễn ra.