Poor Jquery Animation Performance

11 posts, 1 answers
  1. Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 25 Oct 2012 Link to this post

    I am designing an app that takes advantage of jquery's built in animations. I initially designed and tested them in the devices built in web browser, then moved it into icenium. On both android and iPhone, the performance dramatically decreased. Now animations are slow and make the application look less responsive. Is there a way that I can increase javascript performance?

    I created the following animation sample to test on devices.

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>Hello, World</title>
    <link href="jquery-mobile/jquery.mobile-1.1.1.min.css" rel="stylesheet" type="text/css" />
    <link href="styles/main.css" rel="stylesheet" type="text/css" />

    <script src="cordova.js" type="text/javascript"></script>
    <script src="jquery-mobile/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="jquery-mobile/jquery.mobile-1.1.1.min.js" type="text/javascript"></script>
    <script>
    $(document).ready(function() {
    $("#btn1").click(function() {
    $("#box").animate({width:"500px"});
    });
    $("#btn2").click(function() {
    $("#box").animate({width:"0px"});
    });
    });
    </script>
    </head>
    <body>

    <div data-role="page" id="home">
    <div data-role="header">
    <h1>Hello, World!</h1>
    </div>
    <button id="btn1">Animate</button>
    <button id="btn2">Reset</button>
    <div id="box" style="background:#00a0e4;height:500px;width:0px;">
    </div>
    </div>

    </body>
    </html>
  2. Yavor Georgiev
    Admin
    Yavor Georgiev avatar
    982 posts

    Posted 26 Oct 2012 Link to this post

    Hello Chris,

     Applications built on Apache Cordova (aka PhoneGap) run in a UIWebView component under iOS. The difference between Mobile Safari and UIWebView is that JavaScript in Mobile Safari is JIT-compiled with the Nitro engine, while JavaScript in UIWebView is interpreted. This leads to reduced performance of jQuery animations and other JavaScript-heavy operations in UIWebView.

     I'd advise you to use CSS3 animations instead of jQuery animations. What's more, you can enable hardware-accelerated rendering for elements in the DOM, which increases animation performance even further.

     This is a known issue for iOS and will unfortunately continue to persist until Apple decides to use the Nitro engine in UIWebView.

     Could you please share some information about your Android environment? What devices did you test on, and what version of Android were they running?

    Kind regards,
    Yavor Georgiev
    the Telerik team

    Share feedback and vote for features on our Feedback Portal.
    Want some Kendo UI online training - head over to Pluralsight.
  3. Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 06 Nov 2012 Link to this post

    So I recreated an animation using css3 animations and only using jquery to trigger it. This is being tested on a samsung galaxy sIII running android 4.1.1. I am still getting mediocre performance overall.

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>Hello, World</title>
    <link href="jquery-mobile/jquery.mobile-1.1.1.min.css" rel="stylesheet" type="text/css" />
    <link href="styles/main.css" rel="stylesheet" type="text/css" />

    <script src="cordova.js" type="text/javascript"></script>
    <script src="jquery-mobile/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="jquery-mobile/jquery.mobile-1.2.0.min.js" type="text/javascript"></script>
    <style> 
    .open
    {
    width: 200px;
    height: 615px;
    background: green;
    position: relative;
    -webkit-animation: open .35s; /* Safari and Chrome */
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    -o-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    left: -15px;
    top: -15px;

    }

    @-webkit-keyframes open /* Safari and Chrome */
    {
    0% { background: green; left: 0px; top: 0px; height: 615px; width: 0px; left: -15px; top: -15px; }
    25% { }
    50% { }
    75% { }
    100% { background: green; left: 0px; top: 0px; height: 615px; width: 200px; left: -15px; top: -15px; }
    }

    .close
    {
    width: 0px;
    height: 615px;
    background: green;
    position: relative;
    -webkit-animation: close .35s; /* Safari and Chrome */
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    -o-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
                    left: -15px;
    top: -15px;

    }

    @-webkit-keyframes close /* Safari and Chrome */
    {
    0% { background: green; left: 0px; top: 0px; height: 615px; width: 200px; left: -15px; top: -15px;}
    25% { }
    50% { }
    75% { }
    100% { background: green; left: 0px; top: 0px; height: 615px; width: 0px;left: -15px; top: -15px; }
    }

    </style>
    </head>
    <body>

    <div data-role="page" class="page" id="home">

    <div data-role="content">
    <div class="first" style="float:left; position:relative;"></div>
    <div  style="float:left; position:relative;">
    <a href="#" data-role="button" data-theme="b" id="open" >open</a>
    <a href="#" data-role="button" data-theme="b" id="close" >close</a>
    </div>
    </div>
    <div class="nav">
    <ul data-role="listview">
    <li>
    <a href="#page1" data-transition="slide">UI Interaction Example</a>
    </li>
    <li>
    <a href="#page2" data-transition="slide">Geolocation Example</a>
    </li>
    </ul>
    </div>

    </div>


    <script>
    $.event.special.swipe.horizontalDistanceThreshold = 130;
    $(".page").swipeleft(function () {
    $(".first").removeClass("open").addClass("close");
    });
    $(".page").swiperight(function () {
    $(".first").removeClass("close").addClass("open");
    });
    $("#open").click(function() {
        $(".first").removeClass("close").addClass("open");
    });
                $("#close").click(function() {
    $(".first").removeClass("open").addClass("close");
    });
    </script>
    </body>
    </html>

  4. Jordan
    Admin
    Jordan avatar
    197 posts

    Posted 07 Nov 2012 Link to this post

    Hello Chris,

    We are looking at your issue and will let you know asap if we find a working solution.

    Is the issue now only on Android? Did rework solve it on iOS?

    Regards,
    Jordan
    the Telerik team

    Share feedback and vote for features on our Feedback Portal.
    Want some Kendo UI online training - head over to Pluralsight.
  5. Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 07 Nov 2012 Link to this post

    No, its still happening in both Android and iOS. I am also getting very choppy vertical scrolling. Thanks for looking into this.
  6. Answer
    Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 08 Nov 2012 Link to this post

    Hi Chris,

    I spent few hour on this and it is not very easy to find the proper solution.

    Here is a sample index.html similar to yours that works with very smooth slide transitions on iOS at leas on device I have tested on (5.0.1/6.0) and Android (v.2.3.3) too.

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
     
            <title>Side nav scroll in</title>
            <link href="jquery-mobile/jquery.mobile-1.1.1.min.css" rel="stylesheet" type="text/css" />
            <link href="styles/main.css" rel="stylesheet" type="text/css" />
     
            <script src="cordova.js" type="text/javascript"></script>
            <script src="jquery-mobile/jquery-1.7.1.min.js" type="text/javascript"></script>
            <script src="jquery-mobile/jquery.mobile-1.2.0.min.js" type="text/javascript"></script>
     
            <style>
                         
                body
                {
                    overflow: hidden;
                    height: 100%;
                }
     
                .nav
                {
                    left: 0;
                    top: 0;
                    position: fixed;
                    -webkit-perspective: 1000;
                    -webkit-backface-visibility: hidden;
                    height: 100% !important;
                    display: block;
                }
                .nav > ul
                {
                    width: 260px;
                }
                 
                .slide-to-left
                {
                    left: 0;
                    top: 0;
                    position: fixed;
                    background-color: #FFF;
                 
                    left: 0px;
                    -webkit-transition-property: left;
                    -webkit-transition-duration: 0.35s;
                    -webkit-transition-property: ease-in-out;
                }
                 
                .slide-init {
                  left: 0px;
                }
                             
                .slide-out
                {
                    left: 260px !important;
                }
                 
                @media all and (-webkit-transform-3d)
                {
                    .slide-to-left
                                {
                                    -webkit-transition-property: -webkit-transform;
                                }
                 
                    .slide-out
                                {
                                    left: 0 !important;
                                    -webkit-transform: translate3d(260px, 0, 0) !important;
                                }
                }
             
            </style>
        </head>
        <body>
     
            <div id="nav" class="nav" data-theme="a">
                <ul data-role="listview">
                    <li>
                        <a href="#home" data-transition="none" data-icon="home" >Home</a>
                    </li>
                    <li>
                        <a href="#page1">Page 1</a>
                    </li>
                    <li>
                        <a href="#page2">Page 2</a>
                    </li>
                </ul>
            </div>
     
            <div data-role="page" class="slide-to-left" data-transition="none" id="home">
                <header data-role="header">
                    <h1>Slide menu</h1>
                    <a href="#" data-role="button" class="slide-toggle" data-icon="grid" data-iconpos="notext"></a>
                </header>
                <div data-role="content">
                    <p>Enjoy!</p>
                </div>
            </div>
     
            <div data-role="page" class="slide-to-left" data-transition="none" id="page1">
                <header data-role="header">
                    <h1>Page 1</h1>
                    <a href="#" data-role="button" class="slide-toggle" data-icon="grid" data-iconpos="notext"></a>
                </header>
                <h1>Page 1</h1>
            </div>
     
            <div data-role="page" class="slide-to-left" id="page2">
                <header data-role="header">
                    <h1>Page 2</h1>
                    <a href="#" data-role="button" class="slide-toggle" data-icon="grid" data-iconpos="notext"></a>
                </header>
                <h1>Page 2</h1>
            </div>
     
            <script>
                 
                // hack to style nav with jQueryMobile
                $("#nav").page();
                // disable default transitions
                $.mobile.defaultPageTransition = 'none';
     
                $(document).on("pagebeforehide", function (event , data) {
                    $(data.nextPage).addClass("slide-out");
                });
     
                $(document).on("pagechange", function (event , data) {
                    $(".slide-out").removeClass("slide-out").removeClass("slide-init");
                });
                 
                $.event.special.swipe.horizontalDistanceThreshold = 130;
                $("body").swipeleft(function () {
                    $(".slide-to-left.ui-page-active").removeClass("slide-out");
                });
                 
                $("body").swiperight(function () {
                    $(".slide-to-left.ui-page-active").addClass("slide-out");
                });
                 
                $(".slide-toggle").click(function() {
                    $(".slide-to-left.ui-page-active").toggleClass("slide-out");
                });
            </script>
        </body>
    </html>

    Hope this will give you an idea how to implement in your app. Regards,
    Jordan
    the Telerik team

    Share feedback and vote for features on our Feedback Portal.
    Want some Kendo UI online training - head over to Pluralsight.
  7. Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 09 Nov 2012 Link to this post

    Jordan,

    First, Thank you for the reply. Its fixed 90% of the problems. Its smooth on the transition out, but staggers a bit on the transition in. The code was tested on my galaxy s3. Do you think this is related to the screen size?
  8. Jordan
    Admin
    Jordan avatar
    197 posts

    Posted 09 Nov 2012 Link to this post

    Hello Chris,

    it may be, but can not tell of fix without real device :(

    Unfortunately I can get the Galaxy s3 on Monday to play with.

    1. First add -webkit-transform: translate3d(0, 0, 0); to .nav class to force it to be 3D accelerated too.

    2. Just a wild guess try to play with viewport meta tag as described here and set it to native resolution and see if this will improve things.


    Greetings,
    Jordan
    the Telerik team

    Share feedback and vote for features on our Feedback Portal.
    Want some Kendo UI online training - head over to Pluralsight.
  9. Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 09 Nov 2012 Link to this post

    Here is where I am declaring the viewport meta.

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">

    I tried adding the css. I don't see a noticeable difference. Still, this is much better than it was before. Thank you for keeping up with this. Please get back to me as soon as you get the galaxy S3 on monday.

    If you need access to an app that I am testing with, please contact me privately. 
  10. Chris
    Chris avatar
    8 posts
    Member since:
    Mar 2012

    Posted 09 Nov 2012 Link to this post

    I read the article and started doing more testing. Its important to note performance seems to be based on the content on the defined page. So there may be something else at work here. Try adding a  long data list and set it to data-inset="true". Pages with this markup are much slower than others.
  11. Ivan K. Ivanov
    Admin
    Ivan K. Ivanov avatar
    32 posts

    Posted 12 Nov 2012 Link to this post

    Hello Chris,

    We just tested with Jordan the sample app he sent you on Galaxy S3 and expanding and collapsing both works fine. Our device is upgraded to the latest official Samsung release of Android version 4.1.1.

    Is it same on your device?

    P.S. Jordan will contact via email for your specific app.

    Thanks,
    Ivan K. Ivanov
    the Telerik team

    Share feedback and vote for features on our Feedback Portal.
    Want some Kendo UI online training - head over to Pluralsight.
Back to Top