遇到一个性能相关的问题,使用 Element Plus 的 <ElSelect> 组件在数据量很大时,加载速度变慢。
下面简单分析下原因,并提供了一些解决方法。
1. 问题分析
1、大量 DOM 节点渲染
问题:当数据量非常大时,每一个选项都会生成一个 DOM 节点。在 HTML 中,每一个 <option> 元素都需要单独渲染,导致页面需要处理大量 DOM 元素的加载和渲染,影响页面性能。
影响:浏览器在渲染和操作大量 DOM 时效率会降低,导致组件初始化和操作(如滚动、过滤)变慢。
2、Vue 响应式系统的性能瓶颈
问题:Vue 的响应式系统会追踪每个数据项的状态变化。当 <ElSelect> 中的数据量过大时,Vue 的响应式系统需要为每一个 Option 建立响应式追踪,增加内存和计算的开销,尤其是在更新数据、滚动或筛选时,这种情况会更加明显。
影响:响应式追踪在数据项非常多的情况下可能导致浏览器出现卡顿,甚至出现页面响应不及时的情况。
3、事件监听和计算
问题:当 <ElSelect> 中的数据项很多时,每次选择、过滤或输入,都会触发事件监听器和计算操作。如果数据项非常多,这些操作会变得频繁且耗时,增加组件的负担。
影响:页面响应速度降低,用户在操作组件时会感觉到明显的卡顿。
4、过多的无意义的渲染
问题:在默认实现中,<ElSelect> 会一次性渲染所有数据项,不管用户是否在当前视口中看到这些数据。即便用户只滚动一小部分,整个组件仍然会处理所有数据项,导致加载速度慢。
影响:浏览器资源被过度消耗,渲染效率降低,页面加载时间延长。
2. 解决方案
1、使用虚拟滚动
方法:借助虚拟滚动技术(如 Element Plus 的 ElVirtualizedSelect 组件),只渲染当前视口中可见的部分数据。虚拟滚动技术通过动态加载和卸载数据项来减少页面上的 DOM 节点数量。
这种方法能显著减少 DOM 渲染的节点数量和内存占用,提升渲染速度和用户体验。
🌰
<template>
<!-- 使用虚拟滚动的选择框 -->
<el-select-v2
v-model="selectedValue"
:options="options"
placeholder="请选择"
style="width: 200px"
/>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
// 创建 10,000 条模拟数据
const options = ref(
Array.from({ length: 10