Number of objects vs Payload, while scaling a modern Javascript project which is more important? Number of objects vs Payload, while scaling a modern Javascript project which is more important? reactjs reactjs

Number of objects vs Payload, while scaling a modern Javascript project which is more important?


I like some of the answers I've read, but I think I would approach the question of the bottle neck in a different way, by which I hope you could avoid future bottle necks as well.

Most answers assume that the number of objects is the bottleneck. I think this isn't the case. I believe the bottleneck is the fact that the JavaScript event loop gets excessively backlogged.

As you well know, JavaScript runs only a single thread and an event loop.

Each function you call is actually a callback for such events.

However, since there is only a single thread, any code in the web page has to wait for each event to complete before any other task can be performed.

This means that it's more important for JavaScript functions to be fragmented (into micro events/callbacks) than for any single function to be performance oriented.

In your case, you're both looping over a long string and performing actions - without returning the control to the event loop - which means the browser has to wait for this big chunk of code to complete before it can process any more data / events.

The question of data collection / processing can be argued over. Is it better to get a lot of small messages (placing, perhaps, more load on the network / server)? Is it better to receive a huge string and process it by chunks? ...

... I don't know, this really depends on other factors, such as the server's design, the database's design, the client load, update interval, etc'.

If you do prefer to process a single huge string, it might be better to process it a bit at a time and then forward it to a callback for future processing.

i.e. for a \n seperated JSON string, you could try:

function consumeString(s) {    if(s.length == 0)        return;    var sep = s.indexOf("\n");    if(sep < 0)        sep = s.length;    try {        var obj = JSON.parse(s.slice(0, sep));        console.log("processed:", obj);    } catch {        console.log("Failed... not valid JSON?:");    }    // schedule the next slice for later processing.    setTimeout(consumeString, 0, s.slice(sep + 1));}var text = '{ "employees" : [' + // JSON1'{ "firstName":"John 1" , "lastName":"Doe 1" },' +'{ "firstName":"Anna 1" , "lastName":"Smith 1" },' +'{ "firstName":"Peter 1" , "lastName":"Jones 1" } ]}' + // END JSON1"\n" +'{ "employees" : [' + // JSON2'{ "firstName":"John 2" , "lastName":"Doe 2" },' +'{ "firstName":"Anna 2" , "lastName":"Smith 2" },' +'{ "firstName":"Peter 2" , "lastName":"Jones 2" } ]}';consumeString(text);

This is just an outline, obviously, but although it seems less performant (it wastes time rescheduling itself and is constantly interrupted, increasing the chance for CPU cache misses)... it actually helps the browser remain responsive and improves the perceived performance, from a user's point of view.


10,000 object don't seem a lot for modern JavaScript VMs. Your problem seems to stem from the fact that you are processing a large amount of String in memory and Updating DOM both of which are slow and memory intensive operations.

Note that Strings are immutable in JavaScript, so every time you are chopping it you are creating new instance of it in memory. This is especially bad if you are doing String manipulation inside a loop.Every iteration will lead to creation of a new String object in memory. The old one is now discarded but might not get garbage collected immediately so will eat up memory. Problem will get worse if you are manipulating large chunks of strings. Javascript is not really good for doing this type of long running in-memory operations because it is single threaded. And such operations tie up the main thread which makes your application slow.

while(...) {  // this will create a new instance of fullStr in memory every iteration  fullStr = fullStr + 'str1';}

DOM manipulation can be really slow even with modern JS libraries like React if not done correctly. If you keep rendering new rows by appending new nodes to existing DOM you will see performance problems. DOM manipulation leads to reflows and repaints both of which are very slow and computationally intensive. Every call to render might cause a complete reflow and repaint. If your higher order component gets rendered on prop change, it might force all the child components to re-render which slows down you page. React does take care of some of these concerns by batching updates.

Another thing that a lot of people don't consider is the side-effect of using event handlers for events like mousemove or scroll. Every tiny movement might cause an element on a page to change in some way that might cause repaint or reflow of other parts of the DOM too. Things can get worse when using lot of animations on the page. These type of event handlers can also tie up VMs event loop by constantly firing. One to tackle this problem would be to use throttling.

Least likely but something to consider, objects when created, have an extra overhead of keeping count of references. To us it might look like VM is storing an object with all it's properties and values in a contiguous block of memory. However, in reality objects store references to actual values stored else where in memory. This overhead can be non-trivial for large number of objects.

There is a misconception that creating a new instance of a class or function causes lot of memory overhead as all properties are and values are cloned. This is not true. Use of prototypes by JavaScript cuts down memory usage by sharing the same properties with all the instances of of a particular class or function. That is why prototypal inheritance is very efficient in terms of memory usage. Deep prototype chains might cause slow lookups though.


I'll give the best answer I can, considering that my areas of expertise only cross the scope of this question rather than fully covering it.

Modern computers have a memory hierarchy: main memory; two or three levels of caches. Each level of cache is smaller but nearer to the CPU (and so faster, in effect) than the one above it.

Therefore, in terms of the speed at which a program runs, it tends to be less important how much overall memory it is using than the current 'working set' - the parts of memory that the program is making use of at one moment in time.

From your description, it sounds like breaking up the big JSON string into a lot of smaller objects would help reduce the size of the working set most of the time. If, in doing this, you are left with a lot of unused properties, that probably won't matter, because they will probably remain outside the working set most of the time.

It might be a useful technique to have the back end filter out some of the properties that are not needed, simply because this will reduce the amount of data being transmitted. However, you need to carefully consider how this would scale; it might put too much load on the server(s).

It may be that there are ways to speed up your program by re-assessing the algorithms you have coded and the library (methods) you use. There may be some techniques specific to typical modern JavaScript engines; I'm afraid this is outside my expertise.

It might help to introduce some new concepts into your application. Might it be acceptable for the processing to be reduced by adopting heuristics (systematic guesswork) or reduced accuracy?

For example, users could be presented with interim results based on a first pass that only uses some of the data. A spinner (or message) could be used to alert the user that more processing is going on. When the full data set has been processed, present that to the user.

Or, give the user the choice of 'quick' or 'deep' results; the deep results might be computed on the back end instead (and possibly this could be farmed out to machines other than the HTTP or database server(s)).

HTH & Good Luck!