Làm thế nào cải thiện performance trong ứng dụng angular js
Bài đăng này đã không được cập nhật trong 3 năm
Đã có rất nhiều thảo luận về những tính năng tuyệt vời mà angularjs mang lại cho những ứng dụng trên nền web như: two way-binding, dependency injection, directive, service,..Tuy nhiên, trong quá trình xây dựng các ứng dụng lớn cùng angularjs chúng ta có thể gặp rất nhiều vấn đề về performace. Điều này yêu cầu các lập trình viên cần control tốt về ưu và nhược điểm của framework nổi tiếng này. Trong bài viết này tôi sẽ giới thiệu tới các bạn những gợi ý để cải thiện hiệu suất app sử dụng angularjs.
1. Giảm thiểu tối đa hoặc tránh sử dụng các watches
Thông thường khi angular app bị chậm có 2 nguyên chính, một là có quá nhiều watchers hoặc các watchers làm việc nhiều hơn so với nhu cầu cần thiết. Angular sử dụng cái gọi là "dirty checking" để theo dõi tất các thay đổi trong app. Nghĩa là, nó phải duyệt qua tất cả các watchers để kiểm tra liệu chúng cần cập nhật hay không.
1.1 Các loại watches
- $scope.$watch
- {{ }} bindings
- Hầu hết các directives (ng-show, ng-hide,..)
- Scope variables scope: { bar: '='}
- Filters {{ value | myFilter }}
- ng-repeat
1.2. Watchers (digest cycle) chạy khi nào
- User actions (ng-click, ng-enter,..)
- ng-change
- ng-model
- $http events
- $q promises resolved
- $timeout
- $interval
- Manual $scope.apply and $scope.digest
2. Tránh dùng ng-repeat nếu phải sử dụng scrolling vô hạn hoặc phân trang
Về bản chất angular sử dụng $watchCollection để phát hiện sự thay đổi của collecion trong ng-repeat. Khi collection càng lớn, với mỗi thay đổi angular sẽ re-render DOM, như vậy sẽ là cái giá đắt cho performace. Để khắc phục điều này chúng ta nên sử dụng track by $index để hạn chế tối đa việc tạo mới phần tử DOM. Khi sử dụng cú pháp này, angular chỉ cập nhật những phần tử thay đổi chứ không re-render lại toàn bộ DOM như trước. Chúng ta có thể dùng nó như sau:
<li ng-repeat="item in items track by item.Id></li>
3. Sử dụng binding một lần khi có thể
Từ angular 1.3, bạn có thể sử dụng :: để binding một lần. Điều này nghĩa là: Sau khi bind giá trị hoàn thành trên DOM, angular sẽ không tiếp tục watches cho các lần sau. Như vậy app có thể gỡ bỏ một watcher không cần thiết.
<p id="one-time-binding-example">One time binding: {{::name}}</p>
4. Sử dụng $watchCollection thay vì dùng $watch (sử dụng tham số thứ 3)
$watch với 2 tham số là khá nhanh. Tuy nhiên, khi sử dụng watch với 3 tham số giống như:
$watch('value', function(){}, true)
Với tham số thứ 3 này, angular sẽ kiểm tra sự thay đổi mọi thuộc tính của đối tượng, điều này có thể ảnh hưởng lớn đến performance của ứng dụng. Để giải quyết vấn đề này chúng ta có thể sử dụng
$watchCollection('value', function(){})
Thay đổi này có thể áp dụng cho hầu hết các các $watch sử dụng tham số thứ 3 và hiệu quả là rất cao.
5. Tránh sử dụng filters lập lại bất kì khi nào có thể
Việc binding một lần không được thực hiện với filter. Để tăng performance, chúng ta có thể dùng một biến để lưu giá trị đã được filter (Hoặc gán nó như một thuộc tính của đối tượng)
Ví dụ, thay vì:
{{'DESCRIPTION' | translate }}
Bạn có thể làm:
– JavaScript
$scope.description: $translate.instant('DESCRIPTION')
– HTML
{{::description}}
Thay vì:
{{step.time_modified | timeFormatFilter}}
JavaScript
var timeFormatFilter = $filter('timeFormatFilter');
step.time_modified = timeFormatFilter(step.time_modified);
Trong HTML
{{::Path.time_modified}}
6. Sử dụng Debounce ng-model cho ng-model
Nếu bạn phát hiện ra rằng có rất nhiều thay đổi đến từ ng-model, bạn có thể sử dụng de-bounce cho input. Ví dụ, nếu bạn có một input tìm kiếm, bạn có để de-bounce bằng việc thiết lập ng-model option:
ng-model-options="{ debounce: 250 }.
Điều này sẽ đảm bảo digest cycle do thay đổi của input sẽ chỉ xảy ra sau mỗi 250 ms. Nhằm hạn chế việc tracking liên tục làm giảm performance hệ thống.
7. Sử dụng ng-if thay vì ng-show
Ng-show sẽ vẫn render một phần tử và chỉ thiết lập display:none để ẩn nó. Ng-if thực tế sẽ gỡ bỏ phần tử trên DOM và tạo lại nó khi cần thiết. Bạn có thể cần sử dụng ng-show cho một phần tử mà thường xuyên thay đổi trạng thái. Nhưng hầu hết các trường hợp, ng-if là cách sử dụng tốt hơn.
8. Sử dụng Batarang đo hiệu năng watchers trong angular
Batarang là một công cụ tuyệt vời từ Angular team và nó là rất hữu ích trong việc debugging. Nó có rất nhiều tính năng hữu ích. Một trong số đo là thích hợp trong trường hợp sử dụng kiểm tra performance
Trên đây là những gợi ý nhằm giúp tăng performace cho angular app. Hy vọng những chia sẻ này có thể giúp ích cho các bạn đang nghiên cứu, xây dựng ứng dụng với angular. Chúc các bạn thành công. Các bạn có thể tham khảo thêm tại link gốc sau:
All rights reserved