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

jQuery parallax site (on scroll)

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

Problem

I have this code for a website I'm working on. It uses window.scroll events to parallax some items. It's running a bit slow on average machines. Is there any way I could improve it to make it run faster?

```
$(function() {

// Tell the DOM that JS is enabled
$('html').removeClass('no-js');

// Navigation Waypoints
$('.waypoint').waypoint(function(event, d) {
var a = $(this);
if (d === "up") a = a.prev();
if (!a.length) a = a.end();
$('.active').removeClass('active');
a.addClass('active');
$('a[href=#'+a.attr('id')+']').addClass('active');
}, {offset: '40%'});

// Parallax Effects
$(window).scroll(function() {
var s = $(window).scrollTop(),
b = ($('body').height()/100)*20;
$('.container').each(function () {
$(this).css('top', Math.round((($(this).closest('.waypoint').offset().top-s)+b)/$(this).attr('data-speed')));
});
$('#home hgroup').css('bottom', '-'+Math.round(s/6)+'px');
});

// FAQs
$(document).on('click', '.faqs a', function () {
$('.faqs .open').slideToggle().removeClass('open');
$(this).siblings().slideToggle('fast').addClass('open');
return false;
});

// Kinetics
$('.counter').kinetic({
y: false
});

// Smooth Scroll
$(document).on('click', 'nav a', function() {
var t = $($(this).attr('href')),
o = t.offset().top,
b = ($('body').height()/100)*10;
if($(this).attr('href') === "#home") {
$('html, body').animate({scrollTop: o}, 'slow');
} else {
$('html, body').animate({scrollTop: o+b}, 'slow');
}
return false;
});

// Set Margin
function setMargin () {
var t = $('#about'),
o = t.offset().top,
c = $('.container'),
b = ($('body').height()/100)*20,
m = Math.round(parseInt(t.css('margin-top')))

Solution

The jQuery documentation offers the best advice:


Event performance


In most cases, an event such as click occurs infrequently and performance is not a significant concern. However, high frequency events such as mousemove or scroll can fire dozens of times per second, and in those cases it becomes more important to use events judiciously. Performance can be increased by reducing the amount of work done in the handler itself, caching information needed by the handler rather than recalculating it, or by rate-limiting the number of actual page updates using setTimeout.

Obviously it would be ideal if you could move the calculations outside the event handler to reach the desired performance, but that may not be possible in this case. So to expand on the rate-limiting approach, there are 2 ways you could go about it:

-
Call event handler after the user has finished scrolling (hasn't scrolled for some set amount of time):

var timer = null;
$(window).scroll(function () {
  if (timer) {
    clearTimeout(timer);
  }

  timer = setTimeout(function() {
    timer = null;

    // your event handling logic here
  }, 50);
});


-
Call event handler immediately after scrolling, with a minimum delay between scroll events:

var justExecuted = false;
$(window).scroll(function() {
  if(justExecuted) {
    return;
  }

  // your event handling logic here

  justExecuted = true;
  setTimeout(function() {
    justExecuted = false;
  }, 50);
});

Code Snippets

var timer = null;
$(window).scroll(function () {
  if (timer) {
    clearTimeout(timer);
  }

  timer = setTimeout(function() {
    timer = null;

    // your event handling logic here
  }, 50);
});
var justExecuted = false;
$(window).scroll(function() {
  if(justExecuted) {
    return;
  }

  // your event handling logic here

  justExecuted = true;
  setTimeout(function() {
    justExecuted = false;
  }, 50);
});

Context

StackExchange Code Review Q#19610, answer score: 6

Revisions (0)

No revisions yet.