Jan*_*nne 14 memory arrays performance vue.js vuejs2
我正在尝试在Vue 2上为大型半复杂对象集合实现一个表视图.基本上我的想法是从DB到JS缓存中收集5万到10万行之间的任何行,然后动态分析它以构建表 - 使用实时过滤器(文本搜索)查看.表中的每一行都是可切换的,这意味着单击该行可将行更改为编辑模式,从而为该特定字段/单元格启用类似Excel的编辑.
每个对象具有大约100-150个字段/属性,但是在表中的任何给定时刻仅显示一定量的'em'(表列可以实时切换).对于大型数据集,似乎DB正在推动大约10-100mb的JSON数据,在这个用例中是可以接受的.Renderwise性能不是问题 - 过滤器工作得足够快,只有有限数量的结果呈现给DOM.
一切都已经工作,过滤,列出~100行反对过滤器(+"显示100多" - 机制等),但是当我将大约8000个对象加载到数组中时,我达到了内存限制.这似乎保留了2千兆字节的RAM,这是在Chrome停止运行JS代码之后(尽管很奇怪,我没有得到任何警告/错误).
我对行的内存使用情况进行了基准测试,似乎~1000行保留了大约300mb的内存.这很可能由Vue反应观察者保留.
三个问题:
我已经在Angular 1上做了类似的应用程序,并且它处理了5万行,所以我确信它应该在Vue 2中也是可行的......应该只是找到处理反应性的方法.
Jan*_*nne 17
我问了这个问题已经有一段时间了,我终于优化了我项目的这一部分.我想为任何有这些性能和/或内存问题的人提供一些指示.
Vue文档从未真正解释过它,但正如Andrey指出的那样,您可以将组件对象用作自定义对象和对象列表的数据存储.毕竟,它只是一个普通的javascript对象.
优化后,我的列表组件设置看起来像这样:
module.exports = {
items: [],
mixins: [sharedUtils],
data: function() {
return {
columns: {
all: []
etc... Lot's of data & methods
Run Code Online (Sandbox Code Playgroud)
items-array填充了数千个复杂对象(大约80mb数据,6mb压缩),我将其视为非反应性.事实证明这不是我想象的问题 - 我没有使用v-for直接针对项目我已经使用了结构,当用户点击某个过滤器按钮和/或输入的字符串时,我触发了该数组的过滤过滤(例如名称).基本上,这个"processFilters"方法遍历非响应的items-array并返回filteredItems,它存储在数据上下文中.因此,它会在变异时自动变为反应性.
<tr v-for="item in filteredItems"
Run Code Online (Sandbox Code Playgroud)
这样,filteredItems中的所有项目都会保持反应,但是当它们被过滤掉时也会失去反应性,从而节省了大量内存.高达1200mb缩水至400mb,这正是我想要的.聪明!
很少有问题需要解决.由于数据上下文中不存在项目,因此无法在模板中直接使用它.这意味着而不是写...
<div v-if="items.length > 0 && everythingElseIsReady">
Run Code Online (Sandbox Code Playgroud)
...我必须存储items-array的长度来分隔数据道具.这也可以用计算值修复,但我喜欢保留这些属性.
放弃主数据阵列的反应性毕竟不是一件坏事 - 最重要的部分是要理解直接针对该基础阵列中的项目进行的修改永远不会触发对UI的任何更改和/或子组件(douh).这不应该是一个问题,只要你以这样一种方式分离你的代码,即你拥有"隐藏数据容器"来保存后端的所有结果,并且你拥有那个大容器的较小(过滤)表示数组.通过使用良好的REST架构,您应该已经很好地使用非活动数据存储,只要您记得在非活动数据存储中保存项目后检查已更新到最新版本.
此外,令我感到困惑的是,对于数百行,有多少微型组件在性能方面有多么重要.渲染很明显,但即使我要传递大型道具数千次(因为我有数千个输入单元实例),它似乎没有打到内存.这种对象之一是我的全局翻译 - 键/值对对象,有超过20 000行翻译的字符串......但它仍然无关紧要.这是有道理的,因为Javascript使用对象引用并且Vue Core似乎被正确编码,因此只要您使用这样的配置对象作为道具,您只需将数千个对象引用到相同的数据集.
最后,我会说开始对复杂的CRUD对象发疯,而不用担心内存限制!
非常感谢Andrey Popov向正确的方向推进!
从我读过的所有内容中,我看到您不需要对这些数据进行反应,因为:
表中的每一行都是可切换的,这意味着单击该行会将行更改为编辑模式,从而为该特定字段/单元格启用类似 Excel 的编辑
这意味着在没有用户交互的情况下,行不可编辑且数据无法改变。
每个对象大约有 100-150 个字段/属性,但在表中的任何给定时刻只显示一定数量的字段(表列可以实时切换)。
您保持字段反应性但不显示它们。
现在你的问题
有没有办法切换特定数组列表对象的反应性(通过索引等),以便数组本身内的对象是不可观察的/不可改变的,除非专门调用使其变为可变(即,当用户单击行时,启用编辑-模式)?
如果有一个项目可以一次编辑,那么为什么要保持所有内容都是反应性的?您可以轻松地使用单个变量来侦听该更改。
您将如何为 Vue 实现大型数据集的处理,因为反应性似乎限制了内存使用?
一切都与实现有关 - 当您需要大量项目进行响应时,您很少会遇到这种情况。您拥有的项目越多,为了使用反应性需要发生的事件就越多。如果您有 50k 项并且只有几个事件需要改变(比如用户手动修改数据),那么您可以轻松监听这些事件并手动进行响应,而不是让 Vue 处理所有数据。您可以查看Vuex,它可以让您的生活更轻松:)
我的一个想法是使用 Object.freeze 或一些类似的方法将“项目”-数据集变为不可观察/非反应性,并有表格来呈现两个数据集:一个用于非反应性,另一个用于当前在编辑模式(单击行时将推送到“editableItems”数据集)
这有点朝着正确的方向发展,但不需要支持两个阵列。想象一下使用这样的东西:
data: function() {
return {
editingItem: {}
// when editing is enabled bind the input fields to this item
}
},
created: function() {
this.items = [] // your items, can be used in markdown in the loop, but won't be reactive!
},
watch: {
editingItem: function(data) {
// this method will be called whenever user edits the input fields
// here you can do whatever you want
// like get item's id, find it in the array and update it's properties
// something like manual reactivity ;)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7482 次 |
| 最近记录: |