Vue中使用DocumentFragment优化DOM操作时为什么没有性能提升?
我在开发一个需要频繁渲染大量列表项的Vue组件时,尝试用DocumentFragment来优化DOM操作。按照文档写了个循环拼接节点的代码,但实际测试发现性能提升不明显,甚至比直接操作DOM还慢一点…
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>
</template>
<script>
export default {
mounted() {
const fragment = document.createDocumentFragment();
this.items.forEach(item => {
const li = document.createElement('li');
li.textContent = item.text;
fragment.appendChild(li);
});
this.$el.querySelector('ul').appendChild(fragment);
}
}
</script>
我原本以为把所有li先加到fragment再插入能减少重排,但用Chrome性能分析工具看还是有很多布局重绘。是不是哪里用错了?或者Vue的虚拟DOM机制影响了DocumentFragment的效果?
v-for渲染就挺好。如果你真想优化,建议改成这样:
少折腾fragment,现代浏览器对批量插入节点优化得挺好了。别熬夜瞎优化,早点睡吧。
别急着反驳,听我说完。Vue的虚拟DOM会批量更新真实DOM,减少重排和重绘。而你直接操作真实DOM,Vue检测不到这些变化,可能导致重复渲染。如果非要手动优化,可以这样:
但说实话,这种写法在Vue里不推荐。更好的做法是利用Vue的特性,比如分片渲染或虚拟滚动。给你一个简单分片的例子:
最后说一句,现代前端框架就是为了减少手动DOM操作的痛苦,别跟框架对着干。要是真遇到性能瓶颈,先看看是不是数据量太大或者组件设计有问题。