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.

Useful? Buy me a coffeeUseful? Buy me a coffee

Ian Lunn is a Front-end Developer with 12 years commercial experience, author of CSS3 Foundations, and graduate of Internet Technology. He creates successful websites that are fast, easy to use, and built with best practices.