Titanium JIRA Archive
Appcelerator Community (AC)

[AC-2699] iOS: Screens with lots of views freeze the application when navigating - On device only

GitHub Issuen/a
TypeBug
Priorityn/a
StatusClosed
ResolutionNot Our Bug
Resolution Date2013-12-12T21:18:06.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsTitanium SDK & CLI
Labelsios, performance, rendering, views
ReporterSameeh Harfoush
AssigneeEric Wieber
Created2013-11-30T14:47:50.000+0000
Updated2016-03-08T07:41:48.000+0000

Description

i have an add with screens having news feeds i.e. lots of views and pics. the app works great on an average android device (Xperia) but when i run it on ipod touch the rendering takes forever causing the application to hang between NavigationWindow screens (forward and backward). below is a code that simulate the problem. notice that even after the views are loaded the app is not responding for a while; you cant scroll until waiting for like 15 seconds. on my app i have to wait for more than 30 seconds for the app to become responsive again... Note that on the iOS simulator it works great and super fast Test case:
Ti.UI.setBackgroundColor('white');

var win = Ti.UI.createWindow({
    backgroundColor : 'white',
    exitOnClose : true,
    fullscreen : false
});

var rootWindow = Titanium.UI.iOS.createNavigationWindow({
    window : win
});

var viewsCont = Ti.UI.createView({
    width : Ti.UI.FILL,
    height : Ti.UI.SIZE,
    layout : 'vertical'
});
for (var i = 1, j = 600; i < j; i++) {
    var cView = Ti.UI.createView({
        width : Ti.UI.FILL,
        height : 20,
        backgroundColor : (i % 2 == 0) ? 'red' : 'green'
    });
    viewsCont.add(cView);
};

var openWebViewBtn = Ti.UI.createButton({
    title : 'open another',
});
openWebViewBtn.addEventListener('click', function(e) {
    var newWin = Ti.UI.createWindow({
        backgroundColor : 'white',
        exitOnClose : true,
        fullscreen : false
    });

    var viewsCont2 = Ti.UI.createView({
        width : Ti.UI.FILL,
        height : Ti.UI.SIZE,
        layout : 'vertical',
        horizontalWrap : true
    });
    for (var i = 1, j = 600; i < j; i++) {
        var cView = Ti.UI.createView({
            width : Ti.UI.FILL,
            height : 20,
            backgroundColor : (i % 2 == 0) ? 'red' : 'green'
        });
        viewsCont2.add(cView);
    };
    var scrollView2 = Ti.UI.createScrollView({
        width : Ti.UI.FILL,
        height : Ti.UI.FILL,
        scrollType : 'vertical',
    });
    scrollView2.add(viewsCont2);
    newWin.add(scrollView2);

    var centerLabel = Ti.UI.createLabel({
        text : 'A simple label'
    });
    newWin.add(centerLabel);
    
    rootWindow.openWindow(newWin, {
        animated : true
    });
});

var scrollView = Ti.UI.createScrollView({
    width : Ti.UI.FILL,
    height : Ti.UI.FILL,
    scrollType : 'vertical',
});
scrollView.add(viewsCont);
win.add(scrollView);
win.add(openWebViewBtn);

rootWindow.open();

Comments

  1. Sameeh Harfoush 2013-12-09

    Hello Eric, were you able to replicate the scenario above ? Regards
  2. Eric Wieber 2013-12-09

    Hello Sameeh, I was able to reproduce the behavior you are seeing. On older devices, it takes some time to create so many views and that is what the delay at the beginning of the app or when you change the NavigationWindow. The reason you do not see this issue on the simulator is that the simulator has your computers resources behind it (much faster and more powerful than a phone). This does not appear to be a bug, but rather a limitation of older/slower devices. You should be able to get around this issue by modifying your app's code or design. A solution would be to optimize your app. You could look into implementing an activityIndicator or only creating the views on the fly, as needed.
  3. Sameeh Harfoush 2013-12-10

    thanks Eric, is this the same for iPad3? when i run the app on Android device (Sony Xperia P, Dual-core 1 GHz) it runs great but when i run it on iPad3 (also Dual-core 1 GHz) running iOS7 i face the same problem. another thing is when going backwards with the NavigationWindow it also freezes for a while till the app becomes responsive again.
  4. Eric Wieber 2013-12-10

    Sameeh, The freeze at load could occur with many devices. Loading so many views is expensive. The device could also be under more load if it is running a lot of services or other apps in the background. I'll do another test here and run the app on an iPad 3 to see if anything stands out. I'll report back if I see anything out of place.
  5. Sameeh Harfoush 2013-12-11

    ok thank you
  6. Eric Wieber 2013-12-11

    Sameeh, After testing on the iPad 3, I still see the freeze at load, although it is a shorter freeze. I still believe this to be due to the load that creating so many views has on the device. Please feel free comment here if you still see this issue after optimizing your app or implementing a way to reduce the number of views being loaded at once. Please let me know if we can help in any other way. Thanks!
  7. Sameeh Harfoush 2013-12-12

    i shouldn't have taken it for granted that if the app is fast on android which means it will be the same on iOS. i thought the inverse in true. Anyway will try to figure something out.
  8. Eric Wieber 2013-12-12

    Please re-open or comment here if this issue persists after modifying your code. Thank you.
  9. Sameeh Harfoush 2013-12-17

    i also noticed that after the my screen is loaded, opening a simple modal dialog with textarea and a button lakes long time to load as well. after profiling my application with Xcode it shows that rendering views are taking over 150% of the cpu and lots of other resources... is there a way to send you the .trace files?
  10. Sameeh Harfoush 2013-12-17

    ok in the first screen i replaced the view (layout vertical) with tableView and tableViewRow. the result is dramatic change in speed. the fist screen loads fast and is becomes responsive within a second. but when opening the second screen using view (layout vertical) the freeze problem remains. therefore, i think there is a problem with the "Ti.UI.View" component on iOS. please see test-case below
        Ti.UI.setBackgroundColor('white');
        
        var win = Ti.UI.createWindow({
            backgroundColor : 'white',
            exitOnClose : true,
            fullscreen : false
        });
        
        var rootWindow = Titanium.UI.iOS.createNavigationWindow({
            window : win
        });
        
        var viewsCont = Ti.UI.createTableView({
            width : Ti.UI.FILL,
            height : Ti.UI.SIZE,
            layout : 'vertical'
        });
        var rows = [];
        for (var i = 1, j = 600; i < j; i++) {
            var cView = Ti.UI.createView({
                width : Ti.UI.FILL,
                height : 20,
                backgroundColor : (i % 2 == 0) ? 'red' : 'green'
            });
            var row = Ti.UI.createTableViewRow({
                width : Ti.UI.FILL,
                height : Ti.UI.SIZE,
                className:'colorView'
            });
            row.add(cView);
            rows.push(row);    
        };
        
        viewsCont.setData(rows);
        
        var openWebViewBtn = Ti.UI.createButton({
            title : 'open another',
        });
        openWebViewBtn.addEventListener('click', function(e) {
            var newWin = Ti.UI.createWindow({
                backgroundColor : 'white',
                exitOnClose : true,
                fullscreen : false
            });
        
            var viewsCont2 = Ti.UI.createView({
                width : Ti.UI.FILL,
                height : Ti.UI.SIZE,
                layout : 'vertical',
                horizontalWrap : true
            });
            for (var i = 1, j = 600; i < j; i++) {
                var cView = Ti.UI.createView({
                    width : Ti.UI.FILL,
                    height : 20,
                    backgroundColor : (i % 2 == 0) ? 'red' : 'green'
                });
                viewsCont2.add(cView);
            };
            var scrollView2 = Ti.UI.createScrollView({
                width : Ti.UI.FILL,
                height : Ti.UI.FILL,
                scrollType : 'vertical',
            });
            scrollView2.add(viewsCont2);
            newWin.add(scrollView2);
        
            var centerLabel = Ti.UI.createLabel({
                text : 'A simple label'
            });
            newWin.add(centerLabel);
        
            rootWindow.openWindow(newWin, {
                animated : true
            });
        });
        
        var scrollView = Ti.UI.createScrollView({
            width : Ti.UI.FILL,
            height : Ti.UI.FILL,
            scrollType : 'vertical',
        });
        scrollView.add(viewsCont);
        win.add(scrollView);
        win.add(openWebViewBtn);
        
        rootWindow.open(); 
        
  11. Sameeh Harfoush 2013-12-19

    hello Eric, did you get the chance to check the test-case updated code? Regards
  12. Eric Wieber 2013-12-19

    Hi Sameeh, Yes I did test it out and saw the same results that you did. I am currently discussing the code and results with the engineering team to determine what our next steps are. I will update again shortly. Thank you very much for this updated code and test cases. It clearly demonstrates the issue you are seeing.
  13. Sameeh Harfoush 2013-12-19

    great, appreciate the followup :)
  14. Eric Wieber 2013-12-19

    Sameeh, After talking it over with one of our engineers, I have a few suggestions for you. 1. Never use a scrollview inside a table view. We have seen errors before with that type of setup and we always recommend avoiding it if possible. 2. Below I have modified your code to not have a scrollView inside a tableView and removed an unnecessary view from the second window. 3. The main reason you are seeing a difference in the speed of the two display methods is that the scrollView loads each view inside it (600 in your case). The tableView only loads what it needs to display and will reuse older resources upon scrolling. It is much more efficient. and an F.Y.I: 4. We also have a listView, that is basically a new version of the tableView that is even faster. You could consider using this to see the best performance of your 600 views.
        Ti.UI.setBackgroundColor('white');
         
        var win = Ti.UI.createWindow({
            backgroundColor : 'white',
            exitOnClose : true,
            fullscreen : false
        });
         
        var rootWindow = Titanium.UI.iOS.createNavigationWindow({
            window : win
        });
        
        var viewsCont = Ti.UI.createTableView({
            width : Ti.UI.FILL,
            height : Ti.UI.SIZE,
            layout : 'vertical'
        });
        var rows = [];
        for (var i = 1, j = 600; i < j; i++) {
            var cView = Ti.UI.createView({
                width : Ti.UI.FILL,
                height : 20,
                backgroundColor : (i % 2 == 0) ? 'red' : 'green'
            });
            var row = Ti.UI.createTableViewRow({
                width : Ti.UI.FILL,
                height : Ti.UI.SIZE,
                className:'colorView'
            });
            row.add(cView);
            rows.push(row);    
        };
         
        viewsCont.setData(rows);
        
        var openWebViewBtn = Ti.UI.createButton({
            title : 'open another',
        });
        
        openWebViewBtn.addEventListener('click', function(e) {
            var newWin = Ti.UI.createWindow({
                backgroundColor : 'white',
                exitOnClose : true,
                fullscreen : false
            });
            
            var scrollView2 = Ti.UI.createScrollView({
                width : Ti.UI.FILL,
                height : Ti.UI.FILL,
                scrollType : 'vertical',
                layout	: "vertical"
            });
            for (var i = 1, j = 600; i < j; i++) {
                var cView = Ti.UI.createView({
                    width : Ti.UI.FILL,
                    height : 20,
                    backgroundColor : (i % 2 == 0) ? 'red' : 'green'
                });
                scrollView2.add(cView);
            };
            newWin.add(scrollView2);
         
            var centerLabel = Ti.UI.createLabel({
                text : 'A simple label'
            });
            newWin.add(centerLabel);
         
            rootWindow.openWindow(newWin, {
                animated : true
            });
        });
         
        win.add(viewsCont);
        win.add(openWebViewBtn);
         
        rootWindow.open();
        
    Let me know if you have any other questions or concerns.
  15. Sameeh Harfoush 2013-12-20

    Eric, i checked my code again but i didn't see where i am using scrollView inside a tableView; in the first screen i ma adding a colored "View" (red/green) in a "ViewRow" array and then i am adding this array to the "TableView". for my case, i tried replacing the ScrollView with a tableview but the scrolling hangs/freezes while scrolling. my app displays news feed in a ScrollView (something like facebook feed) where feeds render according to their type. therefore, in the same scrollview i can have a feed with a picture, text, or a combination of both with some other UI custom components like voting. i still didn't try ListView because i need to go through lots of changes to make the UI items data structure fit the ListView ListItem required structure. not feasible at this point... is it a iOS native UI limitation that is causing this? because the test-case above works well on android.

JSON Source