事件委托的性能影响
#
测试代码测试环境为新版 Microsoft Edge
,Chrome
const inEl = document.createElement('input')inEl.value = 1000document.body.appendChild(inEl)
const btEl = document.createElement('button')btEl.innerText = '刷新'btEl.onclick = () => { console.warn('------------reload--------------') createList(Number(inEl.value), onclick)}document.body.appendChild(btEl)
const eventCount = 500
function onclick(el, elIndex) { console.time(`[独立事件] 操作${eventCount}次当前DOM`) for (let i = 0; i < eventCount; i++) { const count = parseInt(elIndex.innerText) elIndex.innerText = count + 1 } console.timeEnd(`[独立事件] 操作${eventCount}次当前DOM`)}
function createList(count = 4000, onclick) { console.time(`[创建] ${count}元素耗时`) const elUl = document.createElement('ul')
elUl.addEventListener( 'click', (e) => { console.time('事件触发时间差') /** @type {HTMLElement} */ const countEl = e.target.lastChild
console.time(`[委托事件] 操作${eventCount}次当前DOM`) for (let i = 0; i < eventCount; i++) { e.target.lastChild.innerText = parseInt(countEl.innerText) + 1 } console.timeEnd(`[委托事件] 操作${eventCount}次当前DOM`) }, true )
for (let i = 0; i < count; i++) { const elLi = document.createElement('li') elLi.innerText = 'list-' const elCount = document.createElement('span') elCount.innerText = i const elCount2 = document.createElement('p') elCount2.innerText = i elLi.appendChild(elCount) elLi.appendChild(elCount2) if (onclick) elLi.onclick = () => { console.timeEnd('事件触发时间差') onclick(elLi, elCount, i) } elUl.appendChild(elLi) }
document.body.appendChild(elUl) console.timeEnd(`[创建] ${count}元素耗时`)}
下图是在 Edge 中 1000 个元素渲染测试,快照 1 为使用事件委托,快照 2 为每个元素绑定事件,可以看到是否使用委托在运行速度上几乎没有区别,内存消耗也相差无几。
下图是 10000 个元素的渲染测试, 运行速度相同,内存消耗有所增加
下图是 20000 个元素的渲染测试, 运行速度依旧相同,内存消耗显著增加增加
下图是在 Chrome 中 20000 个元素的渲染测试, 结果与 Edge 中的测试结果保持一致
#
结论- 事件委托在运行时性能消耗上无影响
- 在一些
MVC
框架中涉及到频繁的重渲染时,事件委托具有很大优势 - 在数据量较大时,使用事件委托可以节约内存占用
- 对于
Chromium
内核的现代浏览器来说,在数据量小(小于1000
条)时没有必要使用事件委托 - 缺点:层级复杂的元素代理繁琐,容易误判