As an excellent Web framework, AnglarJS can greatly simplify the burden of front-end development. Recently, Sebastian Fröstl said in a blog post "AngularJS Performance Tuning for Long Lists", that AnglarJS will run very slowly when processing large lists containing complex data structures. He also shared the solution in the article. The following is the translation of this article.
AnglarJS is great, but it runs very slowly when dealing with large lists containing complex data structures. This is a problem we encountered in the process of migrating the core management page to AngularJS. These pages should have worked smoothly when displaying 500 lines of data, but the rendering time of the first method took 7 seconds, which was terrible.
Later, we discovered two major performance problems during the implementation process. One is related to the "ng-repeat" directive and the other is related to the filter.
The following article will share our experience in solving performance problems through different methods, hoping to give you inspiration.
1. Why does ng-repeat in AngularJS slow down when processing large lists?
ng-repeat in AngularJS slows down when processing more than 2500 bidirectional data bindings. This is because AngularJS detects changes through the "dirty checking" function. Each detection takes time, so a large list of complex data structures will slow down your application running.
2. Prerequisites for improving performance
Time record command
To measure the time it takes for a list rendering, we wrote a simple program to record time by using the property "$last" of "ng-repeat". Time is stored in the TimeTracker service, so that time records are separated from the server-side data loading.
// Post repeat directive for logging the rendering time ('').directive('postRepeatDirective', ['$timeout', '$log', 'TimeTracker', function($timeout, $log, TimeTracker) { return function(scope, element, attrs) { if (scope.$last){ $timeout(function(){ var timeFinishedLoadingList = (); var ref = new Date(timeFinishedLoadingList); var end = new Date(); $("## DOM rendering list took: " + (end - ref) + " ms"); }); } }; } ]); // Use in HTML: …
Timeline properties of Chrome Developer Tools
In the Timeline tab of Chrome Developer Tools, you can see events, browser frames per second, and memory allocation. The “memory” tool is used to detect memory leaks and memory required by the page. Page flickering issues occur when the frame rate is less than 30 frames per second. The "frames" tool helps understand rendering performance and also shows the CPU time spent on a JavaScript task.
3. Basic optimization is performed by limiting the size of the list
The best way to mitigate this problem is to limit the size of the displayed list. It can be achieved by paging and adding infinite scroll bars.
Pagination
To paginate, we can use AngularJS's "limitTo" filter (AngularJS1.1.4 version and "startFrom" filter. Rendering time can be reduced by limiting the size of the display list. This is the most efficient way to reduce rendering time.
// Pagination in controller $ = 0; $ = 75; $ = function() { return ($/ $); }; // Start from filter ('app').filter('startFrom', function() { return function(input, start) { return (start); }; // Use in HTML // Pagination buttons{{$index + 1}}
If you can't/do not want to use paging, but the filtering process is slow, be sure to check the first five steps and use "ng-show" to hide the extra list elements.
Infinite scrollbar
If you want to know more about this method, please visit/ngInfiniteScroll/
Fourth and Seven Rules of Tuning
1. Rendering a list without data binding
This is the most obvious solution, because data binding is the most likely source of performance issues. If you only want to display the list once and do not need to update or change the data, giving up data binding is an excellent way. Unfortunately, you will lose control of the data, but we have no choice but to do so. Learn more:/Pasvaz/bindonce。
2. Do not use inline methods to calculate data
To filter the list directly in the controller, do not use methods that can obtain filtering links. "ng-repeat" evaluates each [$digest(/api/ng.$#$digest)%5Dexpression. In our case, "filteredItems()" returns the filter link. If the evaluation process is slow, it will quickly slow down the entire application.
//This is not a good way to evaluate frequently.
//This is the method to be adopted
3. Use two lists (one for view display and one as data source)
Separating the list to be displayed from the total data list is a very useful model. You can preprocess some filtering and apply the links stored in the cache to the view. The following case shows the basic implementation process. The filteredLists variable holds the link in the cache, and the applyFilter method handles the mapping.
/* Controller */ // Basic list var items = [{name:"John", active:true }, {name:"Adam"}, {name:"Chris"}, {name:"Heather"}]; // Init displayedList $ = items; // Filter Cache var filteredLists['active'] = $filter('filter)(items, {"active" : true}); // Apply the filter $ = function(type) { if ((type){ // Check if filter is cached $ = filteredLists[type]; } else { /* Non cached filtering */ } } // Reset filter $ = function() { $ = items; } /* View */Select active
{{}}
4. Use ng-if in other templates instead of ng-show
If you use instructions and templates to render additional information, such as clicking to display detailed information of list items, be sure to use ng-if (AngularJSv. 1.1.5 and later). ng-if prevents rendering (compared to ng-show). Therefore, other DOM and data binding can be evaluated as needed.
The above content provides you with 7 suggestions for AngularJS to perform performance tuning, and I hope you like it.