高效前端:不容小觑的DOM性能优化实践

📅 2026/7/28 18:52:28
高效前端:不容小觑的DOM性能优化实践
提起DOM大多数人大概都会认为这是一个不怎么重要的概念以至于在有些关于性能优化的书中都对此闭口不谈但其实我觉得DOM有关的性能优化在前端开发工作中起着非常重要的作用——DOM是将Web页面与脚本或其它编程语言JavaScript连接的桥梁。众所周知DOM也是Web页面实现面向对象编程的中介。我们的网页都是由HTML元素构成的而每一个HTML元素都是一个DOM节点一个一个的DOM节点就构成了我们平时所说的DOM树正如万物皆对象所以我们的每个DOM节点甚至是整个DOM树都可以看成对象我们可以使用JavaScript操作这些DOM节点以实现丰富的交互功能。DOM优化的背景在没有Vue、React的年代要实现复杂的交互需要获取对应元素然后再进行各种操作但这样操作DOM时非常耗费性能的。仅仅是一个节点的属性就非常多关于DOM的优化我在本专栏的其他文章中曾提过一些优化建议比如不要嵌套多个无用的div、能用css实现的就不要写HTML或js等。在React框架中如果遇到必须要一个父元素包裹的情况我们可以用 Fragment 标签来实现它不会在DOM树中创建对应的节点也就意味着对性能和效率比如重绘来说是个不错的选择。我们常常会用到如下形式的代码比如在网页中的导航栏处或者在选项卡中为每个标签菜单添加点击事件。你是否会写出如下代码let container document.getElementById(container); let wrapper document.createDocumentFragment for(let i 0; i data.length; i ){ let li document.createElement(li); li.innerText data[i]; li.addEventListener(click, function(){ // 触发click后要做的事情 },false) wrapper.appendChild(li); } container.appendChild(wrapper);这是很“可怕”的一端代码假设这里有一万条数据那么就需要执行一万次监听事件这对性能影响是很大的我们可以用事件代理机制来解决这个问题let container document.getElementById(container); let wrapper document.createDocumentFragment for(let i 0; i data.length; i ){ let li document.createElement(li); li.innerText data[i]; } wrapper.appendChild(li); container.appendChild(wrapper); container.addEventListener(click, function(e){ target e.target || e.srcElement; //同Vue这里的e就指代了li事件而e.target就指向了li标签比如Vue中input的e.target.value就指向代表了框内的内容 if(target.tagName.toLowerCase() li){ // 触发click后要做的事情 } }, false)这样的话我们就把事件挂在了父元素上面如果有对应事件被触发再去找对应的元素即可。当然我还有一点优化建议一些简单的事件完全可以用css完成在js中只用通过css样式的增加addClass与删去remove来挂载。这对于大型数据下的HTML是非常优化的。这里我们用了DocumentFragments来创建一个节点元素将其作为代理加到父元素上的方法。其实这也是一个优化措施。DocumentFragments是DOM节点但不是主DOM树的一部分通常的用例是创建文档片段将元素附加到文档片段上然后将文档片段加到DOM树。在DOM树中文档片段被其所有的子元素所代替。因为文档片段存于内存中并不在DOM树中所以讲子元素插入到文档片段时不会引起页面回流。可以带来更好的性能体验。