长列表优化

Mr.PDG大约 2 分钟

长列表优化

虚拟滚动

在一含有长列表页面中,你有没有发现你是往下越滑越卡,此时虚拟滚动就排上用场了, 他的基本原理就是只渲染可视区域内的几条数据,但是模拟出正常滑动的效果,因为每次只渲染可是剧域内的数据,在滑动的时候他的性能就会有飞速提升

在vue中比较好用的插件有两个vue-virtual-scrollervue-virtual-scroll-list

安装

npm i vue-virtual-scroll-list

对比

通过 v-for 渲染 10000 个节点,当页面展示94~100区间内的数据时,我们发现浏览器实际将 10000 条数据全部渲染出来了,这很容易导致页面卡顿。

图片
图片

通过 vue-virtual-scroll-list 渲染 10000 个节点,当页面展示94~100区间内的数据时,我们发现浏览器实际只渲染了展示数据前后的91-110内的20条数据(取决于keeps参数)。

图片
图片

简单使用

父组件

<template>
  <div style="height: 650px;">
    <virtual-list 
      style="height: 100%; overflow-y: auto;"
      :data-key="'id'"
      :data-sources="list"
      :data-component="itemComponent"
      :keeps="20"
      :extra-props="{
        address,
        basisInfo,
      }"
      @tobottom="listToBottom"/>
  </div>
</template>

<script>
import VirtualList from 'vue-virtual-scroll-list';
import itemComponent from './itemComponent';
export default {
  data(){
    return {
      VirtualList,
      itemComponent,
      list: [],
      address:{ province:'江苏',city:'南京' },
      basisInfo:[{age:20}] 
    }
  },
  components: {},
  methods:{
    content(){
      for(let i = 0; i < 10000; i++){
        const obj = {id: i, name: `人员${i}`};
        this.list.push(obj) 
      }
    },
    listToBottom(){
      console.log('到底了哦');
    },
  },
  mounted(){
    this.content()
  }
}
</script>

子组件

<template>
  <div>
    编号:{{ index }} <br/>
    姓名:{{ source.name }}<br/> 
    年龄:{{basisInfo[0].age}}<br/>
    地址:{{address.province}}-{{address.city}}
    <hr/>
  </div>
</template>

<script>
  export default {
    name: 'item-component',
    props: {
      // index of current item
      index: { 
        type: Number
      },
      source: { 
        type: Object,
        default () {
          return {}
        }
      },
      address:{
        type: Object,
        default () {
          return {}
        }
      },
      basisInfo:{
        type: Array,
        default () {
          return []
        }  
      }
    },
    mounted(){}
  }
</script>

注意

该组件使用就地补丁策略来呈现列表而不是 v-for:key。 这种方式实现了最佳效率,但仅适用于列表输出不依赖于节点组件内部状态或临时 DOM 状态(如:表单输入值)的情况。 但是遇到这样的情况怎么办? 在不维护内部状态的情况下,推荐使用 propsdispatch(无状态组件),这里是一个 keep-state 的例子。