Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ngrepeat performance is terrible in IE8 #1534

Closed
007design opened this issue Nov 6, 2012 · 31 comments
Closed

ngrepeat performance is terrible in IE8 #1534

007design opened this issue Nov 6, 2012 · 31 comments

Comments

@007design
Copy link

I've written an application that allows you to create a calendar by selecting a set of 12 images from a library. It works wonderfully in Chrome but the performance in Internet Explorer (8 in particular) is just terrible. I think the the issue is using the ng-repeat directive for the gallery of images slows the application way down especially because it's also filtering the images.
However, my angular-fu is not top notch so I would be grateful if someone else could have a look at the code and see if they can find a reason that the app might be running so poorly in Internet Explorer.
I tried to create a plunk but I couldn't seem to get plunkr to work in IE8 (altho it works just fine in chome). Here is the plunk: http://plnkr.co/edit/R1FUR1

Since I couldn't get plunkr to work in IE (does the whole site not work with IE8 or is it just me?) I put the files on github as well.
https://github.com/007design/AngularCalendarBuilder

Thanks very much,
007

@jtymes
Copy link
Contributor

jtymes commented Nov 7, 2012

The first thing that I see that you could try is to take your for-in loops and replace with regular for loops in your filter.

Next thing is that your directive is creating a previewContainer for each image and setting the id to be the same. That's a lot of DOM manipulation. You're also creating the elements with jQuery, which creates overhead. So instead, you can have the element in your template.html, give it some inline css properties and have it hidden by default. Then show it as needed.

http://plnkr.co/edit/hzcaTD

I did not test the performance in IE8, and I didn't see any noticeable difference in Chrome, but you could try these out and see what happens?

@bingomanatee
Copy link

Past a point its an application design issue. If you have significant data - and siginficant can be in orders of 1-200 rows -- and a lot of ng-repeat filtering, I have found it seriously degrades the response as it continually recalculates the data down to the desired subset without any real benefit, each redraw.

I found that extracting the code that calculates the iteration result out of angular - in fact even pulling some of in into web workers -- solves that problem for the most part. If you only recalculate your dataset when the inputs change, and not on every redraw, you can regain a lot of performance.

@fingermark
Copy link

I'm new to angular and my need for ng-repeat would be for generating about 500 rows. I heard that ng-repeat is designed to accommodate animations in the future. This may be why it's slow, as it needs to do a deep comparison instead of a referential comparison and maintains a 1-1 mapping between array members and dom elements. It'd be nice if there was an alternative implementation for those who don't need animations and just want speed.

Let me know if this should be its own issue.

@bingomanatee
Copy link

ng-repeat - in and of it self - over 500 rows of data that is not sorted, ordered, filtered, etc., is probably fine; its when each graphic refresh requires you to do major operations redundantly that Angular dogs down.

Just because you CAN do these operations in Angular doesn't mean you HAVE to do them there, all the time. Its not a failure of the platform to move some of these operations out of the template.

You wouldn't expect a dom based filtering to, say, handle the New York City white pages. Past a certain point some of this has to be backed up to other systems, servers, etc.

@djsmith42
Copy link

I'm having the same kind of performance problem on IE8 with ng-repeat. I have a table with 50 rows and 6 columns. Each row has about a dozen ng-show directives and a few other {{expressions}}. It takes 30-60 seconds to load this table initially. On Chrome it takes less than 1 second. Something about IE8 is causing major performance degradation. It's fine on IE9. When I remove all the ng-show and {{expressions}}, the table loads fast again, but of course, this isn't very useful because it has no data to display to the user. The ng-show expressions and other {{expression}}'s are trivial, and non-expensive to compute.

Any advice would be much appreciated. I'm using Angular 1.0.3. I tried upgrading to Angular 1.0.4, but it caused errors in IE8 (Unexpected call to method or property access).

@jtymes
Copy link
Contributor

jtymes commented Jan 25, 2013

@djsmith42 could you put together a plunk to demonstrate this and see if there's something else we can dig into to help you achieve the performance you desire?

Thanks!

@djsmith42
Copy link

@jtymes I'm putting together a stand-alone demo now. Hopefully it will expose the problem nicely.

@djsmith42
Copy link

@jtymes I'm quite embarrassed to say this, but it appears that I cannot reproduce the IE8 slowness in a stand-alone example that I am seeing in my app. All the examples I am able to conjure are running lightning fast on IE8.

It is a little concerning that IE8 is so dreadfully slow for my app, while other browsers are fast. My app must be doing something that IE8 doesn't like.

Stay tuned for the exciting conclusion to this false alarm as I unravel the source of the slowness in my app.

@jtymes
Copy link
Contributor

jtymes commented Jan 28, 2013

@djsmith42 That's good though, because it narrows down your problem a bit! 👍

@djsmith42
Copy link

@jtymes Here's my report. There is nothing inherently slow about ng-repeat on IE8. Absolutely nothing.

However, and this is a big caveat, you must be very careful about what you do in custom directives that are used within an ng-repeat. For example, if a directive's link function uses $timeout, you are going to trigger N digests where N is the number of items in the ng-repeat. Likewise if your directives use scope.$watch(), especially if they use the function form of scope.$watch(), you are in for a world of pain on IE8.

Another hack we used to make IE8 faster was to use AngularUI's ui-if directive to defer the loading of columns in the table that contain expensive directives. This way, the table rows all appear quickly, but the columns trickle in on an interval of about 300ms per column. It ain't great, but it works, and it's pretty decent for the user (better than hard-locking their browser for 60 seconds anyway).

We patched Angular to notify us on the console every time it runs a $digest and how long each $digest took. This was very useful information while diagnosing the $digest storm we caused for ourselves. I'd love to see some kind of performance reporting from Angular's core in the future.

Oddly, other browsers (even IE9) were nice and performant even before our optimizations. It was just IE8 that really failed to weather the $digest storm.

Now that we've completed our optimizations, IE8 is still pretty sluggish, but usable. And other browsers are lightning fast.

@guillaume86
Copy link

@djsmmith42 I'm interested in your IE8 optimisations, a thread with your findings in the google group would really be nice ;).

I'm building a pretty big web application (mostly CRUD) with lots of gridviews (with server pagination) and IE8 is already having a hard time (I didn't even imlemented custom cell templates), not unusable but already 4-5 secs to switch cockpit is not very comfortable.

@orneryd
Copy link

orneryd commented Feb 22, 2013

ng-repeat perf is terrible anyways. even in chrome and firefox and > IE 8 when you have a list that changes constantly it just hogs the CPU cycles.

@fingermark
Copy link

I'd be interested in seeing someone post something measurable so that this could get more attention.

@AlexGalays
Copy link

Adding an item to the last position should be quite fast, adding one near the top of the list is slow because the algorithm remove/add every subsequent nodes (they use a linked list If I remember well); The algorithm used by knockout or d3 is way smarter. Additionally, digesting hundreds of items is slow (Or observing a whole scope for every changes, don't remember which approach it uses); that will remain a limitation of Angular for a few more years.

That said, even if the Angular team optimizes their ng-repeat, it will still be dog slow in IE8; This browser is crippled and will never run well with many DOM node manipulations as done by Angular (or knockout or equivalent for that matter). Recent browsers are about equally as fast whether you use innerHTML or do many DOM changes though.

If you really need to support a big IE8 user base, using Angular is probably not a good idea.

@djsmith42
Copy link

"If you really need to support a big IE8 user base, using Angular is probably not a good idea."

I don't think the size of your user base has anything to do with it. It's the size of your data on screen at any given time. We've managed to work around IE8's limitations and our app is fully functional in IE8. Only in one small area of the app did we have to do anything special to work around IE8's slowness.

@sinelaw
Copy link
Contributor

sinelaw commented May 10, 2013

Just to check - is there any update on performance of ng-repeat? I too am stuck with IE8 and it's extremely slow.

@AlexGalays
Copy link

Heavy DOM manipulation (adding/removing nodes one by one as done in ng-repeat) is inherently slow in IE8. Your best bet is probably to code a directive that will end up concatenating a string and assign it to the innerHTML of the target container. This used to be the only way to go with crappy old browsers.

@btford btford closed this as completed Aug 24, 2013
@btford
Copy link
Contributor

btford commented Aug 24, 2013

As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months.

Please try the newest versions of Angular (1.0.8 and 1.2.0-rc.1), and if the issue persists, comment below so we can discuss it.

Thanks!

@allenwyma
Copy link

Yeah, i"m having an issue with ng-repeat and rendering. I have 2 ng-repeat "sections. I have rows of users in one section, and rows of shift names in the other section. Inside each of these rows (both users and shifts) is an ng-repeat that is repeating over a range of values (from 0-6 as integers) that I use to calculate each day of the week.

Any idea on how to make this better?

@petebacondarwin
Copy link
Contributor

@HangingClowns - What version of angular are you using? Performance of ng-repeat was significantly improved in 1.1.x

@allenwyma
Copy link

@petebacondarwin I'm using a recent snapshot at v1.2.0-d63a50c. When I try to recalculate some fields, it takes over 4 seconds for it to display. When i have about 4 or more rows in one section.

@petebacondarwin
Copy link
Contributor

Can you provide a running example. There are lots of factors, including
what you are databinding,

On 24 September 2013 10:44, Allen Wyma notifications@github.com wrote:

@petebacondarwin https://github.com/petebacondarwin I'm using a recent
snapshot at v1.2.0-d63a50c. When I try to recalculate some fields, it takes
over 4 seconds for it to display. When i have about 4 or more rows in one
section.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1534#issuecomment-24989575
.

@allenwyma
Copy link

@petebacondarwin for me to reconstruct a smaller example may take some time, so I've just decided to gist my current code, but with some stuff taken out like filters and other irrelevant stuff. With about 4 user rows and 10 of the shift template rows, it seriously takes between 4-5 seconds to update all of the scopes. It seems maybe I have too many scopes or something. It takes almost 3 seconds just to do all of the angular checking:

screen shot 2013-09-26 at 8 19 25 am

If you really want to see a working example that's up and running, I can throw up my application for you, but maybe I wrote my code in a bad way for Angular or something that it's sooo slow, but I'm not sure if that's it:

https://gist.github.com/HangingClowns/67e33ddb9ed8a8beaf22

@petebacondarwin
Copy link
Contributor

From a quick glance, it seems that you are databinding to lots of function calls and filters. For example in this block:

<li>
  <span data-i18n="schedule.monday">
    {{'schedule.monday'|i18n}}
  </span> - 
  <span class="dateHeader">
    {{getCalendarDate(currentDate, 0)}}
  </span>
</li>

which is calling the function getCalendarDate() at least twice for each binding on every digest.

And more importantly this i18n filter, which you have not provided in your gist. As a general rule you should not be using filters to do internationalisation. It will indeed kill your performance.

Try to remove as many of the complex filters that you can.

@allenwyma
Copy link

I moved my filters in with bindonce (so as not to have such a big delay) and removed the function, also, and just set normal variables

<ul>
  <li><span data-i18n="schedule.monday" bindonce bo-text="'schedule.monday'|i18n"></span> - 
<span class="dateHeader">{{day0}}</span></li>
</ul>

This still takes at least 3 seconds to change dates. I'm not sure how to speed it up or if it's even on my side.

Edit: I went ahead and updated my above gist, including ALL of my filters, so I wouldn't miss one, and tried to include some of the updated changes I added.

Here's an updated profile of my app:
screen shot 2013-09-29 at 2 35 41 pm

I'm not quite sure where the problem can be, but it's probably related to the multiple amount of ngRepeat's I have in my page.

@allenwyma
Copy link

Can I have a reply back?

@allaud
Copy link

allaud commented Oct 23, 2013

@btford @HangingClowns @petebacondarwin
There are some pitfalls in default ng-repeat logic. It uses deep watch and waits for digest, which is sometimes undesirable. So you definitely should check out my project quick-ng-repeat. It gives amazing boost to your lists rendering performace (check the examples - index.html uses quick-ng-repeat and index_classic.html uses ng-repeat, just try to scroll the page).

Other performance information is in Readme.

There is also a dfa-stable-repeat project, but as I know it is still proprietary and doesn't allow you to render your list asynchronously.

@jerrykur
Copy link

jerrykur commented May 3, 2014

@HangingClowns Did you ever come up with a solution to this issue? I am struggling with this an have a userbase of 40,000 users that are tied to IE8 for the foreseeable future

I am experience performance issues with loading a select tag with 500 option rows or so. The options loop takes about 8 seconds to execute. On IE10, 11, Chrome, FF it is very quick < 200 ms.

@drtobal
Copy link

drtobal commented May 3, 2014

IE8 is terrible, should be illegal

@jerrykur
Copy link

jerrykur commented May 4, 2014

I definitely wish I did not have to worry about IE, but the client has thousands of systems with IE8 and a migration to later version is not yet planned. So we have to deal with the reality, not would we would like,

@orneryd
Copy link

orneryd commented May 4, 2014

No, companies who make web products need to force people and clients to
upgrade. If you have a product they want to use, they'll figure out a way
to get off IE8 if you don't support it. Development costs are way too high
to support 10 year old technology with security vulnerabilities. It really
is that simple. 'Not secure, we don't support it' your customers will
appreciate you taking security seriously (especially post-heartbleed) and
will give them the impetus to upgrade. Stand up to your customers for
once. That is unless you make a crap product you think your customers would
rather switch off of than be secure.

On Sunday, May 4, 2014, jerrykur notifications@github.com wrote:

I definitely wish I did not have to worry about IE, but the client has
thousands of systems with IE8 and a migration to later version is not yet
planned. So we have to deal with the reality, not would we would like,


Reply to this email directly or view it on GitHubhttps://github.com//issues/1534#issuecomment-42135406
.

-Tim Sweet

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests