debounce(防抖)和throttle(节流)

防抖和节流

窗口的resizescroll,输入框内容校验等操做时,若是这些操做处理函数较为复杂或页面频繁重渲染等操做时,若是事件触发的频率无限制,会加剧浏览器的负担,致使用户体验很是糟糕。此时咱们能够采用debounce(防抖)和throttle(节流)的方式来减小触发的频率,同时又不影响实际效果。javascript

debounce 防抖

debounce(防抖),简单来讲就是防止抖动。html

debounce 防抖

从上图中咱们能够看到,当持续触发事件时,debounce会合并事件且不会去触发事件,当必定时间内没有触发再这个事件时,才真正去触发事件~ 一块儿来实现个简单的debounce:java

function debounce(fn, delay) {
  var ctx;
  var args;
  var timer = null;

  var later = function () {
    fn.apply(ctx, args);
    // 当事件真正执行后,清空定时器
    timer = null;
  };

  return function () {
    ctx = this;
    args = arguments;
    // 当持续触发事件时,若发现事件触发的定时器已设置时,则清除以前的定时器
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    // 从新设置事件触发的定时器
    timer = setTimeout(later, delay);
  };
}

效果图:git

sample debounce

throttle 节流

throttle(节流),当持续触发事件时,保证隔间时间触发一次事件。github

throttle 节流

上图中绿色块表示触发一次事件,持续触发事件时,throttle会合并必定时间内的事件,并在该时间结束时真正去触发一次事件~ 一块儿来看看throttle的简单实现:浏览器

function throttle(fn, delay) {
  var ctx;
  var args;
  // 记录上次触发事件
  var previous = Date.now();

  var later = function () {
    fn.apply(ctx, args);
  };

  return function () {
    ctx = this;
    args = arguments;
    var now = Date.now();
    // 本次事件触发与上一次的时间比较
    var diff = now - previous - delay;

    // 若是隔间时间超过设定时间,即再次设置事件触发的定时器
    if (diff >= 0) {
      // 更新最近事件触发的时间
      previous = now;
      setTimeout(later, delay);
    }
  };
}

效果图:闭包

sample throttle

总结

根据实际业务场景,合理的利用debounce(防抖)和throttle(节流)能够优化性能和提升用户体验。二者间的核心区别就在于持续触发事件时,前者合并事件并在最后时间去触发事件,然后者则是隔间时间触发一次~app

关键知识点

setTimeout 定时器less

w3school函数

Closure 闭包

ruanyifeng

资源

在线测试

源代码

相关文章
相关标签/搜索