性能优化的知识

共同点:降频( 降低函数的调用 )

场景:

一个功能本身就是要限制被调用的次数。例如用户请求登陆的次数不能太频繁。

一个功能没有必须被频繁调用。

防抖(debounce)

某个时间内不能再次触发,一旦触发,就要重新计时。在这个时间内没有被再次调用,才会真正的执行,

如果一直按,就会一直重新计时

防抖函数分为非立即执行版和立即执行版

简单写法:

hInput () {
      clearTimeout(this.timer)
      console.log(this.keyword)
      this.timer = setTimeout(() => {
        this.doAjax()
      }, 200)
    },
     doAjax () {
      xxxx
    },

立即执行

点击按钮,函数f1调用后,立即执行f()。随后,每次点击都不会调用f(),并且会从新开始计时

<button id="btn_debounce_now">防抖3s,立即执行</button>
<script>
  function debounce_callnow(f, t = 3000) {
    var time = null

    return function () {
      if (!time) {
        //如果time是空的话,就直接执行
        f()
      } else {
        console.log('不要着急,等3s后再点才有效')
      }
      clearTimeout(time)

      //每次点击后,过三秒钟才会清一次time
      time = setTimeout(() => {
        time = null //清空time
      }, t)
    }
  }
  function f() {
    console.log(Date.now())
  }
  var f1 = debounce_callnow(f)

  document.getElementById('btn_debounce_now').onclick = f1
</script>

android防止防抖_android防止防抖

android防止防抖_延迟执行_02

非立即执行版本

以下代码每次点击完要等一秒才能看到结果,在一秒以内每次点击都会从新开启定时器

<button type="primary" id="btn_debounce_end">防抖1s,延迟执行</button>
<script>
  function debounce_end(f, t = 1000) {
    let time = null
    return () => {
      if (time) {
        //如果存在time 就会清空定时器,从新开始
        clearTimeout(time)
        console.log('1s以后看结果')
      }
      time = setTimeout(() => {
        f()
      }, t)
    }
  }
  function f() {
    console.log(Date.now())
  }
  var f1 = debounce_end(f)
  document.getElementById('btn_debounce_end').onclick = f1
</script>

混合版本

在立即执行版本的基础上,定时器结束以后再执行一次f()

<button id="btn_debounce_now">防抖3s,立即执行</button>
<script>
  var time = null
  function debounce_callnow(f, t = 3000) {
    return function () {
      if (!time) {
        //如果time是空的话,就直接执行
        f()
      } else {
        console.log('不要着急,等3s后再点才有效')
      }
      clearTimeout(time)

      //每次点击后,过三秒钟才会清一次time
      time = setTimeout(() => {
        time = null //清空time
        f() //t秒以后再执行一次
      }, t)
    }
  }
  function f() {
    console.log(Date.now())
  }
  var f1 = debounce_callnow(f)

  document.getElementById('btn_debounce_now').onclick = f1
</script>

节流 (throttle)

限制 函数两次调用的时间间隔,他们的时间间隔是固定的 ;比如间隔3秒钟才能执行,那么这三秒内不管触发了多少次该事件,函数都只执行一次

简单写法:

data() {
    return {
            timer: null,
      startTime: 0, // 最近一次成功调用ajax的时间
    }
},

hInput {
    const dt = Date.now()
  if (dt - this.startTime > 500) {
        this.doAjax()
        this.startTime = dt
      } else {
        console.log('当前的时间戳是', dt, '距离上一次执行不够500ms,所以不执行')
      }
    },
  doAjax()
}

中级写法:

立即执行版 ——>点击按钮时,会立即执行f ,但是不论点的有多块,都间隔1s执行一次

<button id="btn_throttle_now">节流1s,立即执行</button>
<script>
  var time = 0
  function throttle_now(f, t = 1000) {
    return () => {
      var now = Date.now() //获取当前时间戳
      if (now - time >= t) {
        // 如果间隔时间大于t,就可以执行f
        f()
        time = Date.now()
      } else {
        console.log('必须超过1秒')
      }
    }
  }

  function f() {
    console.log(Date.now())
  }
  var f1 = throttle_now(f)
  document.getElementById('btn_throttle_now').onclick = f1
</script>

android防止防抖_android防止防抖_03

非立即执行版 ——>点击按钮时,等一秒以后会执行一次f;但后续不论点的有多块,都间隔1s执行一次

<button id="btn_throttle_end">节流1s,延迟执行</button>
<script>
  function throttle_end(f, t = 1000) {
    let time = null
    return () => {
      if (!time) {//如果time不是null,就不能执行f
        time = setTimeout(() => {  //每间隔1s,将time设置为null
          f()
          time = null  
        }, t)
      } else {
        console.log('请等一秒钟')
      }
    }
  }

  function f() {
    console.log(Date.now())
  }
  var f1 = throttle_end(f)
  document.getElementById('btn_throttle_end').onclick = f1
</script>

android防止防抖_javascript_04

混合版

第一次点击按钮,会立即执行f。如果在3s内再次点击,则会开启一个三秒后执行的定时器。

<button id="btn_throttle_now">节流3s,立即执行</button>
<script>
  function throttle_callnow(f, t = 3000) {
    let timer = null
    let preTime = 0
    return function () {
      var now = Date.now()
      clearTimeout(timer) //如果3s内再次点击,就会先清除上一次点击的定时器
      if (now - preTime >= t) {
        f() //立即先执行一次
        preTime = now
      } else {
        console.log('间隔不足,开始定时器')
        // 如果间隔不足,才会开启这个定时器
        timer = setTimeout(() => {
          f() //如果三秒内没有再次点击,就会执行f。如果再次点击,就会清除这个定时器
        }, t)
      }
    }
  }

  function f() {
    console.log(Date.now())
  }
  var f1 = throttle_callnow(f)

  document.getElementById('btn_throttle_now').onclick = f1
</script>

android防止防抖_javascript_05