起源
最近在开发中,需要做一个滚动加载的卡片内容的效果,发现scroll事件的一些属性和特性,记录一下
滚动事件优化必要性
var i = 0
window.addElementListener('scroll', () => {
console.log(i++)
}, false)
以上代码在浏览器执行,发现在滚动过程中,浏览器一直在执行, 他们的触发频率非常的高,间隔也很近,如果在时间回调中有大量逻辑计算的话,会造成浏览器掉帧, 为了提升用户体验,必须有很多优化的必要性
scroll 事件本身会触发页面的重新渲染,同时scroll事件和handler,又会被高频触发,如果handler中有负载的操作,针对这些操作,我们应该做到一些频率控制,常用的有防抖和节流
防抖
防抖技术即是可以把多个顺序地合并成一次,在一定时间完成内,规定事件的触发次数
function debounce(fn, time) {
var timer = null
var _this = this
return function(...arg) {
clearTimeout(timer)
timer = setTimeout(fn.bind(_this), time)
}
}
节流函数
防抖函数确实不错,但是也存在问题,譬如图片的懒加载,我希望在下滑过程中图片不断的被加载出来,而不是只有当我停止下滑时候,图片才被加载出来。又或者下滑时候的数据的 ajax 请求加载也是同理。
function throttle (func, wait, mustRun) {
var timeout
var startTime = new Date()
return function (...args) {
var context = this
var curTime = new Date()
clearTimeout(timeout)
if (curTime - startTime >= mustRun) {
func.apply(context, args)
startTime = curTime
} else {
timeout = setTimeout(func, wait)
}
}
}
使用raf 触发滚动事件 火狐开发者中心优化方案
var ticking = false
function onScroll () {
if (!ticking) {
requestAnimationFrame(realFunc)
ticking = true
}
}
function realFunc() {
ticking = false
}
滑动过程中尝试使用pointer-events:none 禁止鼠标事件
pointer-events 可以指定鼠标对某些失效