I have a simple script on my site that adds a css class to the navigation bar after the user has started to scroll, and removes it when they are back at the top of the page.

However, this is causing a significant amount of jank (fps lag), and it 100% is not worth the performance hit.

Is there a way to optimise this or to make it work without causing jank?

```
$(window).scroll(function() {    
    var scroll = $(window).scrollTop();
    var navbar = $('#navbar');

    if (scroll >= 40) {
        navbar.addClass("navbar-border");
    } else {
        navbar.removeClass("navbar-border");
    }
});

```

If not, I'll remove it.

Thanks!
['https://Stackoverflow.com/questions/36536657', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2484643/']
You code is accessing the DOM potentially 100 times per second, which is the reason for your performance issue, to improve performance you can throttle the scroll event so that it executes your code less by using a Timeout that first unbinds the Scroll event then binds it after a delay(threshold), increasing the threshold will cause the code to execute less often.

```
var navbar = $('#navbar-border');
var threshold = 100; // in milliseconds

function borderControl() {
  console.log("run");
  var scroll = $(window).scrollTop();
  if (scroll >= 40) {
    navbar.addClass("navbar-border");
  } else {
    navbar.removeClass("navbar-border");
  }
}

function setScrollTimer() {
  unbindScroll();
  scrollTimer = window.setTimeout(function() {
    bindScroll()
  }, threshold);
}

function unbindScroll() {
  $(window).unbind("scroll");
}

function bindScroll() {
  $(window).scroll(function(e) {
    setScrollTimer();
    borderControl();
  });
}
bindScroll();

```

<https://jsfiddle.net/sjmcpherson/Lugrukwm/>
You could cache the results of processing to process less often by storing results in global variables or at least variables that persist outside the scroll callback.

There is so little in the callback to begin with that we don't have much room for improvement. 

```
var navbar = $('#navbar');
var navborder = false;
$(window).scroll(function() {    
    var scroll = $(window).scrollTop();

    if (!navborder && scroll >= 40) {
      navborder = true;
      navbar.addClass("navbar-border");
    } else if(navborder && scroll < 40) {
      navborder = false;
      navbar.removeClass("navbar-border");
    }
});

```

<http://codepen.io/t3hpwninat0r/pen/yOvaGN>

Alternatively you could disable the scroll position checking, and then set a timer to re-enable it after a short delay

```
var scrollTimer = 0;
$(window).scroll(function() {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(function() {
      var scroll = $(window).scrollTop();
      var navbar = $('#navbar');

      if (scroll >= 40) {
        navbar.addClass("navbar-border");
      } else {
        navbar.removeClass("navbar-border");
      }
    }, 100);
});

```

<http://codepen.io/t3hpwninat0r/pen/BKYLMb>

If the user keeps scrolling, the timer keeps restarting, and the function will only run when the 100ms timer is complete. This example adds only 4 lines to your code without any other changes.

I took (read: plagiarised) the code from this answer: <https://stackoverflow.com/a/14092859/1160540>