性能优化-防抖(debounce)和 节流(throttle)

防抖debounce

+.监听一个输入框,文字变化后触发change事件

+.如果没有用防抖,直接用keyup事件,则会频发change事件,影响性能

+.但是采用防抖:用户输入结束或者暂停时,彩绘触发change事件

debounce 一段时间内连续的函数调用,只允许其函数执行一次。原理是,维护一个定时器,只有定时器结束才可以继续触发事件。

未封装代码代码(用于巩固理解):

let timer = null
let oInput = document.getElementById('input')
oInput.addEventListener('keyup', function(){
  if(timer){
    clearTimeout(timer)
  }
  timer = setTimeout(function(){
    console.log(oInput.value)
  }, 500)
})

 封装好的代码:

// setTimeout是过了一段事件后触发函数体
// 防抖就是说,比如当在文本框内输入内容,如果在时间没有到之前继续输入文字内容,那么最后的时间将是最后一个文字输入时间一直到结束
function debounce(fn, delay=500){
  // 给闭包使用
  let timer = null
  return function(){
    if(timer){
      clearTimeout(timer)
    }
    // 采用箭头函数,如果采用ES5的写法,则this会指向Window
    timer = setTimeout(() => {
      // 指向fn这个函数,最好能这么写,比如传了event上面那个就会报错
      fn.apply(this, arguments)
    }, delay)
  }
}

代码测试:(在一段时间(600ms)内连续触发debounce函数,但是debounce函数只会执行一次,当用户不在输入文字时,并且在输入最后一次文字等待600ms结束才会触发funtion(){console.log(oInput.value}),并且取消定时器

let oInput = document.getElementById('input')
// 要知道传进去什么,然后返回什么
oInput.addEventListener('keyup', debounce(function(){
  console.log(oInput.value)
}, 600))

节流throttle

+.拖拽一个元素时,要随时拿到该元素被拖拽的位置

+.直接用drag事件,则会频繁触发,很容用导致卡顿

+.但是使用节流,无论拖拽速度多块,都会每隔100ms触发一次

throttle:一段时间内的函数调用,保证事件一定会被执行一次。节流可以保证在一段时间内函数必定会触发一次。

未封装代码(用于巩固):

const oDiv1 = document.getElementById('div1')
let timer = null
oDiv1.addEventListener('drag', function(e){
  if(timer) {
    return false//事件停止执行并跳出函数
  }
  // timer也可以是执行的次数
  timer = setTimeout(function () {
    // console.log(timer)
    console.log(e.offsetX, e.offsetY)
    // 因为timer为null,这个定时器才能持续运行
    timer = null// 因为是null,所以继续执行这个计时器
  }, 500)// 500秒后执行函数体,此时timer有值了,如果此时停止滑动,则执行判断语句
})

封装后的代码:

// 节流就是说,在触发时候是没有的,只有规定的时间内才触发事件,然后想要触发时候触再进入到这个函数体
function throttle(fn, delay=100){
  let timer = null
  return function(){
    // let _this = this
    // let arg = arguments
    if(timer){
      return false
    }
    timer = setTimeout(() => {//要采用箭头函数,采用ES5写法则this会指向window
      fn.apply(this, arguments)
      timer = null
    }, delay)
  }
}


// test
const oDiv1 = document.getElementById('div1')
oDiv1.addEventListener('drag', throttle(function (e) {
  console.log(e.offsetX, e.offsetY)
},1000))

测试

当在拖拽的时候,第一个100ms内是不会执行的的,到了100ms时候,执行上面箭头函数体一次,然后因为函数体的timer=null跳出return的函数体,最后重复下一个100ms的动作。

const oDiv1 = document.getElementById('div1')
oDiv1.addEventListener('drag', throttle(function (e) {
  console.log(e.offsetX, e.offsetY)
}, 100))

防抖的典型案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。

节流的典型案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。

你可能感兴趣的:(性能优化,javascript)