首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vue v-for性能差。

Vue v-for性能差。
EN

Stack Overflow用户
提问于 2017-05-11 10:58:21
回答 2查看 19.8K关注 0票数 7

我有大约4000个对象正在通过AJAX返回。我正在用v把它们循环起来,然后把它们吐到桌子上。

初始加载和呈现非常快,但我也有一个输入字段,我正在使用‘即时搜索’。我使用一个计算属性来使用输入值和一个小的数据集过滤数据集,比如说,最多100个结果--这是非常好的,但是当数据集变得更大时,它会变得更慢。

我正在呈现一个包含4个值的表,其中一个是自定义组件。移除组件会加快速度,但我很惊讶它的性能如此糟糕。我不知道我是不是遗漏了什么,或者有人能给我指明正确的方向吗?

我知道这是一页大量的数据,但我认为这是Vue应该擅长的。我搜索了这个问题,例如,我发现这个码页以完全相同的方式呈现类似的条目列表并进行过滤,并且我可以复制粘贴数组中的条目数到大约10,000,而且搜索时没有明显的性能影响。

我已经采取了一些措施来加快速度,这些措施要么取得了微小的进步,要么根本没有改进:

  • 在v-for上添加了一个具有唯一值的v-bind:键。
  • 不使用表元素,而是使用div或ul
  • 放弃nativeJS .filter方法,因为它可能很慢,并且使用我自己的filter方法。
  • 尝试在一个新的代码基上运行它,只需要运行所需的依赖项。
  • 我知道分页技术等等,但我不愿意这样做,除非我已经用尽了所有其他的可能性。

谢谢

它希望我在这里粘贴代码,尽管我已经链接到了codepen,所以这里是没有items数组的JS。

代码语言:javascript
复制
    Vue.component('my-component', {
  template: '#generic-picker',
  props:['items','query','selected'],
  created: function(){
    this.query='';
    this.selected='';
  },
  computed:{
    filteredItems: function () {
      var query = this.query;
      return this.items.filter(function (item) {
        return item.toLowerCase().indexOf(query.toLowerCase()) !== -1})
    }
  },
  methods:{
    select:function(selection){
      this.selected = selection;
    }
  }
})
// create a root instance
var genericpicker = new Vue({
  el: '#example'
});
EN

回答 2

Stack Overflow用户

发布于 2017-05-11 15:54:21

使用计算数组的问题是,当您使用v-if时,当v-show是一个更好的选择时,必须不呈现和重新呈现。

相反,为每个项目保留是否应该显示的指示符,并在此基础上使用v-show。下面的代码片段实现了这两种功能,可以通过复选框进行选择。您会发现,当不使用v-show版本时,过滤器更新会有些停顿,但在使用v-show时会保持良好的状态。

最值得注意的是,当您将其过滤到0行时(例如,在x上进行筛选),然后显示所有内容(删除过滤器),但是您可以看到像me 2这样的部分过滤的不同之处。

代码语言:javascript
复制
let arr = [];
for (let i=0; i<6000; ++i) {
  arr.push({name: `Name ${i}`, thingy: `Thingy ${i}`});
}

Vue.component('tableRow', {
      template: '<tr><td>{{name}}</td><td>{{thingy}}</td></tr>',
      props: ['name', 'thingy']
    }
);

new Vue({
  el: '#app',
  data: {
    arr,
    filter: 'x',
    useVshow: false
  },
  computed: {
    filteredArr() {
      return this.filter ? this.arr.filter((item) => item.name.indexOf(this.filter) > -1) : this.arr;
    }
  },
  watch: {
    filter() {
      for (const i of this.arr) {
        i.show = this.filter ? i.name.indexOf(this.filter) > -1 : true;
      }
    }
  }
});
代码语言:javascript
复制
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
  Filter: <input v-model="filter">
  Use v-show: <input type="checkbox" v-model="useVshow">
  <table>
    <tr>
    <th>Name</th>
    <th>Thingy</th>
    </tr>
    <template v-if="useVshow">
    <tr is="tableRow" v-for="row in arr" v-show="row.show" :key="row.name" :name="row.name" :thingy="row.thingy"></tr>
    </template>
    <template v-else>
    <tr is="tableRow" v-for="row in filteredArr" v-show="row.show" :key="row.name" :name="row.name" :thingy="row.thingy"></tr>
    </template>
  </table>
</div>

票数 12
EN

Stack Overflow用户

发布于 2019-03-06 21:23:51

如果您对双向绑定和/或反应性绑定不感兴趣,也就是说,如果您只想可视化对象,而不是能够在数据更改时编辑它们或更新视图,那么使用Object.freeze可以显着地提高性能。这样,Vue.js就不能在每个属性上添加观察者,而只能读取属性。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43913454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档