Search code examples
iphoneiosgwtiscroll4iscroll

iScroll 4 performance on iOS


I was impressed by the smoothness of the iScroll on iOS so i tried to implement it in my iPhone application.

The iScroll Demo works real fine on my iPhone. But only when the scrollable content is as simple as short text in <li> elements:

<ul id="thelist">
    <li>Pretty row 1</li>
    <li>Pretty row 2</li>
    <li>Pretty row 3</li>
        etc..
</ul>

When i tried to put a slightly more complex contents :

<ul>
    <li class="GOE-WOTBDO GOE-WOTBIO GOE-WOTBEO " __idx="0">
        <div class="cssDivStyle">
                <img width="120px" height="74px" src="http://some_jpg_image.jpg">
        </div> 
        <div> 
            <p>Some long text ....</p>
        </div>
    </li>

The smoothness is completely gone, and the list hardly scrolls ..

Is there a way to make my contents lighter ?

Any suggestions whatsoever ? Thank you very much !

Here's how i declare my iScroll element:

myScroll = new $wnd.iScroll(
            elem,
            {
                useTransition : true,
                topOffset : pullDownOffset,
                hScroll : false,
                onRefresh : function() {
                    if (pullDownEl.className.match('loading')) {
                        pullDownEl.className = 'pullDown';
                        pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
                    }
                },
                onScrollMove : function() {
                    if (this.y > 5 && !pullDownEl.className.match('flip')) {
                        pullDownEl.className = 'flip pullDown';
                        pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...';
                        this.minScrollY = 0;
                    }

                },
                onScrollEnd : function(response) {
                    if (pullDownEl.className.match('flip')) {
                        pullDownEl.className = 'loading pullDown';
                        pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';
                        [email protected]::callbackSuccess(Lcom/google/gwt/user/client/rpc/AsyncCallback;Lcom/google/gwt/core/client/JavaScriptObject;)(pullDownCallback,response);
                    }
                }
            });

[EDIT]

only by removing divs from:

<ul>
    <li class="GOE-WOTBDO GOE-WOTBIO GOE-WOTBEO " __idx="0">
        <div class="cssDivStyle">
            <img width="120px" height="74px" src="http://some_jpg_image.jpg">
        </div> 
        <div> 
            <p>Some long text ....</p>
        </div>
</li>

and making it to:

<ul>
    <li class="GOE-WOTBDO GOE-WOTBIO GOE-WOTBEO " __idx="0">
        <img class="cssDivStyle" width="120px" height="74px" src="http://some_jpg_image.jpg">
        <p>Some long text ....</p>
    </li>

Made the scrolling much, much faster !! I have no idea why!


Solution

  • The code below will render your page the way webkit expects it. So redrawing will be massively quicker.

    The HTML

    <body>
        <div class="headerFix">
            <div class="header">
                <!-- The content in header...logo/menu/e.t.c -->
            </div>
        </div>
        <div class="content"><!-- you dont need this extra div but it keeps structure neat -->
            <ul>
                <li>List content here which can be as complex as needed</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
                <li>Item</li>
            </ul>
        </div>
        <div class="footerFix">
            <div class="footer">
                <!-- The content in footer -->
            </div>
        </div>
    ...
    

    The css

    .headerFix, .header {
        height:50px; /*important to share width in both divs*/    
        width:100%;
        background:red;
    }
    
    .headerFix, .footerFix {
        position:relative;
    }
    
    .header {
        position:fixed;
        top:0;
        left:0;
        /*this is now fixed, but the parent being in flow keeps this div from overlapping your list which is why the height had to be the same for both*/
    }
    
    ul li {
        /*basic list look for sample purposes*/
        display:block;
        min-height:40px;
        border-bottom:solid 1px #777;
    }
    
    .footerFix, .footer {
        height:50px; /*important to share width in both divs*/
        width:100%;
        background:red;
    }
    
    
    .footer {
        position:fixed;
        top:0;
        left:0;
        /*you will need to use javascript to find the height of device screen to know what the css value for "top" should really be. This will take some work on android where getting screen sizes is funky if you plan to support it. */
        /*If its iphone only you can assume the size which has always been the same, and make an exception for the new iphone 6. I say use javascript to position this footer if you plan to support many platforms*/
    }
    

    By the way I recommend using this meta tag in your html head to make sure you use the screen at its best

    <meta content='width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;' name='viewport' />