面试找工作那会,经常被问到长列表性能优化问题。例如某乎页面数据量为1万条数据,在分批加载数据前提下怎样优化才能滑动不卡顿。当时准备不是很充分,大脑一片空白,导致面试反馈效果不是很好,于是就有了这篇文章。
一、原因
当页面dom元素太多时浏览器渲染速度就会变慢,当浏览器内存不足时甚至会导致浏览器卡顿或者卡死等现象。因此对症下药,解决方案就是减少页面dom的渲染。
二、原理
可以通过按需进行加载dom,即只显示可视化区域的数量。从而减少dom的结构,实现性能提升。因此,分页加载、懒加载等方案根本治标不治本。
三、实现
此文章基于vue-virtual-scroll-list第三方插件,通过虚拟列表进行滚动加载数据。
// 安装
npm i vue-virtual-scroll-list --save
<virtualList
style="height: calc(100vh - 100px); overflow-y: auto;border:1px solid"
:size='50'
:keeps='15'
:data-key="'id'"
:data-sources="data"
:data-component="itemComponent"
:extra-props="{
itemClick
}"
>
</virtualList>
2个关键的参数,分别是size和keeps。size属性指每一行高度,默认50px,keeps属性指每一行显示个数, 默认30个。
// 父组件
<script>
import virtualList from "vue-virtual-scroll-list";
import Item from './item';
export default {
name: 'List',
components: { virtualList },
data() {
return {
data: [],
itemComponent: Item, // 自定义的插槽组件
}
},
methods: {
itemClick(e) {
console.log('e: ', e);
},
getList() {
for(let i =0;i<30;i++) {
this.data.push({
id: i + 1,
name: '列表' + (i + 1)
})
}
},
},
mounted() {
this.getList()
}
}
</script>
// 子组件
<template>
<div class="item" @click="itemClick(source)">{{index + 1}}----{{source}}</div>
</template>
<script>
export default {
name: 'ListItem',
props: {
index: {
type: Number,
default: 1
},
source: {
type: Object,
default: () => {}
},
// 传递事件
itemClick: Function
},
mounted() {
// console.log('执行list', this.source)
}
}
</script>
四、效果