Hardware-Accelerated Page Transitions for Mobile Web Apps / PhoneGap Apps

I have been delivering a few PhoneGap Architecture and Performance talks in recent weeks. One of the performance techniques I talk about is –no surprise– the use of Hardware (GPU) Accelerated animations when available on the device. A typical example in a mobile application, is to hardware accelerate your page transitions. Even though this capability has been around for some time now, I still get a lot of questions about it. So I figured I would discuss it in this blog post.

Basic Infrastructure

Here is a typical set up for sliding pages in an out of the viewport in a mobile app:

The white box in the middle represents the browser viewport (the window through which the visible part of the document is seen): that is where the current page of your app is displayed at the full (100%) width and height of the viewport.

A page can be positioned to the left or to the right of the viewport by setting its “x” coordinate to -100% or 100% respectively (100% representing the viewport width). This can be done using two different approaches as explained below.

To slide a page from the right, you would:

  1. Position the page at the starting position of the transition (right)
  2. If needed, force a reflow to anchor the page at its starting position.
  3. Finally, position the page at the ending position of the transition (center) with the transition-duration style added to the page to indicate that it should be animated to that new position (see style definitions below).

In my own experience, I don’t have to force a reflow (step 2) when animating elements that are already in the DOM. However, I have to force a reflow when adding new elements to the DOM before animating them to their new position (see pageslider.js described below). More information here.

Here is a code example:

var homePage = document.getElementById("homePage"),
    newPage = document.getElementById("newPage");
// Position the page at the starting position of the animation
newPage.className = "page right";
// Position page at ending position of animation and add transition-duration
newPage.className ="page transition center";
// Simultaneously slide out the current page to the left of the viewport
homePage.className = "page transition left";

And here are two versions of the accompanying CSS: the first version will not hardware accelerate the transition; the second one will.

Non hardware accelerated transition:

Adding transform: translate3d(0,0,0); to the page will hardware accelerate the actual composition (drawing of the element on top of the background). However, it will not hardware accelerate the transition: The “left” property cannot be hardware accelerated. Changing the “left” property will force a layout every time the property changes (every frame).

.page {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

.page.left {
    left: -100%;
}

.page.center {
    left: 0;
}

.page.right {
    left: 100%;
}

.page.transition {
    -webkit-transition-duration: .25s;
    transition-duration: .25s;
}
Hardware accelerated transition:

To hardware accelerate the transition, apply a 3D transform to the page’s x coordinate instead of changing the value of the left property. The version of the style sheet below should hardware accelerate both the actual composition (drawing of the page) and the transition.

.page {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

.page.left {
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
}

.page.center {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

.page.right {
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
}

.page.transition {
    -webkit-transition-duration: .25s;
    transition-duration: .25s;
}

Try the simple example below. The code is self-contained in simplepageslider.html. Right-click the sample and select “View Frame Source” to check it out.

PageSlider.js: A Micro Library for Simple Page Transitions

In a real-life application, you will typically want to generalize the process a little bit. For example, you could:

  • Automatically add new pages to the DOM and remove them from the DOM after they are animated out of the viewport.
  • Automatically determine the sliding direction based on the page history.
  • Provide a hook (using the webkitTransitionEnd event) for adding some logic when the transition completes.

I isolated that logic in pageslider.js, an example of a micro library you could use to provide hardware accelerated page transitions in your mobile apps.

Try the example below, or try it fullscreen here.

Source Code

The pageslider.js source code is available in this GitHub repository.

Hardware acceleration is not available on all platforms. Check out caniuse.com to see which platforms are supported. Make sure your animations work on platforms that do not support hardware acceleration.
  • Thanks for sharing this. I’ve yet to use translate3d, but if it speeds things along, I don’t see the reason why not.

    As far as I can tell (reading documentation and source) jQuery Mobile also uses translate3d and translateX,Y,Z for panel and page animations respectively.

  • Full page demo works perfectly on my old iPhone4, very slow on Nexus10, with the transition not showing at all at times (and sometimes showing from the wrong direction)

  • Ben

    How could this be dropped into a Backbone app where the views are dynamically generated? Would you be calling slider.slide() from the Router ?

  • You might want to change the html structure a bit.

    On bigger apps the reflow caused by the changing of classes might be too expensive.

    a) I’d suggest positioning each page in its final position, but with a wrapper, change the class only on the 2 pages you’re animating. Since they’re contained in their own absolutely positioned wrapper only those 2 pages will reflow, not all els (pages) on the same level.

    b) Since this is a predictable a/b animation, we can use keyframe animations instead to avoid having to force a reflow, to make sure the animation is consistent, more control.

  • Pingback: Making PhoneGap Feel Native | Esa Juhana()

  • app-UI also use this in his CSS, https://github.com/triceam/app-UI/blob/master/src/viewnavigator/viewnavigator.css, still, in android is sooooo slow, on ios it feels ok, but android is just a PITA, any workaround for android?

  • Sir Kelsen

    Excuse me, is there any kind of way to delete the transitions? I am making an APP that works as a ”quiz”, and depending on the answer, it goes to a page or other. The problem is the transition, my app does a flicker and i would like to avoid that. :(

  • Pingback: Sociogram Mobile: A Starter-Kit Application for PhoneGap and Facebook Integration | Christophe Coenraets()

  • Federico González Brizzio

    Hi Christophe,

    I’m using Page Slider, but I need to integrate it with BootStrap (responsive). “.page” with absolute position is a problem with container’s width (in px) ¿Have you any fix for this?

    Thanks! Federico, from Ushuaia, Argentina

  • Pingback: Days till Dead – Android App built on PhoneGap - Jae Subramoney()

  • david

    How to solve IE9 problem, since that doesnt support 3d

  • We’re a group of volunteers and opening a brand new scheme in our community. Your site provided us with valuable info to work on. You have done an impressive activity and our entire group can be thankful to you.

  • Jeremy

    Hi,

    Great article – many thanks!

    Question – If my pages have different heights with scrolling in them, when I slide between pages, how do I maintain the scroll position of each page? For example, page A is 460px high and B is 700px. I slide from page A to B and then I scroll down B to the bottom of the page. When I scroll back to A, it’s also become 700px high and the bottom of A is shown. When I slide back to A, I want its original scroll position to have been preserved.

    Many thanks
    J

  • Hadrien

    Hi, nice code thanks. I have an issue while running your first example on Android (as a compiled phonegap app I mean):

    I can scroll horizontally and thus display the right panel without clicking on the link. I’m facing the exact same issue on another app where I have div overflowing the screen. Any ideas on that?

    • Jure Čekon

      If you’re having problems with horizontal scrolling, try using position: fixed; instead of absolute.

  • Pingback: Phonegap and Android overflow issue | BlogoSfera()

  • Pingback: Phonegap and Android overflow issue | Ask & Answers()

  • matt

    I like the idea behind your slider but I notice when inspecting the page in firebug that each time I navigate to and from a “PAGE” it reinserts the page so depending on how often you navigate to and from a page it adds it in again. is this going to be an issue?

  • Tobias Sjögren

    Hi,

    I would really like to have the page transitions without jQuery, would it be possible for you exclude any bigger JavaScript file dependencies?

    …Tobias

  • johnny

    Hi Christophe, great article and very nice plugin. I want to thank you for all of your work. I’m very new to Phonegap and I’m not the fittest in Javascript. So your articles and videos were a good source for my learning process.

    Now I’m trying to combine pageslider.js with the native scroll from iscroll.js (version 5). I want to see if it works together so I mixed up together the code of your pageslider example on github with a simple iscroll 5 demo (barbone).
    I primarily want to run it on iOS. But I don’t get it to work. The native scrolling is not working. I think that it has something to do with the dynamic loading of the HTML content. So I tried to refresh iscroll. But I don’t know how to do that exactly. I’ve already tried a lot of solutions that I found in some forums but it’s still not working and I don’t want to use jquery mobile just for page sliding.

    Please can somebody help me?

    Thanks
    johnny

  • Pingback: Parallax UI for PhoneGap and Mobile Web Apps | Flippin' Awesome()

  • Hellow
    whether it is reasonable to use jquery address plugin for the construction of a mobile application where we load specyfic page when address is change ( we load pages and their scripts ) ?

  • Gud but not if you want to have dynamically generate pages…

  • Cheers m8,

    big thanks for your solution. Up on this we build:
    https://github.com/linslin/pagingSlider

    – slide to pages with touch swipes
    – auto switch to pages by clicking menu item
    – animated mobile pagebrowser
    – integrated touch events with QuoJS

  • vishant

    Hi,

    I have an issue with the simple pageslider on my iphone. From portrait to landscape back to portrait the page shrinks so the next page is also visible. Is there a fix for that?

  • NSY

    Hi,

    Your work really saved my life, I been struggled for couple weeks due to my phonegap app is really slow and laggy….

    Is that any possibility to make the page swipeable?

  • Lu

    I own the domain name HardwareAcceleration.net, I am selling it. Visit my website if interested.

  • Sebastián Garzón

    Page Slider doesn’t work on my Android Huawei G610 the app doesn’t make anything. Don’t know why

  • falkdav

    Hi, Mr Coenraets, I have a problem (conflict) with your script and jQuery Mobile, this is my index.html

    Page Slider

    In Firebug log:

    TypeError: $ is undefined
    var slider = new PageSlider($(“#container”));
    ReferenceError: $ is not defined
    var slider = new PageSlider($(“#container”));
    How I can fix this problem?
    Thanks in advance!

  • hi!,I really like your writing very much! percentage we keep up a correspondence more about your post on AOL? I require an expert on this house to resolve my problem. Maybe that is you! Having a look forward to see you.

  • @Christophe

    Hi have used cordova notification plugin navigator.notification.confirm(), this plugin shown on the screen at the same time background timer count is running. user didn’t click conform dialog option but my timer will reach to zero, In the case i force to dismiss the conform dialog box.

  • This page really has all of the information and facts I needed concerning this subject and didn’t know who to ask.

  • Kilka rad dla utrzymanie siebie młodszy, chociaż system jest starzenie, jest utrzymać nauka.
    Dowiedz się więcej o: aktywnie gra most,
    wykorzystanie Twój komputer osobisty, ogrodnictwo, drewno pracy lub cokolwiek powrotu do odkrycia wcześniej w życiu codziennym ale nie
    posiadać czas zrobić. Ponieważ jesteś na emeryturze i Twój młodzież są uprawiane, już nie posiadać wymówki z nie mając czasowa
    do spojrzeć te nowe eskapady z nauka. Bynajmniej pozwolić Mózg pozostać nieproduktywne!
    mouse click the next webpage; pbmstoria.it, Kombajny gorące i pikantne wyżywienie
    na cudownym wina. Zwłaszcza ciepła z Tajlandii i Indii produkty żywnościowe, trzeba będzie wolne od wilgoci biało-kolorowe i czerwonawy kolorowe
    wino które s. Niektóre wielkie par składa się z Chenin Blanc, Gewurztraminer
    i Riesling. Po zakupie Riesling, rozważyć zmierzasz marka bo ich
    lepiej poziom kwasowości nie tworzenie słodycz wydaje się jak
    zauważalne. Te wino stanowić podniebienia środki czyszczące pomóc cieszyć się pikanterii z w Jedzenie.
    secret info Aby mieć pewność, elegancki proces starzenia, należy
    include przeciwutleniacze w Twój konsumpcja żywności walczyć
    wolne rodniki. Nawet największym źródło ziołowy przeciwutleniacze pochodzą z
    artykuły spożywcze jak pomidory, zielona fasola, zielony szpinaku, wiemy to
    niekoniecznie łatwo brać w wystarczająco aby Odmiana .
    Specjaliści sobie i adwokata za pomocą suplementy zdrowotne z Kwas askorbinowy i E, oraz, jedzenie żywności przeciwutleniacze,
    witaminy. please click the up coming post Wskazówka dla prowadzenie młodszy, nawet jeśli system jest starzenie, jest zawsze utrzymać odkrywanie.
    Dowiedz się więcej o: aktywnie gra most, tak,
    jak korzystania Twój komputer osobisty, ogrodnictwo, stolarka lub cokolwiek planował dowiedzieć się,
    w życiu codziennym ale nie trzymać czas, aby zrobić. Ponieważ jesteś młodzież są opracowała, już nie mieć
    uzasadnienie z nie potrzebuje czasu do spojrzeć te nowe Działalność z zrozumienie.
    Nigdy nie umożliwić mózgu nadal bezczynny! click the up coming website Wprowadzenie wszystko na własną rękę, polski paznokci często są bardzo
    obciążających, szczególnie kiedy z brak – wybitny
    palmy. Następnym razem, zastosowanie wasze typowe normalny color a
    także palto w nocy (oferta połysk kilka godzin do
    wolne od wilgoci przed snem). Nie się martwić zbytnio w przypadku polski
    będzie na swojej skórek. Następnie codziennie,
    wymagają prysznic Powierzchnia, i ekstra polski w Twoje skóra będzie masaż właściwe off.
    view publisher site Wprowadzenie wszystko na własną rękę, polski paznokci może być bardzo irytujące, szczególnie kiedy z niski – dominuje palmy.
    następnym razem, zastosowanie wasze typowe normalny shade oraz palto wieczorem (dostarczyć połysk kilka godzin do wolne od wilgoci przed snem).
    Nie stres zbytnio w razie poprawy będzie w skórek. Następnie rano,
    wymagają prysznic Powierzchnia, a wszystko wszelkie dodatkowe poprawa w Twoje pory naskórka i skóry będzie masaż prawo z dala.
    click through the up coming article Wskazówka dla pobytu młody,
    nawet gdy ciała jest starzeje, jest zawsze zachować odkrywanie.
    Odkryj więcej o gra połączenie, jak używać komputer, rosnące rośliny, drewna lub cokolwiek chcieli odkrycia w życiu ale nie się czas,
    aby zrobić. Ponieważ jesteś na emeryturze i Twój wasze dzieci uprawiane, nie będziesz już
    pobrać wymówki z bez jakiś czas do spojrzeć te nowe podróże z studia.
    Bynajmniej pozwolenie mózg człowieka pozostać bezczynny!

  • It’s in fact very complex іn tnis active life tο listen news
    on TV, so I ʝust usе the web for tht reason, and get the mosdt recent news.

  • The other day, whule I was at work, my sister stole my iPad and tested to seee if it can ssurvive a
    40 foot drop, juist so she caan be a youtube sensation. My apple ipad is
    now broken and she has 83 views. I know this is entirely off topic but
    I had to share iit with someone!

  • I’ve learn several just right stuff here.
    Definitely worth bookmarking for revisiting.
    I surprise how a lot effort you put to create any such excellent informative web site.

  • Very soon this website wilkl be famous amid all blogging viewers, due to it’s fastidoous content

  • It’s tthe best time tto make a few plans for the longber term
    and it’s time tto be happy. I’ve read this publish and if I may I wish to recommmend you few fascinating things orr suggestions.
    Perhaps you could write subsequent articles regarding this article.
    I wish too read more issues about it!

  • Hey there just wanted to give you a quick heads up.
    Thhe words in your post seem to be running ooff the screen in Firefox.
    I’m not sure iif this is a formatting issue
    or something to do with internet browser compatibility but
    I thought I’d post to let you know. The style and design
    look great though! Hope you get the problem fixed soon.
    Kudos

  • Thank you for every other informative website. The place else
    may just I am getting that type of information written in such an ideal approach?
    I’ve a venture that I’m just now operating on, and I have been at the look out for such info.

  • Yann

    Hello,

    Nice work !

    I implemented this in my phonegap app, it works great on the browser (desktop and mobile) but it’s not smooth at all when compiled in cordova on a Nexus 5.

    I use background-image on both pages it seems to be the cause.

    Do i need to add something in css or cordova config to help smoothing, just like in the mobile browser ?

    I use :
    cordova 3.5
    Backbone.js
    handlebars.js
    zepto.js

    Thanks,

  • Your means of explaining the whole thing in this
    article is genuinely pleasant, every one be able to simply understand it,
    Thanks a lot.

  • url

    certainly like your web site but you have to check the spelling on several of your posts.
    Many of them are rife with spelling issues and I in finding it very bothersome to inform the truth however I will
    definitely come back again.

  • I get pleasure from, cause I found just what I was taking a look for.

    You have ended my four day lengthy hunt! God Bless you man. Have a great day.
    Bye

  • Hey! Quick question that’s totally off topic. Do you know how to make your site mobile friendly?
    My weblog looks weird when browsing from my apple
    iphone. I’m trying to find a template or plugin that might be able to fix this issue.
    If you have any suggestions, please share. Many thanks!

  • perfect this blog is very informative . you have briefly explain in this short blog about hardware accelerated type transmission for mobile apps. your tips are really good,

  • Thank you for this. However, this approach seems to make the page 200% of what it should be, so that users could “scroll over” and see the hidden pages on the right. To get around this I added “overflow: hidden”, however, for some reason that messes with the animation of pages from the right. Now they simply “appear”. Does anyone have any suggestions for getting around this?

  • Awesome piece of kit. Am struggling to add a function to get item from local storage and perform a calc with value taken from one page to another, can anyone help?

  • Pingback: Parallax UI for PhoneGap and Mobile Web Apps - Modern Web()

  • good blog thanks admin

  • Pingback: jQuery Mobile and PhoneGap Performance problems | Some Cordova Questions and Answers()

  • качество, надежность, экономичность и связанные работы выполняются imalattan.profesyonel команду.http://jonsunsport.com/spor-coraplari.html

  • A.R Butt

    I read your article the way you describe is impressive the all parts info you give with the help of that info many people learn too much after a long time i see a fabulous site which content is good thanks for the nice information i am waiting for update.

  • The only other way I know would be to hack away at the CSS for JQM.

  • Jack

    Thanks for sharing it!
    I have found nice open source library!
    The library is created using the parallax effect. It looks fresh and eye-catching. – https://github.com/Cleveroad/SlidingTutorial-Android

css.php