Big data set issue
See original GitHub issueHello, I have an issue with handling big data set in Vue.js
The app: The app has like 50k objects in its memory, lets call them items. Every item has an _id and a name property. I want to list the items to the user one at a time. The user picks an item then i put the item in the Vue instance to render it on screen.
The problem: The data set is like 4 mb big. If i put all the data set (the items object) into a vue instance the 4mb data with the observer properties will be 85 mb. I tried to put the data set into a vuex store, the result was 89mb of memory usage. (This is only a test case, the real production data is like 100mb so in a vuex store it will be instant out of memory i guess).
So I did not put all the data in the instance cuz i do not want reactivity for all the objects, only the one the user picked at that time. So i store the data set in a plain object and if a user pick a an item i put the item into the vue instance then i will have reactivity for that one item. Everything good expects it causes memory leak. Every time i put an item into a vue instance a new observer property will be added to the object. Even if the object was in the instance before a new observer is added next to the unused ones. This works as intended i guess but my issue/feature request is: Can i somehow remove unused observers and getter/setters or are there any other practices to handle big data set in vue?
Things that would solve the issue but I can’t use them: I could deep clone the item before put it into the vue instance, but i need to keep the original object refence cuz other parts of the app updates the object and i want to keep reactivity. Could use a database engine but I need to have offline capability and fast IOless memory search locally.
Here are the test cases I made:
// data in Vuex store 89mb
var store = new Vuex.Store({
state: {
items: {}
},
mutations: {
addItem(state, item) {
Vue.set(state.items, item._id, item);
}
}
});
for (var index = 0; index < 50000; index++) {
store.commit('addItem', { _id: index, name: 'item' + index })
}
var app = new Vue({
el: '#app',
data: {
pickedItemId: 0
},
computed: {
item() {
return store.state.items[this.pickedItemId]
}
}
});
//all in the instance 85mb
var app = new Vue({
el: '#app',
data: {
items: (function () {
var elems = {};
for (var index = 0; index < 50000; index++) {
elems[index] = { _id: index, name: 'item' + index }
}
return elems;
} ()),
item: {}
}
});
//plain object 4mb but memory leak every time when i update app.item with the picked item
var items = (function () {
var elems = {};
for (var index = 0; index < 50000; index++) {
elems[index] = { _id: index, name: 'item' + index }
}
return elems;
} ())
var app = new Vue({
el: '#app',
data: {
item: {}
}
});
Issue Analytics
- State:
- Created 7 years ago
- Reactions:4
- Comments:23 (9 by maintainers)
Top GitHub Comments
Will any of these items be mutated? If they are not, you can simply call
Object.freeze
on them before setting it into the Vue instances. This will let Vue know that it can skip observing the internals of these items and basically solve your memory issue.Even if you do need to mutate them, you can instead do something like
this.item = Object.freeze(Object.assign({}, this.item, changedFields))
.Object.freeze
saves almost 800MB of memory on my big 5K nested array!