Пишу MMO RTS. На фронте использую Vue. С заданной периодичностью, с сервера, по WebSoket, прилетают обновленные данные. Естественно, данные помещаются во Vuex, за которым следят компоненты.
Обнаружил, что с каждым новым коммитом увеличивается потребление памяти. Если оставить вкладку открытой, то браузер вылетает.
Ниже код демонстрирующий проблему: запустите, откройте консоль - вкладка Memory - и наблюдайте
const data = {
lvl: 0,
a: {
lvl: 1,
b: {
lvl: 2,
c: {
lvl: 3
}
}
}
}
const store = new Vuex.Store({
state: {
count: 0,
data: []
},
mutations: {
increment(state) {
state.count++;
},
set_data(state, payload) {
state.data = payload;
}
},
actions: {
increment(context) {
setInterval(() => {
context.commit('increment');
const newData = JSON.parse(JSON.stringify(data));
context.commit('set_data', newData);
}, 500);
}
}
});
var app = new Vue({
store,
el: '#app',
template: `
<div>{{count}}</div>`,
data() {
return {
count: 0,
d: window.performance.memory.totalJSHeapSize
};
},
created() {
this.$store.dispatch('increment');
},
watch: {
'$store.state.data': {
deep: true,
handler() {
this.count = this.$store.state.count;
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.1/vue.js"></script>
<script src="https://unpkg.com/vuex@2.0.0"></script>
<div id="app"></div>
Новость для меня печальная). Четкого понимания, как решить проблему - пока нет.
UPD Обнаружился нюанс: если html-файл, с этим примером, открыть не через сервер, а полному пути в адресной строке, то утечки нет.
Я думаю что дело не VUEX, а в компонентах что на него подписаны. Скорее всего один из их складывает данные в локальную коллекцию или массив и после изменения хранилища не чистит их.
Попробуй отключить все подписки на изменения, компонент за компонентом пока не найдешь.
Как оказалось,проблема была во Vuex. Если подключить последнюю версию (3.1.2), то это убирает утечку в моем демо-примере.
const data = {
lvl: 0,
a: {
lvl: 1,
b: {
lvl: 2,
c: {
lvl: 3
}
}
}
}
const store = new Vuex.Store({
state: {
count: 0,
data: []
},
mutations: {
increment(state) {
state.count++;
},
set_data(state, payload) {
state.data = payload;
}
},
actions: {
increment(context) {
setInterval(() => {
context.commit('increment');
const newData = JSON.parse(JSON.stringify(data));
context.commit('set_data', newData);
}, 500);
}
}
});
var app = new Vue({
store,
el: '#app',
template: `
<div>{{count}}</div>`,
data() {
return {
count: 0,
d: window.performance.memory.totalJSHeapSize
};
},
created() {
this.$store.dispatch('increment');
},
watch: {
'$store.state.data': {
deep: true,
handler() {
this.count = this.$store.state.count;
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.1/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app"></div>
Но, к сожалению, в моем приложении утечка не исчезла. Но это уже другая история
Продолжение истории: В итоге, пришел к выводу, что утечка максимально себя проявляет в дев-режиме. Поэтому у меня 2 подозреваемых: сам vue/vuex
и vue-dev-tools
, при этом, после иследования срезов памяти, больше склоняюсь к vue-dex-tools
. Т.к. утечка памяти, сама по себе "пахнет" не очень хорошо, я все равно постарался ее минимизировать. Для этого мне пришлось во всех "тонких местах" (watch, computed, store ...) присвоение объектов делать после их глубокого копирования. После таких манипуляций, в дев-режиме, стала заметна работа сборщика мусора. В конечном счете, объем потребляемой памяти все равно растет, но стали заметны откаты. Что же касается прод-режима, то там стало все замечательно.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как можно при помощи javascript заменить слово в тексте, не используя replace?
Подскажите, каким способом лучше сделать (скриншот) подобную диаграмму? Данные должны браться из базы данных и выводитьсяВидел примеры с использованием...
Как получить обработанные данные в виде структурированных данных (например массива)Дело в том, что эти данные необходимо обновлять в таблице,...