0

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

Gregor Sotošek
  • 357
  • 1
  • 4
  • 22
  • 1
    Have you tried running it long enough to see if the program fails from a lack of memory. A lot of time, garbage collection doesn't run right away. – entpnerd Jan 14 '20 at 22:31
  • I did try to run it and yes, it eventually fails from a lack of memory – Gregor Sotošek Jan 15 '20 at 05:43
  • Would you please add whatever details you can about how it fails when it runs out of memory? Logs, error messages, etc. – entpnerd Jan 15 '20 at 05:44
  • I doubt the posted code is sufficient to diagnose the problem. Your app seems complex which means debugging will be difficult. Study and follow the [relevant tutorials](https://www.google.com/search?q=devtools+debugging+memory+leaks). P.S. this can be also a bug in Chrome so try a much older portable version and also Chrome Canary. – wOxxOm Jan 15 '20 at 06:09

0 Answers0