首先介绍函数节流与防抖的概念
函数节流:一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。 有个需要频繁触发函数,出于优化性能角度,在规定时间内,只让函数触发的第一次生效,后面不生效。
为什么要使用函数节流呢?
譬如现在我们有一个页面,这个页面从上到下拥有很多楼层,我们需要在页面滚动时监听scroll事件来动态的对比页面当前滚动高度与各个楼层在页面的位置来计算当前页面停留在哪个楼层,但是 scroll 事件的触发频率实在太高了,10ms就会触发好几次,这样高频率的计算,特别吃cpu,手机性能如果不够好的话,整个页面滑动起来可能特别卡顿。而且很明显,我们计算对当前楼层的计算频率并不需要这么高,大约 100ms 计算一次也就够用了,这时候就可以用节流函数给计算楼层的函数加100ms执行一次的节流。加如节流后计算函数100ms最多执行一次,计算频率比之前的几毫米一次低了几十倍,cpu的负荷降低,页面的性能就得到了提升。
代码示范:
function getCurrentFloor () {
// 楼层计算代码
}
// 获得节流后的计算函数
getCurrentFloor = throttle(getCurrentFloor, 100) // 文章末附节流代码
dom.addListenerEvent('scroll', getCurrentFloor, false)
复制代码
防抖函数:一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效。 防抖效果展示:
从动图右边 DevTools 的network面板可以看出,知乎在连续输入多个字符时不会为每一个字符都发出 http 请求,只会在输入停止大约 500ms 后再一次性将搜索请求发出去。这个效果就是利用函数和防抖实现的,可以让浏览器少发送很多无意义的请求,同时降低服务器的并发压力。代码示范:
function doSearch () {
// 搜索操作
}
doSearch = debounce(doSearch,500) // 返回一个500ms只会执行最后一次调用的doSearch函数
let searchInput = document.querySelector('.search-input')
searchInput.addEventListener('input', doSearch, false)
复制代码
throttle 与 deounce的实现
Performance.js
class Performance {
static instance
constructor () {
return Performance.instance || (Performance.instance = this)
}
// 节流函数
throttle (fn, time = 50) {
let nowTime
let lastTime
return function (...args) {
nowTime = +(new Date())
if (!lastTime || nowTime - lastTime >= time) {
fn.call(this, ...args)
lastTime = nowTime
}
}
}
// 防抖函数
debounce (fn, time = 50) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
timer = null
}
timer = setTimeout(fn.bind(this, ...args), time)
}
}
}
let instance = new Performance()
let { throttle, debounce } = instance
export { Performance, throttle, debounce }
复制代码
以上是jh-util类库中的 Performance 性能模块
附jh-util类库的github连接:
类库正在慢慢完善当中,如有不足还请大家多多指教
转载于:https://juejin.im/post/5d079790f265da1bca51dba5