-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Description
前言
前端开发最注重的就是用户体验。但是用户往往在交互过程中体验到卡顿,那么就会很不愉快。
举几个例子:
- 当我们在window对象上注册了
scroll事件,当我们轻轻拨动一下鼠标滚轮,会触发12次scroll事件处理器(在chrome浏览器上的测试数据),而如果我们在事件处理器里面占用了过多cpu,就会阻塞页面的渲染,也就是常说的页面卡顿。 - 不仅是
scroll事件还有拖拽事件,也会有类似的情况 - 还有表单提交事件,跟上面两个情况不同的是,表单提交一般会涉及异步网络请求,当用户_手抖_多点了两次提交,那么就会请求两次服务器,一来增加服务器负担,而来也会因为要多执行几次回调而增加浏览器渲染页面的负担。
没办法,JavaScript就是单线程,我们得入乡随俗。解决方案是千千万的,但是这里仅提到其中的两种。
防抖(debounce)
概念:事件回调必须在事件发生的若干时间之后才会被执行。如果发生多个事件,则以最后一个事件为准。
实现方式:
闭包 + 异步回调模块,通用模板如下
export function debounce(interval, callback) {
var timeout
return () => {
timeout && clearTimeout(timeout)
timeout = setTimeout(() => {
callback && callback()
}, interval)
}
}
通过简单修改,也可以变为仅触发第一次事件,若干时间间隔内不会再触发:
export function debounce(interval, callback) {
var timeout, shouldRun = true
return () => {
if (!shouldRun) return
shouldRun = false
callback && callback()
timeout = setTimeout(() => {
shouldRun = true
}, interval)
}
}
这也就是节流的另一种写法。
节流(throttle)
概念:两个事件回调的执行之间有个最小间隔,换句话说,前面的事件回调执行完了之后,后面的事件回调会在最小间隔时间之后才能被执行。
实现方式:
闭包 + 异步回调模块,通用模板如下:
export function throttle(interval, callback) {
var shouldRun = true
return () => {
shouldRun && callback && callback()
shouldRun = false
setTimeout(() => {
shouldRun = true
}, interval)
}
}
节流和防抖结合
function throttle(fn, delay) {
let last = 0, timer = null;
return function () {
let now = +new Date();
if (now - last < delay) {
clearTimeout(tiemr);
timer = setTimeout(fn, delay);
} else {
last = now;
clearTimeout(tiemr);
fn();
}
}
}
参考:
轻松理解JS函数节流和函数防抖
JavaScript专题之跟着underscore学防抖
JavaScript专题之跟着 underscore 学节流
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels