Collection-repeat and view cache weirdness

I encountered a pretty weird bug using collection-repeat and the view cache. I am using v1.0.0-beta.14. This is what it looks like:

  • I have a bunch of different views. One of them is a collection-repeat with a couple thousand items, the other is a view that has a button that opens up a modal
  • If I start the app, and directly open the view to popup the modal, it pops up fast and clean.
  • If I start the app, open up the collection-repeat view, it pops up fast, but if I then navigate to the other view and popup the modal, it takes a couple of seconds to open up (This is true both on my iPhone and the Simulator)
  • When I debugged it, it seems like the opening up the modal is trying to render every item of the collection-repeat in the collection-repeat in the other, now cached, collection! Each item has a different picture, and I can see it trying to fetch thousands of images, which is chocking the performance.

After spending a bit of time in the debugger, it seems like the modal is emitting a ā€˜resize’ event, which is somehow being processed by the collection-repeater in the cached view, and causes the rerender of every item. When I mark the view with the collection-repeat to not be cached, the issue disappears.

Anybody else seeing issues with cached views, modals and large collection-repeats?

Mik

2 Likes

YES! Thank you for sharing this, I’m having the same issue and this helped me track it down. When running on my iPad I noticed that when I opened a modal in the second view, memory usage would jump up by 30Mb. Now I know this is because it was rerendering all the items (not just the visible ones) in the collection-repeat in the cached view. And when I switched back to the cached view, my app would crash every time. Commenting out the:

ionic.trigger('resize'); 

on line 2955 of ionic-angular.js seems to fix the problem.

I also traced through and it looks like the collectionRepeatManager receives the resize event and calls

collectionRepeatManager.resize()

on line 7748 of ionic-angular.js, which then calls

this.render(true) 

on line 979 and then

  i = renderStartIndex;
  while ((rect = this.dimensions[i]) && (rect.primaryPos - rect.primarySize < scrollSizeEnd)) {
    doRender(i, rect);
    i++;
  }

on lines 1099-1103, which is what does the actual rendering (and in this case, damage). It looks as if this is only supposed to render the visible items, but in this case it’s rendering EVERYTHING.

I suspect that there’s something else about the unintended rerendering that’s causing my initial cached view to crash when I navigate back to it, since navigating to other views after opening the modal doesn’t cause any problems.

I’ll try to put together a codepen and log an issue on github.

Great to hear I am not the only one, and awesome debugging job! Strange not more people have bumped into this!

Ƥhm i can remember that somewhere the documentation says you should not cache long lists or pages with many media files (images, videos, and so on). Because of memory consumption.

So do not cache those views.
If you want to speedup those pages -> cache the http-requests which gets data for the lists, store the loaded data in a service (if you use something like lazy loading) and remember scrollposition.

The template is automatically cached in angulars templateCache.

So the only thing is to rebuild the scope ;).

Greetz.

Yeah: that is the interesting thing about this problem, we are not actually caching anything. Ionic is, mistakenly, resizing and re-rendering views that are not currently visible but are cached. If those views re-render, they will pull in any data they need, and because it seems to re-render without a visible size, it is pulling data and resources for every possible row of the collection-repeat.

I am pretty sure it is a problem with the collection-repeat component…

Maybe the crappy view-transition to a collection-repeat view is so crappy.

If i go from a ordinary view to a collection-repeat view the previous view gets black during transition.

greetz.

1 Like

How would you do to remember scroll position on those states without cache? Just spent 2 hours to come up with a clean solution and I’m stuck… Thanks

Scroll position was a feature present in ionic beta 13, but removed since according to Ionic Team, cached views would make the job. However, it would be good to let this feature for non-cached views.

Thanks @Mik378 I’d love to have a workaround from the ionic team (or yourself :slight_smile: ?) @adam to the rescue?

Do you have a mini-codepen showing the issue?
I typically have a Tab A with view A exposing a collection-repeat of 66 data.
When I click on an item, it opens the ā€œshowā€ page, exposing a button, opening a modal.

I don’t see some lags when opening the modal…
Do you really think it’s about the sole difference between 66 items and 2000 ?

I can make a codepen for this if you’d like. On my list (which contains a lot of images) I can literally see the elements stacking above each other when opening the modal. On mobile devices, this results in HUGE performance issues, where there is no animation on modal opening/closing.

I would be interested in seeing your code :wink:

Have logged an issue here: https://github.com/driftyco/ionic/issues/2879
Here’s Codepen that shows the problem: http://codepen.io/rajatrocks/pen/myOYLw

Nice! Thanks for making the pen and the issue!

What if you put the ā€œopen modalā€ button in the header. (right button for instance)
I have a very similar scenario, and no item of my collection-repeat is loaded after switching the list page.

I can reproduce your issue with the codepen.

In my app, when I open a modal from the same tab as the collection-repeat, nothing bad happens. It’s only when I switch to a new tab and then open a modal that it occurs.

1 Like

It seems to have several distinct bugs regarding collection-repeat + modal…

A simple fix (workaround) for you would be to remove the ā€œopen modalā€ button from the FIRST ā€œAboutā€ tab view, but rather redirect to a next state (through a link/button, whatever) that would have this button.
It would change your UX … but can fit.

My UI is pretty fixed. The simpler fix is just to comment out the call to ionic.trigger(ā€˜resize’) for now, since it doesn’t seem to do anything useful anyway. Showing a modal shouldn’t force the view to resize.

Completely agree, this is surely linked to my issue : https://github.com/driftyco/ionic/issues/2865
I will test your fix now :wink: