iScroll v4.1.3 introduces performance mode

Some users reported lower responsiveness in v4.1. Since iScroll is all about speed I introduced an “uber performance mode” that you can activate on compatible devices to get the smoothest scroll experience ever.

To reach a wider compatibility I had to remove some options available to iDevices only. Since many of you are using iScroll in iPhone only applications I introduced a maximum performance mode that grants the highest speed squeezable out of the Apple device.

To test the difference between standard and performance mode open the online demo ( ) on iPad.

You can enable this mode by passing the useTransition:true option, but it is compatible only with a bunch of devices (modern iPhone/iPod/iPad and Playbook). Of course all this smoothness comes to a price, some iScroll features are disabled while in “performance mode” (notably scrollbar shrinking). If the device doesn’t support transitions or their support is faulty, iScroll falls back to standard mode, so you don’t have to worry about loosing wide compatibility.

As far as I know, iScroll in performance mode is the only scrollview to benefit of 100% HW accelerated animations. As always on github you can grab the latest version (the performance mode is in the use-transition example folder).

Lastly let me share my frustration about features detection on both mobile and desktop browsers. Detecting browser features is a joke. Some features are detected but badly implemented, others are present but not detectable, others are so complicated to detect that checking the user agent becomes the lesser of two evils. Anyway iScroll is a work in progress, continuously evolving together with mobile technology, as soon as better features detection will be available I’ll try to adopt it.

30 thoughts on “iScroll v4.1.3 introduces performance mode”

  1. No difference on iPad 2 besides the scroll bar. But I love the concept 🙂

    1. I’d say *almost* no difference 🙂 it’s slightly more readadble, so I’d guess that more frames get drawn. I like it!

  2. Oh and Matteo, I know you must hear this often but could you work a bit on the bouncing? Maybe look at “scrollability” for a good algorithm.

  3. I’m agreeing with Christopher. The kinetics at the end of a scroll do not feel right yet.


  4. Hi Matteo…

    Please see PM. Really would love to have opportunity to ask for help to implement your script- it looks perfect for me…but we’re stuck.


  5. Hm, I’ve got a bunch of problems, when trying this new version:

    I have a html-page based on your 2way scroll demo. If I scroll left/right, it now always snaps to the top of the page (‘pagewrapper’).

    You can easily reproduce if you link the current version to your 2way-example.

    Anything I’m missing here?

  6. After upgrading to latest version (which incidentally in the source is labelled v4.1.2) – I realise form inputs can’t be clicked in a desktop Chrome browser OR a HTC browser, however on mobile safari and phonegap app its fine.

    Is this an issue with latest version 4.1.3 being iPhone only??

  7. Looks like we can now get rid of iScroll as fixed positioning is supported in iOS5! Happy days!! 🙂
    Thank you for all your good work though. Wouldn’t have been able to work and release my apps! Speak soon!

    1. Fixed positioning is a GODSEND, but I think iScroll will be needed for quite some time.

      I’m building a site using iScroll, and I cannot express how awesome it is to have this tool in the toolbox.

  8. Having said that… one of the frustrating things about 4.1 is it broke some of my layouts. I had my container box moved with position relative so that I could “center” my carousel items (like the screenshot view in the App Store). It was working fine but the new snapping method scrolls elements to the left-most position regardless. I tried position-relative moving the elements themselves, and it just added more scroll. I tried adding padding to my container. More scroll. I tried adding margin, or padding to the container OUTSIDE the scroller, and no matter what, it always scrolls as far left as it can.

    I’m still trying to figure out how to snap to an element to the center like I was doing with the old release.

  9. Thanks. There might be something different in the offset calculations. So if I add padding to the internal scroll container, it just scrolls the carousel elements even further. This is different than previous releases.

  10. What has happened to onZoomStart and onZoomEnd?
    I was using this to toggle snap on and off as snap really breaks when zoomed.
    Also now when you pinch out the snap jumps to far and does not end up on the page that was being zoomed.

    On the whole though great update.

    1. I miss this callback to, but I was able to insert two lines, which brought me the callback back again. Thanks to the universal “options” of the iScroll object:

      if (that.options.onZoomEnd)
      inserted into lines 442 and 955 (former 954).

      Initialize with:
      myScroll=new iScroll(‘pinchWrapper’, {
      zoom:true, […],
      onZoomEnd : function() { myPinchFunction() }

      But I would prefere, if Matteo will bring us back the zoom callback 🙂



  11. Hi,
    When I add jqtouch.js to my code the header on iscroll takes up the screen. Any ideas why this is?

  12. Thank you Matteo!

    But without the callback line at the end of the zoom function (now line 980), a double tab does not trigger any callback function.



  13. Excellent as usual
    can you make a demo example of your 2way scroll using 1Scroll 4.1? I love the performance of 2way on the old iscroll 3.7 and would like to upgrade it but it seems that your magic ninja Safari Css3 Javascript is beyond me.

  14. Hi Matteo,
    I’ve been working with iScroll4 for a few months incorporating it into my new iPad app. I have found a few problems that affected its functionality in my app. It took a while but I think i’ve sorted out the issues as it affects me. The problems relate to use of snap:’element’ and the section that has errors is in the refresh() code.

    PageX and PageY arrays
    The arrays built in the original code are only useful if you are using 1-D pages, ie just cells in a row or cells in a column. On a page structured like a table everything gets messy. What I did for my app was to build the arrays more carefully tracking the last x and y pos to determine when a new entry should be added to the array.

    Scale is not needed for the PageX and PageY calculations
    Scale has already been applied before the refresh code is reached so when the call to querySelectorAll is made, the co-ordinates have already been adjusted for scale. Therefore the pos.x * that.scale; and pos.y * that.scale; are not necessary.

    querySelectorAll doesn’t return co-ordinates in the necessary frame of reference
    I have found that I had to normalise the co-ordinates relative to the first element returned from querySelectorAll.

    The changes I made to the code only address my requirements and may not be suitable for a general implementation.

    Anyway, thanks for the work that you have put into this piece of code and hope that these comments help you.


  15. I had problem using iScroll if I try to put multiple iScrolls inside a div. So picture something like this:

    with scroller1
    with scroller1
    with scroller1

    The scroll won’t work as your code will take:

    that.wrapperH = that.wrapper.clientHeight

    and then

    that.maxScrollY = that.wrapperH - that.scrollerH + that.minScrollY;

    maxScrollY will just become 0.

    I did a quick hack and got multiple iScroller to work with position: relative.

    In the constructor:

    // hack to properly set it to relative
    // was empty for some reason, had to use jQuery to fetch it = $(that.wrapper).css('position');

    Then inside the refresh:

    if ( == 'relative') {
    that.wrapperH = that.wrapper.parentNode.clientHeight || 1;
    } else {
    that.wrapperH = that.wrapper.clientHeight || 1;

    This fixes the iScroller using position: relative.

    Is kinda ugly hack, but works for what I am trying to do.

  16. A bit mess up but I tried to type:

    with scroller1
    with scroller1
    with scroller1

  17. DANG IT…!

    div id=”outerHorizontalSlider” absolute
    >> div id=”wrapper1″ relative with scroller1
    >> div id=”wrapper2″ relative with scroller1
    >> div id=”wrapper3″ relative with scroller1
    end div

  18. Hi Mattheo,

    I am using a jSon file tot populate my list. When populating hardcoded iscroll works fine. But not white à jSon file?

    Is this à known issue?

    1. @JSON MRAVA
      i think that size of wrapper and elements to scroll should be knowed when initialize iscroll.
      Try popolate list by json and then create iscroll istance.

  19. I was wondering if there is a way to check if it is currently being dragged and not clicked. But cause i have some jquery who checks if the list item is being clicked, but it is also activated when being dragged.

    Very nice script, good work also on the other ones.

Comments are closed.