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

对于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)

你可能感兴趣的:(javascript,性能优化,javascript,性能优化,防抖,节流,RAF,scroll)