Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Practices For Heavy Computations in Javascript?

I am working on client side scripts and need to do heavy computations like pushing huge number of objects in an array, it causes JavaScript to stop response and browser hangs giving an alert:

Browser Warning

Is there any best practices or design patterns for handling these computation, I search and find many different ways to handle these situation but solutions are difficult to implement so I need best practices and easy to understand?

(I am writing code just for example But I need a general solution that is cross-browser i.e, multi-threading etc)

Example Code (series contains thousands of objects):

for (var series = 0; series < chartObj.masterChart.series.length; series++) {
    var detailData = [];
    jQuery.each(chartObj.masterChart.series[series].data, function (i, point) {
        if (point.x >= chartObj.RangeSelectedMinValue && point.x <= chartObj.RangeSelectedMaxValue) {
            detailData.push({
                x: point.x,
                y: point.y
            });
        }
    });
    chartObj.detailChart.series[series].setData(detailData);
}
like image 946
Zaheer Ahmed Avatar asked Dec 19 '12 07:12

Zaheer Ahmed


People also ask

What are the best practices for using variables in JavaScript?

JavaScript Best Practices Avoid Global Variables Always Declare Local Variables Declarations on Top Initialize Variables Never Declare Number, String, or Boolean Objects

How to improve the performance of your JavaScript website?

7. Compress your files Use a compression method such as Gzip or Brotli to reduce the size of your JavaScript files. With a smaller sizes file, users will be able to download the asset faster, resulting in improved performance. 8. Limit library dependencies

What are the causes of JavaScript performance issues?

This guide will explore the causes of JavaScript performance issues and provide a list of best practices for optimizing JavaScript code. The first step to fixing any problem is identifying the root cause. Here are a few things that can cause JavaScript performance to falter: 1. Too many interactions with the host

How to make your JavaScript programs more readable and maintainable?

Check out over 50 tips to make your JavaScript programs more readable and maintainable. 1. Declare and initialize your variables at the top Nothing disrupts readability like a late declaration.


2 Answers

Okay, looking at your code, there's a few things you can optimize:

var s = chartObj.masterChart.series, // #1
    sLength = s.length,              // #2
    chartMin = chartObj.RangeSelectedMinValue,
    chartMax = chartObj.RangeSelectedMaxValue;
for (var series = 0; series < sLength; series++) {
    var detailData = [],
        data = s[series].data,       // #3
        length = data.length;        // #2
    for(var i = 0; i < length; i++){ // #4
        var point = data[i];
        if (point.x >= chartMin && point.x <= chartMax) {
            detailData.push({
                x: point.x,
                y: point.y
            });
        }

    }
    chartObj.detailChart.series[series].setData(detailData);
}
  1. You're getting the same "deeper" object inside chartObj multiple times --> Assign it to a temporary variable;
  2. Don't calculate the length for every iteration of the loop. Same principle as #1
  3. Assign s[series].data to a temp var. This provides a direct pointer to the data instead of having to access s[series].data each iteration of the loop. Same principle as #1
  4. jQuery is slow. For a simple loop, use JavaScript instead, especially if you're looping through a massive object.

I'm not saying this edit will work miracles, but it should reduce the load a bit.

like image 176
Cerbrus Avatar answered Sep 18 '22 20:09

Cerbrus


You should use WebWorkers

They are really supported and they are real threads in javascript as they spawn real OS threads!

Example

main.js

var heavy_process = new Worker('heavy_process.js');

heavy_process.addEventListener('message', function(e) {
  // Log the workers message.
  console.log(e.data);
}, false);

heavy_process.postMessage();

heavy_process.js:

for (var series = 0; series < chartObj.masterChart.series.length; series++) {

  var detailData = [];
  jQuery.each(chartObj.masterChart.series[series].data, function (i, point) {
      if (point.x >= chartObj.RangeSelectedMinValue && point.x <= chartObj.RangeSelectedMaxValue) {
        detailData.push({
            x: point.x,
            y: point.y
        });
      }
  });
  chartObj.detailChart.series[series].setData(detailData);
  // you should use self.postMessage here !!!
}
like image 45
johnnydev Avatar answered Sep 18 '22 20:09

johnnydev