window resize和scroll事件性能优化

简介: window resize和scroll事件性能优化

只要用户改变窗口大小,会对内部一些元素大小重新计算,可能导致整个页面重新渲染,最终导致大量消耗 CPU。比如调用 resize 方法,用户改变窗口大小时会不停的被触发, 低版本的IE 会可能陷入假死状态。window的scroll事件也是如此,鼠标滚动或拖动滚动条,就会不停的触发scroll事件,如果处理的东西多,低版本的IE也会陷入假死状态。

基本的优化思路:在一定的时间之内,只执行一次resize事件函数,建议使用requestAnimationFrame(https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame), setTimeout 或者 customEvent(https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent), 比如:


requestAnimationFrame


var optimizedResize = (function() {
    var callbacks = [],
        running = false;
    // fired on resize event
    function resize() {
        if (!running) {
            running = true;
            if (window.requestAnimationFrame) {
                window.requestAnimationFrame(runCallbacks);
            } else {
                setTimeout(runCallbacks, 66);
            }
        }
    }
    // run the actual callbacks
    function runCallbacks() {
        callbacks.forEach(function(callback) {
            callback();
        });
        running = false;
    }
    // adds callback to loop
    function addCallback(callback) {
        if (callback) {
            callbacks.push(callback);
        }
    }
    return {
        // public method to add additional callback
        add: function(callback) {
            if (!callbacks.length) {
                window.addEventListener('resize', resize);
            }
            addCallback(callback);
        }
    }
}());
// start process
optimizedResize.add(function() {
    console.log('Resource conscious resize callback!')
});

setTimeout

(function() {
  window.addEventListener("resize", resizeThrottler, false);
  var resizeTimeout;
  function resizeThrottler() {
    // ignore resize events as long as an actualResizeHandler execution is in the queue
    if ( !resizeTimeout ) {
      resizeTimeout = setTimeout(function() {
        resizeTimeout = null;
        actualResizeHandler();
       // The actualResizeHandler will execute at a rate of 15fps
       }, 66);
    }
  }
  function actualResizeHandler() {
    // handle the resize event
    ...
  }
}());

requestAnimationFrame + customEvent

;(function() {
    var throttle = function(type, name, obj) {
        obj = obj || window;
        var running = false;
        var func = function() {
            if (running) { return; }
            running = true;
             requestAnimationFrame(function() {
                obj.dispatchEvent(new CustomEvent(name));
                running = false;
            });
        };
        obj.addEventListener(type, func);
    };
    /* init - you can init any event */
    throttle("resize", "optimizedResize");
})();
// handle event
window.addEventListener("optimizedResize", function() {
    console.log("Resource conscious resize callback!");
});

scroll事件优化同理。

效果如图:

1f3a8c336a51b69795fab6601531572f_640_wx_fmt=gif&wxfrom=5&wx_lazy=1.gif


目录
相关文章
|
7月前
|
监控 JavaScript
vue中监控元素大小变化element-resize-detector
vue中监控元素大小变化element-resize-detector
448 0
window.scrollTop 不生效的原因,如何解决
window.scrollTop 不生效的原因,如何解决
574 0
给 element-plus 增加一个防抖的功能(二)
element-plus 功能非常强大,但是好像只有 el-autocomplete 提供了一个防抖功能,其他表单子控件并没有提供防抖功能,而 el-autocomplete 的防抖和我想要的效果又不太一样,所以只好写个函数实现我想要的防抖效果。
关于监听window.top的滑动,Iframe嵌套
关于监听window.top的滑动,Iframe嵌套
window.addEventListener注册滚动scroll事件不生效
window.addEventListener注册滚动scroll事件不生效
|
JavaScript UED
解决 Element-ui中 选择器(Select)因options 数据量大导致渲染慢、页面卡顿的问题
解决 Element-ui中 选择器(Select)因options 数据量大导致渲染慢、页面卡顿的问题
3712 0
解决 Element-ui中 选择器(Select)因options 数据量大导致渲染慢、页面卡顿的问题
|
JavaScript API
给 element-plus 增加一个防抖的功能(一)
element-plus 功能非常强大,但是好像只有 el-autocomplete 提供了一个防抖功能,其他表单子控件并没有提供防抖功能,而 el-autocomplete 的防抖和我想要的效果又不太一样,所以只好写个函数实现我想要的防抖效果。
|
JavaScript 容器
Element UI - v-infinite-scroll无限滚动组件
Element UI - v-infinite-scroll无限滚动组件
830 0
|
JavaScript
vue 里 onresize 事件被覆盖,以及怎么实现 resize 防抖、移除 resize 事件?
vue 里 onresize 事件被覆盖,以及怎么实现 resize 防抖、移除 resize 事件?
503 0
为什么会有window.window这种设计
为啥要搞这个这个看起来貌似很奇葩的设计。 要解答这个问题,还得请出this,我们经常说浏览器中的全局对象是window, 这句话对了,也还没完全对。 全局对象的真实身份应该是全局作用域的this。 window只是为了便于访问this,弄出来的一个属性。
316 0
为什么会有window.window这种设计