函数节流与函数防抖

  有些浏览器事件会被用户在很短的时间内触发很多次,例如点击事件或滚动页面。如果你给窗口滚动事件添加一个事件监听函数(事件句柄),然后用户不停地快速上下滚动页面,那你的事件可能在一秒之内都会被触发很多次,这会导致严重的性能问题,比如说你的页面卡住了(假死),所以我们需要降低触发回调的频率。
  下面就说一下优化这种高频执行js的方法,来提高页面速度和性能。
1.Throttling(节流 读音:丝sao丝特lin)
  预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。(设置阈值)

var canRun = true;
document.getElementById("throttle").onscroll = function(){
 if(!canRun){
 // 判断是否已空闲,如果在执行中,则直接return
 return;
 }
 canRun = false;
 setTimeout(function(){
 console.log("函数节流");
 canRun = true;
 }, 300);
};

2.Debouncing(防抖 读音:帝不囊sing)
它的做法是限制下次函数调用之前必须等待的时间间隔。

var timer = false;
document.getElementById("debounce").onscroll = function(){
 clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
 timer = setTimeout(function(){
 console.log("函数防抖");
 }, 300);
}; 

如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout清掉,重新开始。函数防抖的实现重点,就是巧用setTimeout做缓存池,而且可以轻易地清除待执行的代码。关于清除上次未执行setTimeout:
  setTimeout()函数将返回一个标识符 ID,这个 ID 是唯一的(一般是整数,从1开始,每调用一次 setTimeout() 就加1)。如果需要 setTimeout() 执行的函数或代码尚未执行,我们可以通过 clearTimeout() 函数来取消该执行操作,clearTimeout() 函数需要接收一个参数,这个参数就是 setTimeout() 函数返回的标识符ID。
  当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。把触发非常频繁的事件合并成一次执行。

throttle 应用场景

DOM 元素的拖拽功能实现(mousemove)
射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
计算鼠标移动的距离(mousemove)
Canvas 模拟画板功能(mousemove)
搜索联想(keyup)
监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次

debounce 应用场景

函数去抖有哪些应用场景?哪些时候对于连续的事件响应我们只需要执行一次回调?

每次 resize/scroll 触发统计事件
文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)

你可能感兴趣的:(浏览器工作原理)