美文网首页深究JavaScript让前端飞技术文
事件处理程序过多也会导致性能问题?

事件处理程序过多也会导致性能问题?

作者: baiying | 来源:发表于2017-08-18 16:33 被阅读48次

在JavaScript中,添加到页面上的事件处理程序数量将会直接关系到页面的整体运行性能,主要有一下几方面的原因

  • 每个函数都是对象,都会占用内存,对象越多,性能越差
  • 必须实现指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间

要如何提升性能呢

  • 方案一:事件委托

事件委托利用了事件冒泡,只为一个元素(DOM树中尽量高层次的元素)指定一个事件处理程序,就可以管理某一类型的所有事件
举个例子,对于click事件,加入有多个元素都有该事件,不用事件委托我们会这么做,为每个元素逐一添加事件处理程序,当元素过多而且又不是调用同一处理函数时是非常麻烦的

//html
<body>
<div id="eles">
    <button id="btn1">1</button>
    <button id="btn2">2</button>
    <button id="btn3">3</button>
    <button id="btn4">4</button>
</div>

//JavaScript
window.onload = function () {
    var btn1 = document.getElementById('btn1');
    var btn2 = document.getElementById('btn2');
    var btn3 = document.getElementById('btn3');
    var btn4 = document.getElementById('btn4');

    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false)
            }
            else if (element.attachEvent) {
                element.attachEvent('on' + type, handler)
            }
            else {
                element['on' + type] = handler;
            }
        }
    };

    EventUtil.addHandler(btn1, 'click', handler);
    EventUtil.addHandler(btn2, 'click', handler);
    EventUtil.addHandler(btn3, 'click', handler);
    EventUtil.addHandler(btn4, 'click', handler);

};
function handler(event) {
    console.log(event.target);
}

那么,利用事件委托我们可以像下边这样做

//JavaScript
window.onload = function () {
    var eles = document.getElementById('eles');

    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false)
            }
            else if (element.attachEvent) {
                element.attachEvent('on' + type, handler)
            }
            else {
                element['on' + type] = handler;
            }
        },
        getEvent: function (event) {
            return event ? event : window.event.srcElement
        },

        getTarget: function (event) {
            return event.target || event.srcElement
        }
    };

    EventUtil.addHandler(eles, 'click', handler);

    function handler(event) {
        var event = EventUtil.getEvent(event);
        var target = EventUtil.getTarget(event);
        var eleId = target.id;
        switch (eleId) {
            case 'btn1':
                console.log('1');
                break;
            case 'btn2':
                console.log('2');
                break;
            case 'btn3':
                console.log('3');
                break;
            case 'btn4':
                console.log('4');
                break;
            default:
                console.log('err');
        }
    }
};

在这个代码中我们为四个按钮的父级元素添加了点击事件,然后在事件处理程序中再去区分是哪一个按钮,这样做的好处是我们只去了一次DOM节点,也只添加了一次处理程序,占用内存更少,速度更快

如果可行,我们也可以为document元素添加事件处理程序来处理某一类型的多个事件,在事件发生元素多次数多的情况下事件委托是非常好的选择,适合用事件委托技术的事件有click,mousedown,mouseup,keydown,keyupkeypress

总结一下事件委托的优势
  • document对象很快就可以访问,而且可以再页面生命周期的任何时间点上为它添加事件处理程序(只要可单击的元素呈现在页面上,就可以立即具备适当的功能)
  • 在页面上设置事件处理程序所需的更时间少(所需DOM引用少)
  • 整个页面占用的内存更少

方案二:移除事件处理程序

有时候我们会通过innerHtml来替换某个元素的子元素,但假如这个子元素此时绑定着一些事件处理程序呢,假如直接替换,会导致原来的子元素虽然被移走,但是事件处理程序任然与子元素保持着引用关系,这个时候我们就需要在用innerHTML移除元素之前先移除它的事件处理程序,具体方法可看移除事件处理程序

还有一种情况就是卸载页面的时候,如果在页面卸载之前没有处理干净事件处理程序,那么它们就会留在内存中,不断地跳转或者刷新页面会导致内存中滞留的对象数目越来越多,最好的做法就是在页面卸载之前通过unload事件处理程序来移除掉所有的事件处理程序,和上一个方法联系一下,假如用了事件委托来添加事件处理程序,那么在这个时候去移除所有的事件处理程序就会简单很多.

相关文章

  • 事件处理程序过多也会导致性能问题?

    在JavaScript中,添加到页面上的事件处理程序数量将会直接关系到页面的整体运行性能,主要有一下几方面的原因 ...

  • 事件委托

    事件委托对”事件处理程序过多”问题的解决方案就是事件委托,事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管...

  • DOM 事件委托

    什么是事件委托? 对"事件处理程序过多"问题的解决方案,就是需要触发子事件时,只用给某父元素指定一个事件处理程序,...

  • 事件委托

    事件委托:利用冒泡的原理,把事件加到父级上,触发执行效果。避免事件处理程序过多影响性能。 把事件绑定在父元素上,点...

  • 事件委托

    (摘自js高级教程)对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程...

  • 单例模式singleTon的几种常见写法 - Java实现

    饿汉式: 单例实现缺点: 如果构造方法存在过多的处理,会导致加载这个类很慢,可能会引起性能问题 在未调用getIn...

  • java基础之异常处理

    导语 异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的。异常处理提供了处理程序运...

  • 【javascript】事件-内存性能&模拟事件

    内存和性能 在JavaScript 中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。 导致这一问...

  • JS-杂篇-18/4/7

    XMLHttpRequest请求 内存和性能 js事件处理程序数量将直接影响页面整体运行性能 事件委托 利用冒泡特...

  • 图片设置圆角

    关于给图片设置圆角,普遍使用layer进行处理,简单方便;但过多的渲染layer会导致降低app性能,拖慢了fps...

网友评论

    本文标题:事件处理程序过多也会导致性能问题?

    本文链接:https://www.haomeiwen.com/subject/uxsarxtx.html