AngularJS really slow at rendering with about 2000 elements?

Asked
Active3 hr before
Viewed126 times

8 Answers

angularjsrenderingreally
90%

In AngularJS 1.3+, there is One-time binding built-in:,The main purpose of one-time binding expression is to provide a way to create a binding that gets deregistered and frees up resources once the binding is stabilized. Reducing the number of expressions being watched makes the digest loop faster and allows more information to be displayed at the same time.,In order to make the one-time binding, prepend :: to the binding value:, 3 As this is a one time binding, does this mean that the initial rendering of the elements will not be any faster? As the binding is required for the first pass of interpolation. – Neil Oct 9 '14 at 21:48

In order to make the one-time binding, prepend :: to the binding value:

<div>{{::name}}</div> 
load more v
88%

Notice that limit is a variable in the $scope, so changing it automatically adjusts the number of rendered items. And incrementing limit, only renders the added elements.(The drawn elements in the DOM remain untouched) From StackOverflow question.,Final solution: Upgrade to AngularJS 1.1.5 and use limitTo together with Infinite scrolling. AngularJS ng-repeat offers from version 1.1.4 the limitTo option. I slightly adapted the Infinite Scroll directive to make scrolling within a container possible that does not have height 100% of window.,AngularJS is great. I started with BackboneJS as frontend MVC, but soon switch to AngularJS because of the concept AngularJS adds to HTML. AngularJS allows me to get simple things get done very quickly, watch a value for changes and update the views whenever necessary.,NOTE: when using TRACK BY be sure to add it correctly to the ng-repeat line.

  • https://github.com/Pasvaz/bindonce Bindonce allows to create a template to render that uses jQuery to render the HTML, so no two-way binding. This was the first solution i tried and even though I expected this to solve the problem, i was surprised to see it did not. Performance improve only slightly, maybe we gained 100ms to render, but the rendering still took over 500ms.
  • http://onehungrymind.com/angularjs-dynamic-templates/ Dynamic templates gave me another promise to migrate code to pure JavaScript rather than templates with two-way bindings. Again no success.
  • http://blog.stackfull.com/2013/02/angularjs-virtual-scrolling-part-1/ Virtual Scrolling just renders the visible elements and removes invisible elements from the DOM. In fact this solved the problem of the slow rendering, but created another one namely that scrolling now had bad performance. On mobile scrolling wa not controllable. Swiping down or up produced unexpected results.
  • Final solution: Upgrade to AngularJS 1.1.5 and use limitTo together with Infinite scrolling. AngularJS ng-repeat offers from version 1.1.4 the limitTo option. I slightly adapted the Infinite Scroll directive to make scrolling within a container possible that does not have height 100% of window.
ng - repeat = "item in items | orderBy:prop | filter:query | limitTo:limit"
load more v
72%

ReactItemList is the name of the component we wish to use, and items is a scoped array defined in the controller.,To implement ReactJS and ngReact into an Angular app, you will need the following:,If you’re reading this, you most probably tried to make a long and/or complex list of items using a ng-repeat directive, and after seeing how it performs in terms of speed, felt like AngularJS failed you.,An AngularJS app with a controller and a view template

This code generates an unordered list with two anchors (one visible, and one hidden) which can be interacted with. Things are a bit backwards when writing ReactJS code - the parent-most ReactJS component (ReactItemList) is at the bottom of the JSX file and the nested components (ReactItem and ReactSubItem) are above it. This is simply because all the nested components need to be available in the code before their parent components. At the top of the file we have two click handlers and the neat thing about all this is that we have Angular scope inside our ReactJS code. This means we can call any exposed (scoped through the controller) variables and functions which gives us a lot of flexibility. You can notice how we propagated the scope all the way through the most components. We have used these two click handlers to make a connection between ReactJS onClick property and the two Angular scoped functions from the controller that look like this:

$scope.onReactShowSubItemClick = function(reactComponent) {
   var item = reactComponent.props.item;
   item.prop6.show = !item.prop6.show;
   item.prop6.showHide = item.prop6.show ? "Hide" : "Show";
   reactComponent.setState({
      item: item,
      scope: $scope
   });
};

$scope.onReactUpdateSubItemClick = function(reactComponent) {
   var item = reactComponent.props.item;
   item.prop6.counter++;
   reactComponent.setState({
      item: item,
      scope: $scope
   });
};
load more v
65%

Resolves add extra time to the loading of the view. I believe that high performance of the front-end app is our primary goal. It should not be a problem to render some parts of the view while the app waits for the data from the API.,I wanted to give credits to four publishing developers that inspired me the most:,There are two ways, in both of them you pass values to attributes. Consider this MainController:,That is one of the few recommended options for production.

DebugInfoEnabled is a setting which defaults to true, and allows for scope access through DOM nodes. If you want to try that through the JavaScript console, select a DOM element and access its scope with:

angular.element(document.body).scope()
load more v
75%

This is one of the many cases where “the framework is fast, your code is slow”.,The framework is fast, your code is slow,Frameworks in 2020 got better, more efficient and faster. With that said, rendering large lists of items on the Web without causing the Browser to freeze can still be hard even for the fastest frameworks available.,given a container and a list of items, an item is only rendered if it’s within the visible boundaries of the container

To use the CDK’s Scrolling module, we first need to install the module:

npm i @angular / cdk

Then, we import the module:

import {
   ScrollingModule
} from '@angular/cdk/scrolling';
@NgModule({
   ...imports: [ScrollingModule, ...]
}) export class AppModule {}

We can now use the components to use virtual scrolling in our components:

<cdk-virtual-scroll-viewport itemSize="50">        <div *cdkVirtualFor="let item of items">   {{ item }} </div></cdk-virtual-scroll-viewport>

We have a simple ngFor loop template:

<tr *ngFor="let item of data; trackBy: trackById; let isEven = even; let isOdd = odd"    class="h-12"    [class.bg-gray-400]="isEven"    [class.bg-gray-500]="isOdd">  <td>    <span class="py-2 px-4">{{ item.id }}</span>  </td>  <td>    <span>{{ item.label }}</span>  </td>  <td>    <a>      <button class="py-2 px-4 rounded (click)="remove(item)">x</button>    </a>  </td></tr>
load more v
40%

The plunker above demonstrates a simple select element with 2000 options takes about a second to render.,I started exploring AngularJS but wasn't really happy with the time Angular takes to render a select element with huge number of options.,On adding two more select elements, the screen rendering time got tripled., Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

FWIW, it seems to be 3.5x faster with 1.4.0-beta.5 (probably due to ngOptions refactoring).

ngOptions
22%

Not everything needs to be “Angular.” In Directives there are many cases we need to work with pure DOM.,Using the single binding syntax is easy and most importantly fast. The syntax is clear and concise, and a real benefit to lowering the $$watcher overhead. The less work Angular has to do, the more responsive our applications will become.,binPress is here to help get started and grow your online presence. Our team of experts creates and publishes valuable content that will help you succeed.,Before diving into code, consider how to best architect your application to avoid performance challenges that dirty-checking faces in large quantities of Objects.

AngularJS is a huge framework with that already has many performance enhancements built in, but they can’t solve all our problems. No matter how fast the framework, we can all create sluggish code through bad practices and not understanding key concepts that help it perform well. The following performance pointers are some of the things I’ve learned from developing Angular applications that will hopefully enable you to keep building fast applications.

The key concept behind these performance considerations is reducing the number of $$watchersinside Angular to improve the $digest cycle’s performance, something you’ll see and hear more of as you continue working with Angular. These are crucial to keeping our application state fast and responsive for the user. Each time a Model is updated, either through user input in the View, or via service input to the Controller, Angular runs something called a $digest cycle.

$$watchers

AngularJS is a huge framework with that already has many performance enhancements built in, but they can’t solve all our problems. No matter how fast the framework, we can all create sluggish code through bad practices and not understanding key concepts that help it perform well. The following performance pointers are some of the things I’ve learned from developing Angular applications that will hopefully enable you to keep building fast applications.

The key concept behind these performance considerations is reducing the number of $$watchersinside Angular to improve the $digest cycle’s performance, something you’ll see and hear more of as you continue working with Angular. These are crucial to keeping our application state fast and responsive for the user. Each time a Model is updated, either through user input in the View, or via service input to the Controller, Angular runs something called a $digest cycle.

$digest

AngularJS is a huge framework with that already has many performance enhancements built in, but they can’t solve all our problems. No matter how fast the framework, we can all create sluggish code through bad practices and not understanding key concepts that help it perform well. The following performance pointers are some of the things I’ve learned from developing Angular applications that will hopefully enable you to keep building fast applications.

The key concept behind these performance considerations is reducing the number of $$watchersinside Angular to improve the $digest cycle’s performance, something you’ll see and hear more of as you continue working with Angular. These are crucial to keeping our application state fast and responsive for the user. Each time a Model is updated, either through user input in the View, or via service input to the Controller, Angular runs something called a $digest cycle.

$digest
load more v
60%

The expression indicating how to enumerate a collection. These formats are currently supported:,ngRepeat will silently ignore object keys starting with $, because it's a prefix used by AngularJS for public ($) and private ($$) properties.,ngRepeat will silently ignore object keys starting with $, because it's a prefix used by AngularJS for public ($) and private ($$) properties. ,All different types of tracking functions, their syntax, and their support for duplicate items in collections can be found in the ngRepeat expression description.

It is possible to get ngRepeat to iterate over the properties of an object using the following syntax:

<div ng-repeat="(key, value) in myObj"> ... </div>
angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
   var friends = [{
         name: 'John',
         age: 25
      },
      {
         name: 'Mary',
         age: 40
      },
      {
         name: 'Peter',
         age: 85
      }
   ];

   $scope.removeFirst = function() {
      $scope.friends.shift();
   };

   $scope.updateAge = function() {
      $scope.friends.forEach(function(el) {
         el.age = el.age + 5;
      });
   };

   $scope.copy = function() {
      $scope.friends = angular.copy($scope.friends);
   };

   $scope.reset = function() {
      $scope.friends = angular.copy(friends);
   };

   $scope.reset();
});
<div ng-controller="repeatController">
  <ol>
    <li>When you click "Update Age", only the first list updates the age, because all others have
    a one-time binding on the age property. If you then click "Copy", the current friend list
    is copied, and now the second list updates the age, because the identity of the collection items
    has changed and the list must be re-rendered. The 3rd and 4th list stay the same, because all the
    items are already known according to their tracking functions.
    </li>
    <li>When you click "Remove First", the 4th list has the wrong age on both remaining items. This is
    due to tracking by $index: when the first collection item is removed, ngRepeat reuses the first
    DOM element for the new first collection item, and so on. Since the age property is one-time
    bound, the value remains from the collection item which was previously at this index.
    </li>
  </ol>

  <button ng-click="removeFirst()">Remove First</button>
  <button ng-click="updateAge()">Update Age</button>
  <button ng-click="copy()">Copy</button>
  <br><button ng-click="reset()">Reset List</button>
  <br>
  <code>track by $id(friend)</code> (default):
  <ul class="example-animate-container">
    <li class="animate-repeat" ng-repeat="friend in friends">
      {{friend.name}} is {{friend.age}} years old.
    </li>
  </ul>
  <code>track by $id(friend)</code> (default), with age one-time binding:
  <ul class="example-animate-container">
    <li class="animate-repeat" ng-repeat="friend in friends">
      {{friend.name}} is {{::friend.age}} years old.
    </li>
  </ul>
  <code>track by friend.name</code>, with age one-time binding:
  <ul class="example-animate-container">
    <li class="animate-repeat" ng-repeat="friend in friends track by friend.name">
      {{friend.name}}  is {{::friend.age}} years old.
    </li>
  </ul>
  <code>track by $index</code>, with age one-time binding:
  <ul class="example-animate-container">
    <li class="animate-repeat" ng-repeat="friend in friends track by $index">
      {{friend.name}} is {{::friend.age}} years old.
    </li>
  </ul>
</div>
.example - animate - container {
      background: white;
      border: 1 px solid black;
      list - style: none;
      margin: 0;
      padding: 0 10 px;
   }

   .animate - repeat {
      line - height: 30 px;
      list - style: none;
      box - sizing: border - box;
   }

   .animate - repeat.ng - move,
   .animate - repeat.ng - enter,
   .animate - repeat.ng - leave {
      transition: all linear 0.5 s;
   }

   .animate - repeat.ng - leave.ng - leave - active,
   .animate - repeat.ng - move,
   .animate - repeat.ng - enter {
      opacity: 0;
      max - height: 0;
   }

   .animate - repeat.ng - leave,
   .animate - repeat.ng - move.ng - move - active,
   .animate - repeat.ng - enter.ng - enter - active {
      opacity: 1;
      max - height: 30 px;
   }

The example below makes use of this feature:

<header ng-repeat-start="item in items">
  Header {{ item }}
</header>
<div class="body">
  Body {{ item }}
</div>
<footer ng-repeat-end>
  Footer {{ item }}
</footer>

And with an input of ['A','B'] for the items variable in the example above, the output will evaluate to:

<header>
   Header A
</header>
<div class="body">
   Body A
</div>
<footer>
   Footer A
</footer>
<header>
   Header B
</header>
<div class="body">
   Body B
</div>
<footer>
   Footer B
</footer>
load more v

Other "angularjs-rendering" queries related to "AngularJS really slow at rendering with about 2000 elements?"