Reputation: 5381
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
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
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