JavaScript Parallax Effects: A Deeper Look

Earlier this year, I wrote a tutorial explaining how the Nike Better World website was created and how you could use jQuery to create that effect on your own website. Since the launch of Nike Better World, the web has gone parallax crazy with many websites trying their own hand at the effect.

Having seen many-a-site using the effect and having worked on a few too, I think it’s time to dig deeper and take a closer look at some of the issues around using the JavaScript parallax effect, as well as answering some overdue questions from my original tutorial.

Performance

The biggest problem with the JavaScript based parallax effect is that it is very performance heavy. The creators of Nike Better World stated in their interview with Smashing Magazine: “Our primary focus was on creating a great interactive storytelling experience“. It seems that some implementors of the effect have lost sight of the purpose of the parallax effect — “experience”, instead opting simply to use the effect as a way to make their site look impressive, without considering performance.

Issues

To create the parallax effect, JavaScript is used to manipulate the position of an element in relation to a web page’s scrollbar (see my original tutorial for the full explanation). It sounds simple enough but the problem is, this calculation needs to be carried out for every single pixel a web page is scrolled. The calculation could quite possibly be carried out 100s of times per second, depending on how fast the user is scrolling. On top of that, you’ll need to manipulate multiple elements to create the effect. Too many of these calculations and the effect will “stutter”, effecting the scrolling of the web page and the users overall experience, potentially frustrating the user enough to make them leave.

Surprisingly, such a new and impressive effect only makes use of older technologies (JavaScript, HTML4 and CSS2) and can even run perfectly well in old browsers such as Internet Explorer 6. However, there is one exception…Firefox.

When viewing the effect in Firefox, the performance issues are multiplied. I believe this to be a fundamental issue with how Firefox deals with page scrolling and can’t be avoided using a nifty work-around or hack (if you know better, let me know). With Firefox churning out new updates on a regular basis now, the effect has performed better than the last with each new iteration, but in my opinion, Firefox 6 — even on a high end machine — still struggles to calculate the effect without “stuttering”.

One final issue I’d like to point out for the pixel perfectionists…many browsers throttle the scrolling of a page to increase performance. This means, if you’re scrolling quickly up/down a page, the browser won’t trigger events for every pixel you scroll; it won’t redraw the page every pixel and neither will it trigger the JavaScript to create the parallax effect every single pixel. This not only leads to more “Stuttering” but also a loss of synchronization between the elements being manipulated and the scrollbar.

Improvements

So, now we know the issues, how can we avoid them?

The obvious solution is to keep the number of media elements being manipulated to a minimum. However, this doesn’t mean you can only have x number of manipulated elements per page. You could potentially have 100s of elements on the page, providing there are only one or two (my recommendation) being manipulated in the viewport at any one time.

This “selective” manipulation can be achieved by using a script that determines when an element is or is not within the viewport (and being seen by the user).

My original demo uses Remy Sharp’s Inview plugin but that, unfortunately, is no longer supported and doesn’t work with the latest versions of jQuery. There are plenty more of these plugins available though.

Further to this, remember to always test on a mid-level machine to make sure your web page will work for the majority of users. As Firefox seems to “stutter” the most, I’d recommend you benchmark test using that.

Mobile Support

Since posting my original tutorial, I got quite a few people asking me how could they get the effect working on mobile devices. Quite simply, you can’t! At least not for iOS devices (I haven’t tested on other devices so if my next point is true for other smart phones/tablets, please let me know).

Much like the aforementioned desktop browser throttling when scrolling, mobile devices take this one step further to improve performance. When scrolling in a mobile browser, no events are triggered until you’ve stopped scrolling — not even redrawing of the page. So, with the JavaScript parallax effect enabled on a mobile web page, when a user scrolls, nothing will move until the user stops scrolling. An element that should be manipulated will simply go from position A – Z without any transition in between.

So, the solution is to use JavaScript to detect what type of device the web page is being viewed on. If it’s a desktop, allow the JavaScript to go ahead manipulating elements, if it’s a mobile device, don’t. The Nike Better World site uses this code to detect a mobile device:

$.Mobile = ($.Body.hasClass('webkit-mobile') || (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)))

Then later tests whether $.Mobile is true or not and activates/ignores the parallax effect JavaScript based on the outcome:

if($.Mobile){
    //code for mobile device
}else{
    //code not for mobile device
}

Conclusion

In my opinion, the parallax effect and attaching events to a users scrolling offer lots of ways to make a website experiential and unique. With the above tips, hopefully your implementation of the effect can be more efficient and a great experience for your users, just like Nike Better World is.

Written by Ian Lunn

Ian Lunn is a Freelance Front End Developer based in sunny Devon, UK. Specialising in HTML5, CSS3 and jQuery. He uses the latest web technologies to build creative yet effective websites and applications.

This entry was posted in Code Tutorials. Bookmark the permalink.
  • Max

    Hay Ian!

    where I have to put this code: $.Mobile = ($.Body.hasClass(‘webkit-mobile’) || (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)))

    to detect what type of device the web page is being viewed on and block parallax effect for ipad and iphone?

  • Max

    Hay Ian!

    where I have to put this code: $.Mobile = ($.Body.hasClass(‘webkit-mobile’) || (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)))

    to detect what type of device the web page is being viewed on and block parallax effect for ipad and iphone?

  • http://www.ianlunn.co.uk/ Ian Lunn

    Hi Max,

    That piece of code should be placed toward the top of your script. The $.Mobile variable will be either true or false. You should query that variable to say whether you want a particular piece of code to execute for mobile or not. Example:if($.Mobile){     //code for mobile device }else{     //code not for mobile device }

  • Logan

    Hi Ian! What is the correct form to aply this Example:if($.Mobile){     //code for mobile device }else{     //code not for mobile device }

  • http://www.ianlunn.co.uk/ Ian Lunn

    I’m not sure I understand Logan. If you want to apply the parallax effect only to a desktop (instead of mobile), you’d use this:

    if(!$.Mobile){     //parallax code goes here }

    The if statement checks to make sure the device is not a mobile.

  • Andrés Redondo

    Hi Ian, first congratulations for your blog, it´s awesome. I´ve been thinking about to use this parallax effect for my final work of a master, my portfolio page, putting different slideshows or something like this in every section.. Do you think that i can have troubles with that. Best Regards from Spain. Thank you so much.

    Andrés.

  • underlircs

    Hi Ian, I found your site while research for a tutorial on how to create the parallax effect on mobile devices. While all the codes I came across were unable to perform well on say an iPhone or iPad. HBO Go’s product tour did. Check it out at http://www.hbogo.com/product-tour/

  • Andrés Redondo

    Hi Ian, it´s me again. I´ve found a bug in your excellent work. The automatic scroll don´t run under Safari explorer.. Do you know something about that?

    Thank you so much! Andrés.

  • http://www.ianlunn.co.uk/ Ian Lunn

    Hi Andres, no you won’t have problems. This is something I have done before using RoyalSlider, highly recommended! http://codecanyon.net/item/royalslider-touchenabled-jquery-image-gallery/461126

  • http://www.ianlunn.co.uk/ Ian Lunn

    Scrolling doesn’t work in Safari when viewing the demo locally. Upload it to a server and it will work.

  • Lee

    Hi Ian. First of all, great script. Its possibly the smoothest parallax plugin on the web right now!

    I’ve noticed what appears to be a bug, however. When I first load the page, some of the elements are shifted up from where they are supposed to be. The second you scroll, it seems to fix itself and behave normally from thereon. But, that initial ~200px shift is somewhat unsettling.

    Any ideas on what could be causing this? It occurs in both Firefox 7 and Safari, in both the sample I’ve set up and the sample included with your plugin.

    Cheers,

    Lee

  • Jeff

    Hi Ian,

    Me again, I was wondering if it’s possible to have the background images, not hidden by the next one when we scroll ? Imean, I want to have like a kind of big background image with the other background sliding up or down but hiding each other. I hope u understand what I mean.

  • Andersp

    Your parallex effect works better than nike’s, not even kidding. You da man!

  • canusta

    It’s possible to get the effect on mobile: http://www.moodsofnorway.com I’m trying to understand and use the technique, but I couldn’t solve it yet! If anyone did, please help me: talkto@canusta.com 

  • http://www.facebook.com/profile.php?id=615362642 ‘Philippe Nast

    upping this i do have the same provblem, and still searching a workaround. any help is welcome

  • Flashysite

    I’m also experiencing this same problem, strangely! I keep on trying to fix it and it would behaves strangely again on its own. 

    I’m thinking of increasing the page height and keeping it way above the browser, so when it pushes things down it would still look ok, instead of a blank canvas.

    Anyways, I would like to thank you ian, for this very excellent piece of work you did and sharing it with us. By the way your parralax site ‘TIGI’ is looking very nice!!!!

  • Rick

    Hi Ian,

    This is a great plugin. Is there any way to get the background to scroll to a certain spot (percentage possibly?), and stop? Thanks, Rick

  • NoFxor

    Hia Ian,

    it seems that my site using your base is pretty laggy and stuttering on chrome. You got any idea how to fix this?

    do you have any idea how to make a scrollwheel easing with scrollwheel.js?

  • http://baby.taraandaaron.com/ Aaron

    I also ran across this but it was because I changed the position of the background image in the CSS from 50% 0 to 50% 100% (I wanted it to sit at the bottom of the div. This was causing the problem for me. I changed it back to the top position and it resolved the issue. I suggest adding some padding to the image itself if you want to muck about with the image position (unless you’re a JS wizard like Ian).

    Not sure this is the issue for you but it was causing problems for me. Good luck.

  • GG

    This problem occurs depending on how tall the browser’s height is when it’s open…..as a result bkg values changes and pushes everything downward…

  • Grahame

    Hi Ian, I’ve developed this site based on your parallax code (questacon.edu.au/excite/)  Got half way through implementing horizontal parallax options (as you might see in the script) but ran out of time. I’ll implement it when I get a chance.

    Originally threw in the FreshD’s 3d parallax for each exhibit but it got a bit parallax crazy.  

    Just wanted to say thanks, and it’s a sweet tut. Have recommended it a-plenty.

    Grahame