1

I have an upload module that loads a lot of files into memory (no actual uploading) and process them using a memory-intensive function. For ~300Mb of files, it will take the processing function approximately 5 seconds to finish.

My processing function has a progress callback which is called at every slice processed, with a floating-point progress indicator as argument. The (simplified) vue.js component looks like this:

Template (HTML):

<div class="progress" v-bind:style="{ width: progress + '%' }"></div>

Script (ES6):

export default {

  name: 'Dropzone',

  data () {
    return {
      progress: 0
    }
  },

  methods: {
    onDrop (e) {

      let $vm = this;
      let files = e.target.files;

      loadFunction(files, function progressCb (progress) {

        // This lags
        $vm.progress = Math.round(progress * 100);

        // also tried explicit data setting:
        //   $vm.$set('progress', Math.round(progress * 100));

        // also tried manual updating:
        //   document.querySelector('.progress').style.width = Math.round(progress * 100) + '%';
        //   or: $('.progress').css('width', Math.round(progress * 100) + '%');

        // But this works without lag:
        window.document.title = Math.round(progress * 100);


      }, function doneCb () {
        alert('done');
      });

    }
  }

}

The window.document.title updating goes smoothly, linearly from 0 to 100%, whereas the progress bar's behavior is erratic, sometimes advancing by steps of 27%, sometimes going straight from 0% to 100% after 5 seconds of waiting.

My understanding of the problem is that the DOM updates are being throttled by Vue.js' async updates queue due to the high quantity of operations the Javascript VM has to process while updating the progress bar. How do I circumvent this limitation?

3
  • How does loadFunction() work? Is it truly async? are the individual files processes in individual async calls? I think but can't promise (pun not intended), that it would work if you wrapped each file in an individual Promise, wrapped all of them in Promise.all(), and increased the progress value in each Promises then()? Commented Apr 21, 2016 at 19:40
  • @LinusBorg Sadly, it is truly async, and makes use of promises internally :( But I'm curious, what do you think would cause the window.document.title updating fine when the DOM lags? Commented Apr 21, 2016 at 20:30
  • 1
    I think your processing is going to need to pause and continue periodically using setTimeout so that the event loop exits for a moment and the browser can spend time on DOM updates. Commented Apr 22, 2016 at 17:41

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.