1. 程式人生 > >JavaScript效能優化方案(事件委託詳解)

JavaScript效能優化方案(事件委託詳解)

事件處理程式過多導致效能下降

在 JavaScript 中,新增到頁面上的事件處理程式數量會直接關係到頁面的整體執行效能。導致這一問題的原因是多方面的。首先,每個函式都是物件,都會佔用記憶體;記憶體中物件越多,效能就越差。其次,必須事先指定所有事件處理程式所造成的 DOM 訪問次數,也會延遲整個頁面的互動就緒時間。
在事件處理程式角度來提升效能主要有兩張方式:事件委託、及時移除事件處理程式。


事件委託

事件委託專門用來避免事件處理程式過多的情況。事件委託利用了事件冒泡,只指定一個事件處理程式,就能處理同一型別的所有事件。
例如,click 事件會一直冒泡到 document 層次。也就是說,我們可以為整個頁面指定一個 onclick 事件處理程式,而不需要給每個可單機元素都繫結事件處理程式。

    <ul id="myLinks">
        <li id="goSomewhere">Go somewhere</li>
        <li id="doSomething">Do something</li>
        <li id="sayHi">Say Hi</li>
    </ul>

例如上面這個 HTML ,如果我們要給這三個 <li> 元素新增 onclick 事件處理程式,按照常規的做法,是分別新增。但是如果頁面中存在很多可單機元素,造成的結果是有大量的程式碼用來新增事件處理程式,效能就會下降。

此時我們可以通過事件委託技術來解決這個問題。使用事件委託,只需要在 DOM 樹中儘量最高的層次上新增一個事件處理程式,如下:


EventUtil.addHandler(window, 'load', function(event) {
    var list = document.getElementById('myLinks');

    EventUtil.addHandler(list, 'click', function(event) {
        event = EventUtil.getEvent(event);
        var target = EventUtil.
getTarget(event); switch (target.id) { case "doSomething": document.title = "I change the title!"; break; case "goSomewhere": location.href = "http://www.baidu.com"; break; case "sayHi": alert("Hi!"); break; default: alert("Nothing"); break; } }); });

在上面的例子中,我們使用事件委託為 <ul> 元素添加了 onclick 事件處理程式。由於所有的 <li> 元素都是他的子節點,而且事件會冒泡,所以單機事件最終會被這個函式處理。

顯而易見,我們通過這種方式處理事件,事前消耗會降低,也就是頁面就緒時間會縮短。因為只取了一個 DOM 元素,只添加了一個事件處理程式。所有用到按鈕的事件(大多數滑鼠事件和鍵盤事件)都適合採用事件委託技術。

如果可行的話,我們甚至可以考慮為 document 物件新增一個事件處理程式,用以處理頁面上發生的某種特定型別的事件。


移除事件處理程式

另外一種方案,就是在不需要的時候及時移除事件處理程式。記憶體中留有那些過時不用的“空事件處理程式”,也是造成 Web 應用程式記憶體與效能問題的主要原因。

解決方案就是:
如果你知道某個元素即將被移除,那麼最好在它被移除前手動移除事件處理程式。

btn.onclick = null;