Large App crashing in mobile safari.

I have a pretty large app with lots of data. It works well on desktop chrome,safari, firefox. It works well on android 4+ (android browser, chrome, and firefox) but on a growing number of iOS devices it crashes safari.

It appears to be a low memory issue. I have moved as much of the data as I could to pouchdb (which stores it in indexDB or whatever the device supports) and I got it to work on my son's itouch but I need to add more functionality to the app and I assume it will start to crash again.

Is it just impossible to have a large app on mobile safari?
If I use phonegap to make a "native" app will this issue go away?


  • Wrapping it in phonegap isn't going to solve any issues.

    We have a quite large of an app up and running. It did require some concessions, however our users have been happy with it.

    Here's some tips.

    1) Do not load any JSON data into variables that you aren't going to use. Meaning if you just need first/last name displayed on a control do not load address and phone number.

    2) Destroy components. This helps a lot. Initially we had a carousel of data panels and it would cause memory crashes. What we changed to was destroying and creating new panels with the proper data.

    That second one was actually the biggest help.

    If I can think of anything else I'll post a follow up.
  • Thanks, pmarsh. At least I know where I stand. I've already started doing things like you suggest, I guess I will continue tweak it to lower memory usage.
  • I think I'm at the end of the road for EnyoJS and this app. The app displays html pages in a of the pages is over 5 megs and it keeps crashing mobile safari. I can't tweek the web page size...
  • I think my only choice is some kind of native solution.
  • I hate Apple and iOS!!!
  • Why can't you tweak the web page size? What about the app is causing a 5MB page? Is is data? CSS? JS? Images?
  • edited September 2013
    I'm curious as well. All of our page except for the body tag is created by Enyo.

    Are you using massive images? I remember reading about loading images as background-images in div tags. Something about how safari loads img tags in memory.

    Also wrap the app in Phonegap and compile a native app using Xcode. This will allow you to profile the memory usage and get a better sense of when you're making progress and when you're not.
  • This particular page has 54 images ranging in size from 15K to 50K and the rest is just a lot of text. I could maybe trim them down a bit more but I have thousands of pages to deal with and many are in this range of size. The app is only going to get larger as I add the features that I need so I do not know what to do at this point.

    I'll look further into the "destroying of panels" and garbage collecting stuff that is not showing....
  • Might consider either destroying images that are out of view or at least replacing them with lower quality (and therefore smaller) versions that you can swap out when then scroll into view.

    If you have a lot of views like this, you'll probably have to either do panel destruction or at least aggressive clean up when the panel is hidden.
  • I found a lot of "Junk" in my app (unused images, sound files, JS scripts) and between removing the junk and scaling down my images I got my app under 1.5 megs.

    However, it still crashes safari on load and that is before I view the large html documents I mention above.

    Their must be something else going on but why does it only effect a small number of iOS uses and I see no errors or warnings in chrome inspector.

    I tried it on my friends ipad 1 with iOS 5 and it works like a charm but when I tried it on iPAD 3 with iOS 7 it crashes on load. But then I can try it on someone elses iPad 3 and it works fine???
  • I would really try wrapping it in phonegap and debugging and profiling through Xcode.

    You could then hook up your different devices and see what's happening.

    Generally the iPad 1 will crash the most as it has the least amount of RAM.

    File size has little to do with crashes, if safari is crashing out entirely most likely you're running out of RAM and iOS force closes it.
  • Not sure where destroy() is applicable. If I have a multi paneled app can I destroy the panels that are not showing to save memory and then create them when selected?

    Is that what is suggested above? Does this affect performance on transitions? Any examples or how this is done?
  • Yes, destroying unseen panels will help a lot with memory usage. Basically, since we mark the panels as 3D accelerated, WebKit is keeping around large image surfaces for each of them. On the retina screen, these can really add up.
  • To what degree does dropping the DOM subtree beneath the panel (e.g. by setting innerHTML to "") help? I would assume that an empty element wouldn't take much memory even if it's 3D accelerated.

    Here's an approach I'm playing with that follows that logic. I created a mixin that handles dropping and restoring the contents. I also extended Panels to automatically suspend/resume panels when the index changes (note this wouldn't work well with Arrangers that display multiple panels).

    It's pretty rough since I put it together this morning but perhaps it will help.
  • Actually, making panels that aren't seen unaccelerated might be a big benefit memory wise, then turning that acceleration on when they're "on-deck" to be animated. That's likely something we'll be investigating soon for 2.3.
  • Recently had a user tell me that our webapp works on his ios device when viewed in landscape mode but will crash safari when turned to portrait mode. Any idea why this might be?
  • @unwiredben - Any progress on unaccelerated hidden panels you mentioned above?
  • no, that didn't make the 2.3 dev cycle.
  • Awesome! I used the code from theryanjduffy 's jsfiddle example and I was able to get my "large" app to run on my son's itouch which used to crash on load!

    I have some issues with other panels interfering and using setIndex() instead of onTransition() but all fixable...

    @theryanjduffy - Any updates/refinements to that code you would be willing to share?

    @unwiredben - It would be great to have it as a build in feature in Enyo (suspending panel contents)
  • Unfortunately, no. I haven't used that code for anything beyond the example so it's been idle since. Glad it helped, though.
  • Using @theryanjduffy code above and works well for gesture invoked transitions but I'm having issues when using setIndex().

    1. If I try to setIndex() I get the following error:
    "Uncaught TypeError: Cannot read property '2' of undefined" in CollapsingArranger.js:98
    If I first use gesture transition to get to a panel the setIndex() method starts to work as if it is not created yet and undefined.

    2. Even if I gesture to each panel first to "build" them, setIndex works sometimes but somestimes I get this error:
    "Uncaught TypeError: Object # has no method 'querySelectorAll'" in List.js:444

    Not sure what is going on. Anyone have insight and a suggestion of what to try?
  • I'm not seeing that behavior in my example. Can you reproduce outside of your app?
  • It might have to do with having other panel kinds in the main panels. I sent you a link to my app.
  • edited February 2014
    I got it to work. I added a specific arranger kind ("LeftRightArranger") as opposed to default and it seems to be working. Don't know why that would help?

    Update: Although the setIndex() method is working I still see the first error (Uncaught TypeError: Cannot read property '2' of undefined") showing in the inspector.

    Also after a few seconds my "home" page contents disappears. I assume it has to do with the suspension delay.

    Update2: I fixed the problems by placing the suspendable panels within a FittableRowsLayout. All seems good...Thanks!
  • Glad you got it working!
Sign In or Register to comment.