HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

JavaScript parallax cross-platform efficiency

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
platformjavascriptcrossparallaxefficiency

Problem

I wanted to get some feedback on this JS I am working on. It works wonderfully on my desktop, but on my and my friends' laptops (especially Safari) it is very slow. I need some pointers on improving the efficiency so it works nicely across browsers/computers.

http://www.dapper-apps.com

```
// If jQuery was not loaded, offload it.
if (!typeof jQuery) {
document.write(unescape("%3Cscript src='/resources/jquery-2.1.0.min.js' type='text/javascript'%3E%3C/script%3E"));
}

/*
* Called when the DOM has been loaded.
* Create all parallaxElements with their respective properties, pool them
* in an array and begin the parallax animations.
*/
$(document).ready(function () {
var kami = new ParallaxElement("#kami", 1, 1, $("#parallaxcanvas").width(), $("#parallaxcanvas").height(), 1);
var mainrock = new ParallaxElement("#mainrock", .25, .25, 75, 25, 1);
var bgrock1 = new ParallaxElement("#bgrock1", .12, .12, 75, 75, 1);
var bgrock2 = new ParallaxElement("#bgrock2", .06, .06, 75, 75, 1);
var bgrock3 = new ParallaxElement("#bgrock3", .03, .03, 75, 75, 1);

var parallaxElements = [ kami, mainrock, bgrock1, bgrock2, bgrock3];

Parallax("#parallaxcanvas", parallaxElements);
});

/*
* jstr - The css identifier of the parallax element(s).
* xStep - The amount to move, every update, along the x.
* yStep - The amount to move, every update, along the y.
* xRange - The range this element is allowed to move along the x.
* yRange - The range this element is allowed to move along the y.
* update - How often to update this element's position in milliseconds.
*/
function ParallaxElement(jstr, xStep, yStep, xRange, yRange, update) {
var init_pos = $(jstr).position();
var followPos = { left: init_pos.left, top: init_pos.top };
var moveInterval;
var minX = init_pos.left - xRange;
var maxX = init_pos.left + xRange;
var minY = init_pos.top - yRange;
var maxY = init_pos.top + yRange;
/*
* Gets called every update millis

Solution

The one millisecond movement timer is extremely low. With 10 ms, you'll still provide a fluent movement, and the browser actually gets time to finish before the next tick is started. Even 5ms will do, but 1 seems overkill.

To get the same step movement and be able to tweak the update timer, you could put the following in the init of ParallaxElement:

xStep *= update;
yStep *= update;


Although that might get further outside of the intended bounds for larger updates.

A small gain can be obtained by using a direct variable to the element inside a ParallaxElement. Each time $ is used, a lookup is started. Since you did use an id, (so getelementbyid is used), the lookup is plenty fast, but no lookup at all is faster. Since the lookup is done so much (multiple times per element per tick), the difference could be notable.

function ParallaxElement(jstr, xStep, yStep, xRange, yRange, update) {
    var element = $(jstr); //refer directly to the element
    var init_pos = element.position(); //replace the $(jstr) references with the direct variable
    //...
    //var curPos = element.position();
    //element.css({ "left": curPos.left, "top": curPos.top });
    //etc.


Minor issue, the first call to UpdateFollow is moot, because x and y are set after the call. x1 and y1 could be used instead parallaxElements[i].UpdateFollow(x1, y1);

Some minor tweaks, such as moving the range checking, could be done, but that would all be small potatoes compared to changing the interval of 1ms. A lot can be done as well with the jquery animate functionality, if you're not happy with the look and feel if the interval is upped.

Code Snippets

xStep *= update;
yStep *= update;
function ParallaxElement(jstr, xStep, yStep, xRange, yRange, update) {
    var element = $(jstr); //refer directly to the element
    var init_pos = element.position(); //replace the $(jstr) references with the direct variable
    //...
    //var curPos = element.position();
    //element.css({ "left": curPos.left, "top": curPos.top });
    //etc.

Context

StackExchange Code Review Q#49437, answer score: 4

Revisions (0)

No revisions yet.