jQuery parallax site (on scroll) 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'))),
            a = Math.round((((o/2)+b)+m)/2);
        c.css('top', a);
    }

    // Calculate Padding
    function calcPadding() {
        var p = Math.round(($(window).width()-700)/2);
        $('.pr').css('padding-right', p);
        setWidth();
    }

    // Calculate Width
    function setWidth () {
        $('.draggable').each(function () {
            var w = 0;
            $(this).children().each(function () {
                w = w + $(this).outerWidth() + parseInt($(this).css('margin-left')) + parseInt($(this).css('margin-right'));
            });
            $(this).css('width', w);
        });
    }

    // Window Resize
    $(window).on('resize', calcPadding);

    // Initialize Functions
    calcPadding();
    setMargin();

});
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);
});