JQuery scrollTop animation changeable in chrome
I have an element. I am applying some basic transitions based on scroll position. It runs smoothly as expected in Safari and Firefox, but scrolling in Chrome is very choppy.
$(document).ready(function($) {
var divUp = $('.fade');
var divDown = $('.fade-down');
$(window).on('scroll', function() {
var st = $(this).scrollTop();
divUp.css({
'top' : -(st/6)+"px",
'opacity' : 1 - st/400
});
divDown.css({
'opacity' : 1 - st/400
});
});
});
I have commented out each property CSS
individually, but Chrome is fine. The property top
moves a relatively positioned element.
How can I achieve the desired effect while still happy with the JS JS engine? Thanks in advance for any feedback.
source to share
You are experiencing layout markup .
Changing an element's property top
invalidates the current layout. Typically this will prompt the browser to re-compute the layout asynchronously (i.e. not immediately).
However, the call scrollTop
causes the browser to reschedule synchronously . Since you call it in your scroll event handler, this happens repeatedly in a very short amount of time. This sequence of reading a DOM record is a known cause of jank .
To improve performance, you need to prevent layout splitting. Changing the CSS properties transform
(and opacity
) does not override the browser layout - they only require the composite , which is much faster.
If you animate transform: translateY
instead top
, the browser won't have to compute expensive computations on every animation frame:
divUp.css({
'transform': 'translateY( ' + (-(st/6)) + 'px)',
'opacity': 1 - st/400
});
You can help optimize your browser for navigation by setting the will-change property :
.your-div {
will-change: transform;
}
Further reading:
- Jank Free - Articles on Improving Web Application Performance
- CSS Triggers - Lists the steps that must be followed by browsers when each CSS property changes
source to share