防抖

前段时间用echarts画了个图,折线-饼图联动的,数据是从阿里云sls的api查询出来的,每5秒一个采样点,3天的数据就有5*12*60*24*3 = 259200个数据。图大概长这样。。

image.png

关键代码是一段事件函数。

this.instance.on('updateAxisPointer', (event) => {
  let xAxisInfo = event.axesInfo[0];
  if (xAxisInfo) {
    let dimension = xAxisInfo.value + 1;
    this.instance.setOption({
      series: {
        id: 'pie',
        label: {
          formatter: '{b}: ({d}%)'
        },
        encode: {
          value: dimension,
          tooltip: transferToFlow(dimension)[0] + transferToFlow(dimension)[1]
        }
      }
    });
  }
});

这个事件监听函数在用户移动鼠标的时候会频繁触发,造成页面卡顿,图也会失去响应。一开始没想到防抖的方法,通过拟合的方式精简了一部分数据,把5秒的采样间隔取到了30秒级,卡顿的情况有了一些缓解,但还是治标不治本,并且在低配机器上仍然卡死。于是这次用防抖的方式尝试再做一次优化。

// 简陋的防抖函数。。
let debounce = (fn, delay) => {
    let timer
    return (e) => {
        clearTimeout(timer)
        timer = setTimeout( () => {
            fn(e)
        }, delay)
    }
}

用了大量箭头函数免去了this指针丢失的问题。否则还得保存指针apply一次。。

防抖函数的原理在于,每次调用这个函数的时候,都将取消上一次的定时器,造成用户的行为永远也不会被触发,直到用户停止触发这个函数,timer定时器不再被清除,才会在delay时间之后执行一个动作。这样做的好处在于避免了重复触发带来的性能开销,坏处在于无限的取消用户的操作,并且能感觉到响应的迟滞。

// 加了个防抖函数,延迟200响应事件。。
this.instance.on('updateAxisPointer', debounce((event) => {
  let xAxisInfo = event.axesInfo[0];
  if (xAxisInfo) {
    let dimension = xAxisInfo.value + 1;
    this.instance.setOption({
      series: {
        id: 'pie',
        label: {
          formatter: '{b}: ({d}%)'
        },
        encode: {
          value: dimension,
          tooltip: transferToFlow(dimension)[0] + transferToFlow(dimension)[1]
        }
      }
    });
  }
},200));

效果还是立竿见影的,鼠标移动时事件触发的次数极大减少,低配机用户也没了卡顿的现象。

节流

节流我还没用过。。不过仿写了一个简单的节流函数。。节流的目的在于,不论函数触发的频率如何,都让它以固定的速度执行,因此需要记下上次执行的时间,如果已经过了threshold时间那么触发一次,并更新上一次执行的时间,否则清除计时器,并重新设定一个计时器。

// 简单的节流函数
let throttle = (fn, threshold) => {
  let last
  let timer
  return  (...args) => {
    let now = +new Date()
    if (last && now < last + threshold) {
      clearTimeout(timer)
      timer = setTimeout( () => {
        last = now
        fn(...args)
      }, threshold)
    } else {
      last = now
      fn(...args)
    }
  }
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

面试总结 Previous
算法笔记:分治法 Next