How to work with processing the displayed information in a browser with a heavy load in the browser

Context

  • We have an application based on Ember that processes a large amount of structured data (business process models).
  • Attention! We really would like to keep our application offline as possible.

Necessity

While we need to display this data, edit it, etc., there is no show stop in the radar ...

But now we want to apply processing on these models: validation, search for paths ... and several algorithms for using time / memory.

Problem

We could process the algorithms on the server, but that could kill the offline mode of the application.

We thought about web workers to avoid freezing applications and process algorithms in the background, but we faced a serious problem: data duplication when transferring data to an employee. Using portable objects will cause the application to lose ownership (and data) during at least the calculation, so it does not seem viable.

How would you deal with this problem? Is our only way out of using “algorithms” in the form of “coroutine-like” algorithms? Any clue?

+6
source share
2 answers

If your main problem is not to freeze the user interface during the lengthy javascript processing that you developed, you can rearrange the contour bodies into successive steps so that each step calls it next using window.setTimeout . This method allows a (single) thread to process user interface events between each interaction:

 var pr = function(x) {console.log(x)}; var COUNT=3; // original regular javascript loop for(var i=0; i<COUNT; i++) { var msg = "current index is (" + i + ")"; pr(msg); } // step-by-step sequential calls var body = function(i) { var msg = "non-blocking for: index is (" + i + ")"; pr(msg); } nonBlockingFor(body, 4); 

The nonBlockingFor function calls the first argument (as a function) the number of times that have passed as the second argument. This definition follows:

 // function constructor var nonBlockingFor = (function() { function _run(context) { if(context.idx > context.max) return; context.fnc(context.idx++); window.setTimeout((function(){ _run(context)}), 1); } return (function _start(ufn, uqt, runId) { _run({idx: 0, max: uqt -1, fnc: ufn || (function(){}), runId: runId}); }); })(); 

Please note that this is a very simplified function, and it can be improved to handle other issues related to several topics - ie: waiting for threads to complete (merging). Hope this code helps you. Please let me know if you like this approach to the problem, I could spend some time improving my proposal if you want.

+3
source

A long time has passed, but still: the solution may be http://jscex.info/

Javascript is single-threaded in nature, and it is a design choice because multithreading is a difficult topic. 99% of random javascript developers will not handle properly.

Workers are the only way to get a different thread, rather than blocking the user interface, but to make them usable without the dangerous side effects of real multithreading, they work in a completely separate context, as you noticed. Thus, they are more like calling an external command that passes command line parameters than creating another thread.

Thus, working in "async" mode is the only solution right now, but since you did not wait for a button to be pressed or a remote connection, the only async event you can associate with is a tick timer, which leads to poor code style, which causes long operations in js.

However, there is a small library that I think is very interesting and completely unknown that (despite this a bad site) is able to "convert" on the fly a beautifully written procedural code into a mess of timers and functions, an asynchronous model requires: http://jscex.info/

As in Windows 3.1, you just need to “give in” ($ await (Jscex.Async.sleep (50));) for a while in the browser so that it does not completely freeze. It will really freeze under the hood, but if you get it often enough that no one will ever notice :) (after all, so multitasking still works inside each core of your processor, very small fragments of time during which the processor is 100% working over one set of instructions .. take this up to 20 ms, no one can tell).

I think this can help you “create” a coroutine similar to a coroutine, without actually “writing” such code, but delegating to the “precompiler” the launch work.

+3
source

Source: https://habr.com/ru/post/919256/


All Articles