【问题标题】:Performance of Vue with a large array of objects具有大量对象的 Vue 性能
【发布时间】:2020-03-09 13:27:03
【问题描述】:

我在harvesters 中存储了一长串项目(总共 460 个)。这是我在Vue 中过滤列表的代码:

computed: {
    searchHarvesters() {
      var vm = this;
      let searchTerm =this.searchInHarvesters.toLowerCase();

      let collection_filters = {};
      let col_filt_enabled = false;
      this.distinct_collections.forEach(c => {
        if(c.selected) {
          collection_filters[c.name]=true;
          col_filt_enabled =true;
        }
      });

      return this.harvesters.filter(h => {

        let validSearch = (h.name.toLowerCase().includes(searchTerm) ||
          h.db_collection_name.toLowerCase().includes(searchTerm) ||
          h.source_name.toLowerCase().includes(searchTerm));
        return (
          col_filt_enabled ? 
          (typeof(collection_filters[h.db_collection_name])!== "undefined"  &&  validSearch):
          validSearch
        );

      });
    }
  }, 

...
methods:{
    debounceInput: _.debounce(function (e) {
      this.searchInHarvesters = e.target.value;
    }, 500)
  },
...

这是 HTML 元素:

<form class="uk-search uk-search-default uk-float-right">
  <span class="uk-search-icon-flip" uk-search-icon></span>
  <input class="uk-input" type="search" placeholder="Search..." v-on:input="debounceInput">
</form>

当我在输入中输入一个术语来过滤列表时,它工作正常;但是,当我清除输入时,显示完整列表需要 5 秒,这很慢。 如何让 Vue 工作得更快? 谢谢。

【问题讨论】:

  • 通过查看 devtools 并查看它在做什么。像这样在 500 个元素上的过滤器不会花费 5 秒,即使在手机上也是如此。创建 500 * 多少元素/组件可以做到这一点。由于您没有包含该代码,因此我无法确定是否是这种情况。尝试用简单的{{ searchHarvesters }} 替换v-for 而不是searchHarvesters,以确保它仍然可以计算和打印,但不必制作html 元素。这会加快速度吗……很多吗?
  • @Sumurai8 是的,它加速了很多。那么可能是v-for中的渲染代码太重了?
  • 在这种情况下,请寻找一种解决方案,限制可以一次显示的元素数量(例如限制为最多 100 行或其他内容,如果有更多行则显示警告),或查看仅呈现屏幕上的元素,而其余部分是具有高度的空 div 的解决方案。我相信这种技术被称为“虚拟滚动”并且有几个库。

标签: vue.js vuejs2 vue-component vuex


【解决方案1】:

不确定这是否是瓶颈,因为 5 秒对于 500 件商品来说似乎确实很多。

鉴于您不会使用Object.freeze 编辑他们的任何项目信息,您可以“关闭”大型列表的反应性,因此如果它只是列表,您可以这样做:

  1. 禁用所有项目的反应性。
this.harvesters = Object.freeze(this.harvesters);
  1. 禁用计算属性中返回项目的反应性:
const matches = this.harvesters.filter(h => {
  // ...
});

return Object.freeze(matches);

【讨论】:

    猜你喜欢
    • 2012-05-22
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2015-05-11
    • 2021-06-04
    • 2013-07-28
    • 1970-01-01
    相关资源
    最近更新 更多