如何提升scroll等频繁触发事件的性能?

本文深入探讨了在Web开发中优化事件处理性能的关键技术,包括防抖(debounce)、节流(throttle)和使用requestAnimationFrame(raf)。这些技术有助于解决频繁触发事件导致的性能瓶颈,通过调整回调函数的执行频率和时机,实现更高效、流畅的用户体验。此外,文章还介绍了如何在不同浏览器环境下合理应用这些方法,并提供了示例代码和注意事项,旨在帮助开发者构建更加高效、稳定的Web应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于scroll,resize,mousemove等事件,短时间可能被频繁触发,影响性能。若回调函数中涉及到元素重绘、DOM操作等耗时工作,可能导致在下一次scroll触发前回调未完成,造成掉帧。

解决方案

(一)防抖

让函数延迟触发,若在一定时间内再次触发事件,清除计时器,重新计时

  • 适用场景:scroll停止事件,input输入keyup事件等需要在用户操作停止时触发
function debounce(before, after, wait) {
    /*option说明: before [事件触发时立即执行的函数]; 
                   after [回调函数]; 
                   wait [回调触发延迟时间ms]
    */
     var timer
     return function() {
         before && before();
         timer && clearTimeout(timer);
         timer = setTimeout(function() {
             after && after();
             timer = null;
         }, wait);
     }
 }
(二)节流

让函数在一定时间内只触发一次,周期性执行回调,减少一些过快调用

  • 适用场景:scroll事件,屏幕resize事件,mousemove事件等需要在用户操作时频繁触发,流畅性要求较高的
function throttle(after, wait) {
    /*option说明:after [回调函数]; 
                  wait  [周期性执行回调间隔时间ms]
     */
     var timer;
     var isScroll; //是否正在执行回调
     return function() {
         if (isScroll) return; //在回调函数未执行完以前
         isScroll = true;
         timer && clearTimeout(timer);
         timer = setTimeout(function() {
             after && after();
             isScroll = false;
             timer = null;
         }, wait);
     }
 }
(三)RAF利用浏览器的帧渲染

window.requestAnimationFrame:浏览器的原生功能,告诉浏览器在下一次重绘之前执行回调

  • 解决定时器导致掉帧的问题,因为定时器无法准确控制执行回调的时间
#拓展
  • 一帧:指浏览器从js执行到绘制画面的过程,动画是由一帧帧静态画面组成
  • 目前大多数浏览器渲染更新页面的标准帧率为60次/秒,即FPS为60 frame/s,相当于每帧执行时间为1000/60,约为16.7ms。高于这个数字,页面也只刷新一次,造成性能浪费;低于这个数字,30 FPS以下可能造成卡顿,维持在50~60 FPS的动画比较合适
 function rfa(after) {
 //option说明:after [回调函数,16.7ms触发一次]
     var isScroll;// RAF 触发锁
     return function() {
         if (isScroll) return;
         isScroll = true;
         requestAnimationFrame(function() {
             after && after();
             isScroll = false;
         });
     }
 }
总结
  • 定时器由于无法控制回调时间,浏览器可能进行一些复杂计算,导致延迟掉帧;
  • requestAnimationFrame方法有效利用了浏览器帧渲染频率,准确控制回调执行时间;
  • requestAnimationFrame有一定兼容问题,调用requestAnimationFrame之前需对浏览器进行能力测试,判断是否支持window.requestAnimationFrame;若不支持,用定时器代替;

请戳:demo示例(github) / demo示例(gitee)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值