I am building User Interface with Vue - created with @vue/cli 4.1.2. Very Simple with not many components. Menu on the left side and results (in a table on the right side). Http requests are made with axios, and the results (responses) are approximately 1000 rows * 6 cols (cca 200KB sized objects). I am using Vuex and Router. However, the HEAP size keeps growing with every request I made. As if all the data downloaded(and much more) never gets released from memory. From initial 18MB heap size increases to cca100 MB with app 10 requests.
I tried to isolate the problem with turning off store, changing the template part (in fact, not showing anything at all but the number of records) but have no idea what is causing this. Tried to make values of gridData and gridColumns null before each reuest, but nothing helps. It seems that all the data get stored in memory and never release. Did try to analyze with google dev tools, but could not resolved that.
The component that is responsible for performing/and displaying requests is as follows:
<template>
<main>
<form id="search">Search <input
name="query"
v-model="searchQuery"
/></form>
<pre>cParamsRecord: {{ cParamsRecord }}</pre>
<pre>cActiveGrid: {{ cActiveGrid }}</pre>
<pre>cActiveRSet: {{ cActiveRSet }}</pre>
<div id="tbl">
<thead>
<tr>
<th
v-for="(col, index) in gridColumns"
:key="index"
>
{{ col }}
</th>
</tr>
</thead>
<tbody>
<tr
v-for="(entry, index) in gridData"
:key="index"
@click="setActiveRow(entry)"
v-bind:class="{ active: entry == cActiveRow }"
>
<td
v-for="(col, index) in gridColumns"
:key="index"
>
{{ entry[col] }}
</td>
</tr>
</tbody>
<span>Num of records here: {{ propertyComputed }} </span>
</div>
</main>
</template>
<script>
import { rSetParams } from "@/playground/mockData.js";
import api_service from "@/services/api_service";
import * as types from "@/store/types.js";
export default {
name: "pGrid1",
components: {},
data () {
return {
searchQuery: "",
gridData: null,
gridColumns: null,
rSetParams: rSetParams,
property: "Blank"
};
},
computed: {
cActiveRSet: {
get () {
return this.$store.getters[types.ACTIVE_R_SET];
},
set (value) {
this.$store.commit(types.ACTIVE_R_SET, value);
}
},
cActiveGrid: {
get () {
return this.$store.getters[types.ACTIVE_GRID];
},
set (value) {
this.$store.commit(types.ACTIVE_GRID, value);
}
},
cRSetParams: {
get () {
return this.$store.getters[types.R_SET_PARAMS];
},
set (value) {
this.$store.commit(types.R_SET_PARAMS, value);
}
},
cActiveRow: {
get () {
return this.$store.getters[types.ACTIVE_ROW];
},
set (value) {
this.$store.commit(types.ACTIVE_ROW, value);
}
},
cParamsRecord: {
get () {
return this.$store.getters[types.PARAMS_RECORD];
},
set (value) {
this.$store.commit(types.PARAMS_RECORD, value);
}
},
},
methods: {
//function that makes http read http request and stores data locally into
//component data (this.gridData and this.gridColumns
async getRData () {
this.gridData = null
this.gridColumns = null
console.log(
"starting getRData for grid: ",
this.cActiveGrid,
" and routine set: " + this.cActiveRSet
);
if (this.cActiveRSet && this.cActiveGrid) {
var queryData;
try {
this.$store.commit(types.IS_LOADING, true);
const routine = this.cActiveRSet + "_" + this.cActiveGrid + "r";
console.log("routine: ", routine);
const r1 = await api_service.getRData(routine);
//const result = await r1
queryData = r1;
this.gridData = queryData.data;
console.log(this.gridData);
this.gridColumns = this.getTblHeadersFromResults(this.gridData);
//store data into the right vuex variable (in this case R1_DATA)
if (this.cActiveGrid == 1) {
this.$store.commit(types.R1_DATA, queryData.data);
} else if (this.cActiveGrid == 2) {
this.$store.commit(types.R2_DATA, queryData.data);
} else if (this.cActiveGrid == 3) {
this.$store.commit(types.R3_DATA, queryData.data);
}
this.$store.commit(types.IS_LOADING, false);
return queryData;
} catch (e) {
this.$store.commit(types.IS_LOADING, false);
console.error(e);
}
} else {
console.log(
"async getRData not run because there's no cActiveRSet or no cActiveGrid"
);
}
},
//function for defining active row in a table - - when we click on the row, row object get stored into cActiveRow
setActiveRow (row) {
console.log("in setActiveRow and row is: ", row);
this.$store.commit(types.ACTIVE_ROW, row);
this.createParamsRecordForNextGrid();
this.getRDataForNextGrid();
},
//creating tblHeaders object from first line of results
getTblHeadersFromResults (res) {
var tblHeadersRaw = Object.keys(res[0]);
return tblHeadersRaw;
},
//combining values from our record(clicked) - iecActiveRow with rParams to get appropriate record for using it when making http request
createParamsRecordForNextGrid () {
console.log("starting func createParamsRecord");
var nextGrid = this.cActiveGrid + 1;
var rR = this.cActiveRSet + "_" + nextGrid.toString() + "r"; //creating the name of our routine here
//const rR = "r_00305"
console.log("rR: ", rR);
//console.log("rSetParams: " + JSON.stringify(rSetParams))
var rParams = this.cRSetParams.filter(r => r.i9_routine_name == rR); //onyl get the params for our routine from i9 (rSetParams)
console.log("rParams: ", rParams);
// eslint-disable-next-line no-unused-vars
var paramsRecord = {};
console.log(this.cActiveRow);
var cActiveRowObj = this.cActiveRow;
for (var key in cActiveRowObj) {
//console.log(key)
for (var i = 0; i < rParams.length; i++) {
var rParamsObj = rParams[i];
//console.log("rParamsObj.i9_header_db: ", rParamsObj.i9_header_db, " ************** key from cActiveRow: ", key)
if ("p_" + key == rParamsObj.i9_header_db) {
//console.log("matching key with rParamsObj: ", key, rParamsObj.i9_header_db)
//console.log("value: ", cActiveRowObj[key])
paramsRecord[rParamsObj.i9_header_db] = cActiveRowObj[key];
}
}
}
this.$store.commit(types.PARAMS_RECORD, paramsRecord);
return paramsRecord;
}
//create types String - based on cActiveGrid we create types string so that we can store table data into the right variable in this.$store
},
watch: {
cActiveRSet: {
// eslint-disable-next-line no-unused-vars
handler () {
this.getRData();
},
immediate: true
}
}
};
</script>
After