web开发中经常会做滚动监听,比如商品分类功能:左右两列,左侧类目,右侧商品,需要监听右测商品列表的滚动,滚到哪个类目区间,左侧就点亮哪个类目标签。如果在滚动的过程中一直监听而不做性能优化的话,浏览器是很容易卡死的。下面提供两种优化性能的方法:
1、防抖:在滚动过程中不执行操作,只在结束滚动一段时间内不再滚动才执行,这里的一段时间可以是500毫秒也可以是1秒,视具体业务而定。
// js防抖核心代码
function debounce (fn, delay) {
let timer = null
// 闭包
return () => {
// 如果当前正处在某个计时过程中,那么就清除此次计时开始下一次计时,
// 否则不清除,直接开始下一次计时,计时满delay毫秒后才会触发fn函数。
if (timer) {
clearTimeout(timer)
}
// 开始下一次计时
timer = setTimeout(fn, delay)
}
}
function handleScroll () {
console.log('滑动后一秒钟内不再滑动我就执行一次', Math.random())
}
window.addEventListener('scroll', debounce(handleScroll, 1000))
查看演示请狠狠地点击:js防抖demo
2、节流:如果希望即节省性能又不牺牲用户体验,就仍然在滚动中实时监听,只不过降低监听的“频率”,比如1秒才执行一次。下面提供两种实现方法(时间戳、定时器)。
// js节流核心代码
// 时间戳
function throttle1 (fn, delay) {
let prev = Date.now()
// 闭包
return () => {
let now = Date.now()
if (now - prev >= delay) {
fn()
prev = Date.now()
}
}
}
// 定时器
function throttle2 (fn, delay) {
let timer = null
// 闭包
return () => {
if (!timer) {
timer = setTimeout(() => {
fn()
timer = null
}, delay)
}
}
}
function handleScroll () {
console.log('滑动过程中我一秒钟才执行一次', Math.random())
}
window.addEventListener('scroll', throttle1(handleScroll, 1000))
// window.addEventListener('scroll', throttle2(handleScroll, 1000))
查看演示请狠狠地点击:js节流demo
网友评论