You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

视差效果实现:已用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:22:10