zoukankan      html  css  js  c++  java
  • 性能优化——防抖和节流

    性能优化——防抖和节流

    前言

    连续触发的事件中,事件处理函数的频繁调用会加重浏览器或服务器的性能负担导致用户体验糟糕,有哪些连续触发的事件呢 ?

    比如,浏览器滚动条的滚动事件、浏览器窗口调节的resize事件、输入框内容校验以及在移动端的touchmove事件等

    <div id="content"></div>
    <script>
        let num = 1;
        let content = document.getElementById('content');
        function count() {
            content.innerHTML = num++;
        };
        content.onmousemove = count;
    </script>
    

    img

    所以,我们将采用防抖函数(debounce )和节流函数(throttle)来限制事件处理函数的调用频率

    一、防抖(debounce)

    防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了该事件,则会重新计算函数执行时间

    img

    <div class="container">0</div>
    
    let box = document.querySelector(".container");
    function handleMousemove() {
    	box.innerText++;
    }
    let action = debounce(handleMousemove);
    box.addEventListener("mousemove", action);
    
    //防抖函数
      function debounce(fn, wait = 500, immediate = true) {
        //2.设置时间戳,使用setTimeout让返回函数延迟执行
        let timer, result;
        //1.直接返回传入的函数,并将返回函数的this绑定为使用位置的this
        return function (...args) {
          //3.timer存在时,将定时器中函数清除
          if (timer) {
            clearTimeout(timer);
          }
          if (immediate) {
            //4.1 立即执行返回函数
            if (!timer) {
              result = fn.apply(this, args);
            }
            timer = setTimeout(() => {
              timer = null;
            }, wait);
          } else {
            //4.2 非立即执行返回函数
            timer = setTimeout(() => {
              fn.apply(this, args);
            }, wait);
          }
          //5.立即执行时返回函数的返回值
          return result;
        };
      }
    

    img

    原理解析:

    1. 防抖函数作用,对传入的函数进行延时包装后返回
    2. setTimeout在前一次未执行完前,第二次次触发将会覆盖掉前面的定时器,执行第二次的功能
    3. 前一次由于异步加延时还未执行完,使用clearTimeout清除前面定时器,取消上次的fn功能
    4. 为保持fn内部this的指向,使用apply改变this指向
    5. fn传入为函数,不是函数的调用
     function debounce(fn, wait = 500, immediate = true) {
        let timer, result;
        return function (...args) {
          if (timer) {
            clearTimeout(timer);
          }
          if (immediate) {
            if (!timer) {
              result = fn.apply(this, args);
            }
            timer = setTimeout(() => {
              timer = null;
            }, wait);
          } else {
            timer = setTimeout(() => {
              fn.apply(this, args);
            }, wait);
          }
          return result;
        };
      }
    

    二、节流(throttle)

    节流, 指连续触发事件但是在 n 秒中只执行一次函数。

    • 节流会稀释函数的执行频率
    • 在持续触发事件的过程中,函数会立即执行,并且每n秒执行一次
    img
    <div class="container">0</div>
    
    let box = document.querySelector(".container");
    function handleMousemove() {
    	box.innerText++;
    }
    let action = throttle(handleMousemove);
    box.addEventListener("mousemove", action);
    
    //节流函数
    function throttle(fn, wait = 1000) {
          let timer;
          return function (...args) {
            if (!timer) {
              timer = setTimeout(() => {
                fn.apply(this, args);
                timer = null;
                //到达指定时间将定时器清除,让其能够再次进入执行fn
              }, wait);
            }
          };
          }
    

    img

    参考文章

    https://www.bilibili.com/video/BV1F4411h75s?t=6

    https://www.jianshu.com/p/c8b86b09daf0

  • 相关阅读:
    8_python连接数据库
    7_数据类型
    Memcached delete 命令
    Memcached gets 命令
    Memcached get 命令
    Memcached CAS 命令
    Memcached prepend 命令
    Memcached append 命令
    Memcached replace 命令
    Memcached add 命令
  • 原文地址:https://www.cnblogs.com/zengbin13/p/12903001.html
Copyright © 2011-2022 走看看