requestAnimationFrame eats CPU in Firefox
-
20-06-2021 - |
题
So, I'm using Paul Irish's requestAnimationFrame to make a sidebar "sticky" on the page. I've found in at least webkit browsers this lends a vast performance improvement over other solutions like Waypoints. However, I've noticed on Firefox that when I start to scroll the page CPU goes through the roof and the page is immensely slow due to this. Am I implementing this wrong, or will I need to use another method for Firefox?
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
window.widget_is_sticky = false;
window.widget_is_locked = false;
$(function(){
(function animloop() {
requestAnimationFrame(animloop);
if (adjust_networth) {
if (self.pageYOffset) {
yScroll = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop) {
yScroll = document.documentElement.scrollTop;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
}
update_networth_position(yScroll);
}
})();
});
// Separate file written in CoffeeScript
window.update_networth_position = ( offset ) ->
if offset >= 259
if !window.widget_is_sticky
window.widget_is_sticky = true
$('.widgets').addClass 'sticky'
else if !window.widget_is_locked and widget_is_at_boundary(offset)
window.widget_is_locked = true
$('.widgets').addClass 'locked'
else if !widget_is_at_boundary(offset) and window.widget_is_locked
window.widget_is_locked = false
$('.widgets').removeClass 'locked'
else
return false if !window.widget_is_sticky
$('.widgets').removeClass 'sticky'
window.widget_is_sticky = false
widget_is_at_boundary = ( offset ) ->
offset = offset - $('section.top-section').outerHeight(true)
maximum_height = $('section.main-content div.content:first-child').outerHeight(true)
widget_height = $('section.main-content .widgets').outerHeight(true)
if (offset + widget_height) > maximum_height
return true
else
return false
Any help is greatly greatly appreciated! I am also open to completely different solutions for how to approach this (but Waypoints wasn't performant enough to work nicely).
解决方案
Sorry about this, false alarm. Turns out the performance hit is coming from a background css technique I was using. requestAnimationFrame is safe this time :)