视差效果实现:已用requestAnimationFrame还需使用setInterval吗?
要不要在视差滚动代码中加入setInterval?
嘿,先给你吃个定心丸:完全没必要用setInterval,你现在的写法已经是更合理的方案了,甚至比加setInterval的做法更优。下面给你拆解原因:
1. 你当前代码的优势
你用scroll事件结合requestAnimationFrame的思路非常正确:
scroll事件会在页面滚动时触发,但它的触发频率很高(远超过60次/秒),而requestAnimationFrame会自动把回调安排在浏览器下一次重绘前执行,刚好匹配屏幕的刷新频率(通常60fps),既保证了动画的流畅性,又避免了不必要的重复计算。- 更重要的是,
requestAnimationFrame是浏览器原生优化的API:当页面处于后台(比如切换到其他标签页)时,它会自动暂停执行,节省系统资源;如果页面性能不足,浏览器也会自动调整执行频率,避免卡顿。
2. setInterval的问题
那些教程里提到的setInterval其实是过时且有缺陷的方案:
- setInterval是固定时间间隔执行回调,完全不管浏览器的重绘节奏。比如如果浏览器因为负载高,重绘间隔变成了100ms(10fps),但你的setInterval设为16ms(60fps),就会出现回调执行在重绘之后,导致动画滞后、卡顿。
- 如果回调函数的执行时间超过了setInterval的间隔,还会出现回调堆积的问题,进一步拖慢页面性能。
- 即使页面处于后台,setInterval也会继续运行,白白消耗CPU资源。
3. 给你的小优化建议
另外注意你代码里的一个小错误:offset().top()是错的,offset().top是属性,不是方法,不需要加括号。还有可以缓存DOM选择器,避免每次scroll事件都重新查询DOM,提升性能:
// 缓存DOM元素,避免重复查询 const $parallax = $('.parallax'); $(window).on('scroll', function() { const scrollTop = $(this).scrollTop(); const offsetTop = $parallax.offset().top; const offsetBy = Math.floor((scrollTop - offsetTop) * 0.5); // 用Math.floor替代toFixed(0)更高效 window.requestAnimationFrame(() => { $parallax.css('--parallax', `${offsetBy}px`); }); });
总结一下:坚持你现在的方案就好,setInterval在这里完全是画蛇添足,反而会带来性能问题。
内容的提问来源于stack exchange,提问作者sdvnksv
相关产品推荐
相关产品推荐

