起源
最近在開發(fā)中,需要做一個滾動加載的卡片內容的效果,發(fā)現scroll事件的一些屬性和特性械筛,記錄一下
滾動事件優(yōu)化必要性
var i = 0
window.addElementListener('scroll', () => {
console.log(i++)
}, false)
以上代碼在瀏覽器執(zhí)行,發(fā)現在滾動過程中飒炎,瀏覽器一直在執(zhí)行埋哟, 他們的觸發(fā)頻率非常的高,間隔也很近厌丑,如果在時間回調中有大量邏輯計算的話定欧,會造成瀏覽器掉幀渔呵, 為了提升用戶體驗怒竿,必須有很多優(yōu)化的必要性
scroll 事件本身會觸發(fā)頁面的重新渲染,同時scroll事件和handler扩氢,又會被高頻觸發(fā)耕驰,如果handler中有負載的操作,針對這些操作录豺,我們應該做到一些頻率控制朦肘,常用的有防抖和節(jié)流
防抖
防抖技術即是可以把多個順序地合并成一次,在一定時間完成內双饥,規(guī)定事件的觸發(fā)次數
function debounce(fn, time) {
var timer = null
var _this = this
return function(...arg) {
clearTimeout(timer)
timer = setTimeout(fn.bind(_this), time)
}
}
節(jié)流函數
防抖函數確實不錯媒抠,但是也存在問題,譬如圖片的懶加載咏花,我希望在下滑過程中圖片不斷的被加載出來趴生,而不是只有當我停止下滑時候,圖片才被加載出來昏翰。又或者下滑時候的數據的 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 觸發(fā)滾動事件 火狐開發(fā)者中心優(yōu)化方案
var ticking = false
function onScroll () {
if (!ticking) {
requestAnimationFrame(realFunc)
ticking = true
}
}
function realFunc() {
ticking = false
}
滑動過程中嘗試使用pointer-events:none 禁止鼠標事件
pointer-events 可以指定鼠標對某些失效