Exlord
Exlord

Reputation: 5381

Angularjs performance in creating dom elements, pure js vs jqlite

I have a directive in Angularjs that will have a table with lots of rows(over 1000), so my boss said that i shouldn't use binding to make the grids content(because of angular's ~2000 limit in binding) and instead i should create the dom elements on the fly.

And i did that with angular.element(...), and it works. BUT now i am thinking if there could be a performance boost if i use the native js document.createElement?

So is jqlite slower than pure js? how much impact would it make when making over 1000 rows of html?

is jquery faster?slower or equal to jqlite?

UPDATE :

@Joe Enzminger +1 for one time binding it would be good for report/print view witch is just for view. BUT the grid has inline editing so it needs the two-way bindings. it has 19 columns each with a input and 2 buttons and a save button at the last column. each button has ng-show and the save button has ng-class to change its icon based on the rows status. so (19*3)+1 two way bindings.

this grid is a data entry form of some kine :D and all rows should be visible and cannot have pagination.

UPDATE2:

I forgot to mention that right now i have a empty tbody element in my template and all its content is generated as a simple dom and injected into it with absolutely no data bindings of any kind. all the interactions are handled with good all fashion JS manually :D.

Upvotes: 3

Views: 1036

Answers (2)

user2943490
user2943490

Reputation: 6940

There are two things to consider here: DOM rendering performance, and angular $watch($digest) performance. In both cases trying to optimise document.createElement vs angular.element isn't worth it.

For DOM rendering the bottleneck is not JavaScript execution speed, but browser repaints (see: html5rocks) and reflows (see: Google developers). Whether you use document.createElement or angular.element is insignificant because the performance hit and UI blocking come when you add to or modify elements on the page, not when creating DOM elements in memory. This is why most modern UI frameworks batch DOM updates rather than making lots of tiny updates (e.g. ReactJS, Meteor, EmberJS).

For $watch and $digest performance, the performance hit comes from the number and complexity of binding expressions (e.g. {{things}}, ng-bind, ng-show, ng-class, etc) that Angular has to evaluate in each $digest cycle. If you keep in mind that in most cases, a simple action like a click will trigger a $digest cycle, thousands of bindings could be evaluated on each click. Using one-time bindings to minimise the number of $watches and keeping watches as simple as possible is recommended.

In the default ng-repeat directive (presumably what you are using to create a grid) you don't really have fine control over these two considerations aside from preferring one-time over two-way bindings as much as possible or butchering your data model. This is why performance sensitive developers bypass ng-repeat completely and create their own directives. If performance is key to you, you should look into doing something similar.

Upvotes: 2

Joe Enzminger
Joe Enzminger

Reputation: 11190

I'm sure one of them is "faster". However, probably only marginally so - I don't think there is much to gain performance wise using one vs. the other.

However, from a maintainability standpoint, I'd suggest using Angular's one time binding feature. The mythical "~2000 binding limit" really applies to $watches, not bindings, and is not really a limit as much as a guideline. Using {{::var}} inside of an ng-repeat is going to yield much more maintainable code, with comparable performance, than building custom DOM on the fly, and it will not create $watches that could affect performance.

Upvotes: 3

Related Questions