浏览器滚动优化

Reference

前言:图片懒加载、下滑加载数据、侧边浮动导航栏等常常需要监听scroll事件,或者resize事件,频繁触发repaint reflow,CPU负荷很重。

解决方法:

setTimeout

1. 防抖 Debouncing

加上setTimeout让操作延时

// 简单的防抖动函数
function debounce(func, wait, immediate) {
    // 定时器变量
    var timeout;
    return function() {
        // 每次触发 scroll handler 时先清除定时器
        clearTimeout(timeout);
        // 指定 xx ms 后触发真正想进行的操作 handler
        timeout = setTimeout(func, wait);
    };
};

// 实际想绑定在 scroll 事件上的 handler
function realFunc(){
    console.log("Success");
}

// 采用了防抖动
window.addEventListener('scroll',debounce(realFunc,500));

2. 节流 Throttling

如果想要在一定时间内被触发,要使用节流函数

节流函数:只允许并且保证一个函数在 X 毫秒内执行一次。

// 简单的节流函数
function throttle(func, wait, mustRun) {
    var timeout,
        startTime = new Date();

    return function() {
        var context = this,
            args = arguments,
            curTime = new Date();

        clearTimeout(timeout);
        // 如果达到了规定的触发时间间隔,触发 handler
        if(curTime - startTime >= mustRun){
            func.apply(context,args);
            startTime = curTime;
        // 没达到触发间隔,重新设定定时器
        }else{
            timeout = setTimeout(func, wait);
        }
    };
};
// 实际想绑定在 scroll 事件上的 handler
function realFunc(){
    console.log("Success");
}
// 采用了节流函数
window.addEventListener('scroll',throttle(realFunc,500,1000));

requestAnimationFrame

使用 requestAnimationFrame 触发滚动事件, 会在页面重绘之前调用。适用于高级浏览器和复杂的场景。

window.requestAnimationFrame(function(){
    ...whatever
})

简单来说,rAF是一个优化的定时器。可以不仅限于动画制作。被调用的频率是每秒 60 次,也就是 1000/60,触发频率大概是 16.7ms 。(当执行复杂操作时,当它发现无法维持 60fps 的频率时,它会把频率降低到 30fps 来保持帧数的稳定。)

throttle(func, xx, 1000/60)

总结

防抖动:将多次调用合并为一次(这段时间内不一定会执行)
节流函数:一定时间内只允许知行一次。
rAF:16.7ms 触发一次,降低了可控性,但是提升了性能和精确度。

优化

1.

  • 可以在外面初始化的变量就别放进来了
  • 尽量不要修改样式属性。scroll中修改会被浏览器暂存。requestAnimationFrame一开始修改样式,会强制同步布局。

2. pointer-events: none 禁止鼠标事件

添加属性后,鼠标点击和hover都将失效。可以调滚动时的帧频

猜你喜欢

转载自blog.csdn.net/jplyue/article/details/82153338