So sánh module và component trong angular năm 2024
Một ứng dụng angular có nhiều tính năng và thường thì ta sẽ chia mỗi tính năng thành 1 module. Khi tải ứng dụng, nếu không sử dụng lazy load thì angular sẽ tải tất cả các module này 1 lúc, vấn đề ở đây là có nhiều trang nằm trên các module khác mà ta chưa cần hiển thị nhưng angular vẫn tải lên, điều này là thừa và gây vấn đề hiệu suất, lazy load sẽ giải quyết vấn đề này. Ý nghĩa của việc lazy load là chỉ tải khi dùng đến, tức là khi ta click vào 1 link nào đấy, ta sẽ di chuyển sang trang khác, lúc này module chứa trang này mới được tải lên. Show VD1: TH không dùng lazy load const routes: Routes = [ {path: 'dashboard', component: 'DashboardModule'}, {path: 'admin', component: 'AdminModule'}, {path: 'purchase', component: 'PurchaseModule'}, {path: '**', redirectTo: 'dashboard'} ] \=> khi ứng dụng được tải lên thì DashboardModule, AdminModule, PurchaseModule được tải luôn, nếu có nhiều module hơn thì tải sẽ lâu VD2: TH dùng lazy load const routes: Routes = [ {path: 'dashboard', loadChildren: () => import('./admin/dashboard.module').then(m => m.DashboardModule)}, {path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)}, {path: 'purchase', loadChildren: () => import('./admin/purchase.module').then(m => m.PurchaseModule)}, {path: '**', redirectTo: 'dashboard'} ] \=> khi click vào link dashboard => DashboardModule mới được tải 2. trackByKhi danh sách hiển thị trên màn hình được update, lúc này angular sẽ render lại toàn bộ danh sách mới lên html, nếu như các record bán đầu không thay đổi gì mà vẫn phải render lại là không cần thiết và làm app chậm hơn, sử dụng trackBy sẽ giải quyết vấn đề này VD1: TH không sử dụng trackBy @Component({ selector: 'the-fruits', template: \=> khi click button Add fruit, fruits sẽ có thêm 1 record ({ id: 5, name: 'Peach' }), lúc này html sẽ render lại tất cả các records trên fruits VD2: TH dùng trackBy @Component({ template: \=> khi click button Add fruit, fruits sẽ có thêm 1 record ({ id: 5, name: 'Peach' }) => html sẽ chỉ render lại record này Chú ý: trackBy sẽ hữu ích trong TH phải update lại list để hiển thị 3. Sử dụng AOT thay vì JIT để biên dịchTrong ứng dụng angular angular, trước khi trình duyệt có thể hiển thị ứng dụng, các component, template phải được trình biên dịch Angular chuyển đổi sang JavaScript thực thi. Với AOT thì trình duyệt sẽ tải xuống mã đã được biên dịch trước, nên nó có thể hiển thị luôn. Với JIT thì khi trình duyệt truy cập ứng dụng, nó sẽ tải cả trình biên dịch về (@angular/compile) để vừa chạy vừa biên dịch nên việc hiển thị sẽ chậm hơn. JIT:
AoT:
Do đó, quá trình build của AoT chắc chắn sẽ lâu hơn, nhưng render lại nhanh hơn vì tất cả đã được biên dịch sẵn và chỉ chờ để đưa lên. Cách dùng: ng build --prod --aot hoặc config trong angular.json: projects -tên app - architect - build - options - aot = true và chạy ng b --prod 4. Sử dụng pipe thay vì dùng function trong htmlNguyên nhân: pipe sẽ chỉ kích hoạt lại khi đối số đầu vào thay đổi tham chiếu (kiểu đối tượng, array), còn với method nó sẽ thực thi mỗi khi data thay đổi. VD:
Trên console hiển thị như sau: Method called Pipe called Method called Method called Method called Ngay khi hiển thị màn hình thì việc sử dụng method userName() sẽ call 4 lần, còn nếu sử dụng Pipe chỉ call 1 lần vì transform chỉ được trigger lại khi tham chiếu đầu vào thay đổi, cần lưu ý khi giá trị đầu vào có kiểu nguyên thủy, khi giá trị thay đổi thì nó sẽ không được cập nhật trên template. 5. Change detectionAngular bao gồm một cây các component, mỗi component có trình cung cấp ChangeDetectorRef của riêng nó, chịu trách nhiệm xử lý cập nhật liên kết của component đó. Khi ứng dụng được khởi động, ban đầu nó tạo ApplicationContext(root) và trigger phương thức tick() trên AppComponent, phương thức này bắt đầu chạy phát hiện thay đổi trên từng component từ trên cùng (AppComponent) của cây. Theo mặc định: khi phát hiện thay đổi kích hoạt ở bất kỳ component nào, nó sẽ bắt đầu kích hoạt từ component gốc (AppComponent) để xem có cập nhật view hay không. Phát hiện thay đổi xảy ra khi:
Quá trình phát hiện thay đổi này xảy ra đối với tất cả các component. Nó đánh giá tất cả các ràng buộc của một component, bất kể ràng buộc đó có bị thay đổi hay không, điều này ảnh hưởng rất lớn đến hiệu suất. Giả sử một cây có khoảng 50 cấp component và một số component đã kích hoạt phát hiện thay đổi, cuối cùng sẽ kích hoạt phát hiện thay đổi ở tất cả các component từ trên xuống dưới, điều này có nghĩa những component không cần chạy phát hiện thay đổi cũng sẽ phải chạy => vừa thừa vừa ảnh hưởng lớn đến hiệu năng. Để khắc phục vấn đề này, ta sẽ dùng Change Detection OnPush. Chỉ cần thêm changeDetection: ChangeDetectionStrategy.OnPush vào bên trong @Component @Component({ templateUrl: ..., changeDetection: ChangeDetectionStrategy.OnPush }) Khi này, từ component này chở xuống, các component con sẽ chỉ chạy phát hiện thay đổi khi:
myMethod() { this.cd.markForCheck(); } Các sự kiện sau KHÔNG kích hoạt phát hiện thay đổi
6. Sử dụng detachKhi muốn tách rời 1 component khỏi phát hiện thay đổi, tức là khi app chạy phát hiện thay đổi sẽ không chạy từ component này xuống con của nó, ta dùng detach. constructor(cd: ChangeDetectorRef) { cd.detach(); } Nếu muốn đưa component này lại cho mỗi lần chạy phát hiện thay đổi đều chạy qua nó thì dùng mySpecificMethod() { this.cd.reattach(); } 7. Sử dụng NgZone chạy Angular outsideconstructor(private zone: NgZone) { this.zone.runOutsideAngular(() => { // code }); } Những thay đổi giá trị property được viết trong scope của hàm runOutsideAngular() sẽ không kích hoạt phát hiện thay đổi, thích hợp cho Th như lấy tín hiệu thông báo, update theo thời gian thực như chat, comment Ngoài ra còn 1 số phương pháp khác nữa là: tối ưu html, css, sử dụng rxjs, config phía server để cache file tĩnh như html, css, assets, js, dùng service worker ... |