1

I have a VUE app that performs background tasks for various seconds when user clicks a button, freezing all the UI

.vue file:

....
methods:{
    do_task(){
         this.calculator.calculate() //this takes a lot of seconds and the UI freeze
    }
}

calculator.calculate() is like a nested for cycle that takes time

looking for a solution, the best would be not freezing ad all (background task pattern), but also refreshing the UI at least twice per second is ok (some progress feedback to the user)

how can I achieve this?

isherwood
  • 58,414
  • 16
  • 114
  • 157
Luca C.
  • 11,714
  • 1
  • 86
  • 77
  • 1
    with web workers. could you show us your calculate method – bill.gates Jun 20 '22 at 13:53
  • @bill.gates it is a little complicated, you can think it as a nested for cycle – Luca C. Jun 20 '22 at 14:00
  • 1
    well, i need to know if the function is pure or if it has sideffects – bill.gates Jun 20 '22 at 14:02
  • it change the status of data, if you mean this, yes, the rendering during computation changes, until the end, but it would be ok to just have a counter and wait a final update of UI – Luca C. Jun 20 '22 at 14:20
  • well you need to rewrite your function to run without sideeffects, means no computation outside of the function itself, then you could use an webworker – bill.gates Jun 20 '22 at 14:24
  • @LucaC. refreshing the UI means refreshing the data right ? As you are using Vue. Hence, whole component refresh not reqired. – Debug Diva Jun 20 '22 at 15:56
  • @RohìtJíndal yes, buy while doing heavy computing, the UI does not refresh, it only refresh at the end, I wish to give a feedback, like refreshing a progress bar or a counter, while waiting – Luca C. Jun 20 '22 at 16:05
  • Does this answer your question? [How to avoid freezing the browser when doing long-running computations in Javascript](https://stackoverflow.com/questions/13546493/how-to-avoid-freezing-the-browser-when-doing-long-running-computations-in-javasc) – Debug Diva Jun 20 '22 at 16:19

1 Answers1

0

You are likely running a blocking operation which prevents the UI from updating.

If you just want to let reactivity do an update, like notify user that the process is happening and it's OK to let it hang for the next 10 seconds, you could do a simple trick by calling the function through a setTimeout(this.do_task, 0). Setting a 0 will put the execution at the end of the current sequence/pipeline so your UI may update before the process starts. If this works for you, this is likely the easiest way without requiring any refactoring.

Alternatively you can refactor your function to do batch processing, so that only a smaller amount of records/entries/objects (whatever you're processing) gets processed at a time. Hard to give exact details, since no code is available. But you can accomplish this by using promises, or even generator functions (note that it's not exactly beginner friendly)

You can also offload the work to a webworker which will move the processing off the main thread.

Daniel
  • 34,125
  • 17
  • 102
  • 150