UI responsiveness and javascript

I have a large set of data that will be displayed on a google map. Due to the size of the dataset, the google map always freezes for a few seconds before all points are drawn. During loading, I used an animated spinning circle to show it in the process. But end users prefer to see actions. They want the data built on the map, step by step, and not all at once. Since javascript does not support multithreading, what's the best way to approach this?

+4
source share
4 answers

The Javascript engine executes functions one by one, taking them from the queue. Functions can be added either using a script or as a result of user actions (event handlers). Therefore, the idea is to divide a long-term task into small short-term subtasks and transfer them to this โ€œqueueโ€ in such a way that they can be mixed with functions that correspond to user actions.
This can be done by calling the setTimeout window with a zero delay and passing your subtask as a function. So you give a chance to the UI event handler earlier

function plotSpot(spot) { // adding spots to map }; var spots = [1,2,3,4,5,6,7,8,9,10,11,12]; var plotSpotsBatch; plotSpotsBatch = function() { var spotsInBatch = 10; while(spots.length > 0 && spotsInBatch--) { var spot = spots.shift(); plotSpot(spot); } if (spots.length > 0) { setTimeout(plotSpotsBatch, 0); } }; plotSpotsBatch(); 

Here is the extension for the Array prototype:

 Array.prototype.forEachInBatches = function(batchSize, func) { var arr = this; var i = 0; var doer; doer = function() { setTimeout(function() { for (var stopBatch = i + batchSize; i < stopBatch && i < arr.length; i++) { func(arr[i], i); } if (i < arr.length) { doer(); } }, 0); }; doer(); }; 

Usage example (you should have a div with a spot id somewhere in the document). To see the difference, set the batch size to the number of spots:

 var spots = []; for (var i = 0; i < 10000; i++) { spots.push('{x: ' + Math.ceil(Math.random() * 180) + ', y: ' + Math.ceil(Math.random() * 180) + '}'); } spots.forEachInBatches(10, function(spot, i) { document.getElementById('spots').innerHTML += spot + (i < spots.length ? '; ' : ''); }); 
+7
source

Could you build them in batches with a small delay ( setTimeout ) between each?

+4
source

Javascript may not support multiple threads normally, but you can achieve the effect.

 function spawnThread(func, params){ window.setTimeout( (function(f, p){ return function(){ f.call(p); } )(func, params), 0 ) } 

The main problem with this method, of course, would be to verify the success of the thread, I assume that you can handle it with a global variable or something similar, it will not be a great solution, but it will work.

+4
source

Similar to what musicfreak said, but does not require Gears, Javascript website workers . This is currently only implemented in the latest browser versions.

+1
source

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


All Articles