[Vuejs]-How to populate arrays efficiently and non blocking

1đź‘Ť

Your “loading” animation is “frozen” because JavaScript is single-threaded and when your transformation code is running (assuming there are much more data than shown in the example so it is running for significant amount of time), browser’s rendering is blocked.

Either you can optimize the transformation code to make it faster or you can take a look at this SO answer for details and solutions how to make long running operations not to block browser’s rendering….

0đź‘Ť

I guess the problem is that you set loading to false before axios is done getting your data (because that is the only async operation in the code).

The .forEach could probably be optimized a bit, but I doubt that is the culprit.

Try moving all your code in the .then chained off of the axios.get() instead.

👤forkerino

0đź‘Ť

I can’t really speak to the efficiency of your code, but a simple way to keep a loading indicator going until after an async operation finishes, is to to stop it in a finally-block:

const btn = document.getElementById('btn');
const mockLoadIndicator = document.getElementById('loading');
const data = [
  {
    "name": "bob",
    "group": "A"
  }, {
    "name": "sally",
    "group": "A"
  }, {
    "name": "john",
    "group": "B"
  }, {
    "name": "jane",
    "group": "B"
  }
];
const mockAPI = () => {
  mockLoadIndicator.style.display = 'block';
  return new Promise((resolve) => {
    setTimeout(() => resolve(data), 1000);
  });
};

btn.onclick = () => mockAPI()
.then(console.log)
.finally(() => {
  mockLoadIndicator.style.display = 'none';
});
#loading {
  position: relative;
  display: none;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background: grey;
  animation-duration: 300ms;
  animation-name: load;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

@keyframes load {
  from {
    left: 10px;
  }
  to {
    left: 40px;
  }
}
<button id="btn">Get Data</button>
<div id="loading"></div>

Leave a comment