web前端常见问题1【防抖与节流】

什么是防抖&节流
防抖和节流是前端开发中常用的两种性能优化技术。

防抖:在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。

节流: n 秒内只执行一次事件,即使n 秒内事件重复触发,也只有一次生效。

两者的区别:防抖是一段时间内只执行最后一次,节流是一段时间内只执行一次

通俗理解:节流是第一个说了算,后续都会被节流阀屏蔽掉,防抖是最后一个说了算,前面启用的都会被清除

 

防抖的应用

防抖函数的时间段,就相当于给用户的操控时间。

防抖的主要应用场景是优化搜索框的输入,用户在不断输入值时,用防抖来节约请求资源,当用户最后一次输入完,再发送请求。

在表单中输入内容,键盘弹起时就会触发keyup事件,发送请求去查询内容,这样频繁的触发事件发送请求会增加性能消耗,

同时也会增加服务器的压力,并且实际应用中,只需用户最后一次输入完,再发送请求,于是我们可以使用防抖进行优化。

应用于表单元素的校验,如手机号,邮箱,用户名等,部分搜索功能的模糊查询结果实现。

<input type="text">
<script>
  // 防抖 事件触发 n 秒后执行一次, 如果在 n 秒内重复触发则重新计算函数执行时间
  function debounce(func, interval) {
    // 设置标识符
    let timer = null;
    return function () {
      // 判断定时器是否存在,清除定时器
      timer && clearTimeout(timer)
      // 重新调用setTimeout
      timer = setTimeout(() =>  {
        func.apply(this, arguments)
        timer = null;
      }, interval)
    }
  }
  let input = document.querySelector('input');
  let inputValue = debounce(inputChange, 1000)
  function inputChange(e) {
    console.log(e.target.value)
  }
  input.addEventListener('keyup', inputValue)
</script>

 

节流的应用

在事件触发后的规定时间段内,无法再调用目标函数。

节流的主要应用场景是优化滚动事件,当用户滚动页面时,会频繁触发滚动事件,使用节流可以控制滚动事件的触发频率,避免过多的计算和渲染操作,提高页面的性能和流畅度。

有些场景下需要去计算判断滚动条的位置,比如是否加载更多,当我们滚动浏览器的滚动条时,会频繁触发scroll事件,造成频繁的判断滚动条位置,可以利用节流进行优化。

利用节流,可以按一定时间的频率来计算判断滚动条位置,然后决定是否加载更多,这样就能减少浏览器性能的消耗。

 1 // 时间戳方式
 2 // 节流 事件连续触发在n秒内只触发一次
 3 function throttle(func, interval) {
 4   // last为上一次触发回调的时间
 5   let last = 0;
 6   // 将throttle处理结果当作函数返回
 7   return function() {
 8     // 保留调用时的this上下文
 9     let context = this;
10     // 保留调用时传入的参数
11     let args = arguments;
12     // 记录本次触发回调的时间
13     let now = Date.now();
14     // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
15     if (now - last >= interval) {
16       // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
17       last = now
18       func.apply(this, args);
19     }
20   }
21 }
// 定时器方式
function throttle1(func, interval) {
  let sign = true;
  return function() {
    // 在函数开头判断标志是否为 true,不为 true 则中断函数
    if (!sign) return;
    //  sign 设置为 false,防止执行之前再被执行
    sign = false;
    setTimeout(() => {
      func.apply(this, arguments)
      // 执行完事件之后,重新将这个标志设置为 true
      sign = true;
    }, interval)
  }
}
 box.addEventListener('mousemove', throttle(function(e){
    console.log(e.pageX)
  }, 2000))

 

posted @ 2024-04-02 09:06  我家有只喵  阅读(16)  评论(0编辑  收藏  举报