HTML unable to keep up with JS

I want to display real time calculations to the user while my program is running. This is because it is a brute force combination generator which can take 5 - 10 seconds to calculate.

Here is the just JavaScript version of the Program. Expand the console to full screen and hit to run it:

–> https://repl.it/@Michael_Nicol/Combination-Program-20

You will see how I was able to display real time data to the user using console.log()

Now I decided add this to my combination generator

Before you start it, you can see how I have the similar set up where you can see the combinations tried, etc. Its the exact same code but instead of sending it to the console, it just changes the span text.

–> https://codepen.io/Mike-was-here123/full/OYXgMp

However, when the user clicks to run they do not get a fluid motion like in the repl.it i linked. Instead, the HTML just freezes and then it loads in.

Here is my question: How can I prevent the HTML from lagging when I am updating it very quickly like in this case? The JavaScript did upwards of 22,500 combinations (on my CPU) per minute and it seems the HTML cannot keep up.

I feel like this isn’t a issue with my program itself, but rather the concept of doing this. What do you suggest?

1 Like

Some thoughts

  1. You’re using jQuery to traverse the DOM. There may be performance hit with jQuery vs. pure JS.
  2. Instead of updating a span, how about just having a text box and append the new “printout” at the bottom of the text box content. (Don’t know if this will be slower or faster, but something to try.)
  3. Does the user need to see all 22,500 values per minute on the webpage? Why?
  4. Input/output operations (i.e. display) are expensive vs. in-memory calculations. Why not just show a spinning box to show that calculation is taking place and just display the resullts to the user. The user doesn’t care to see all 22,500 values.
1 Like

@camperextraordinaire @owel

I thought a simple number changing would not be that hard for HTML handle.

I just thought it would be cool to show the user just a few basic numbers on what is happening rather then a spinning progress bar would be better.

If i append to the box, then after a couple thousand combinations it becomes so long the calculations slow down. When I did a couple massive tests with the repl.it version, after 50,000 combinations it would take upwards of 20 milliseconds (instead of 1) to make a combination. It is spending so much CPU on the list it takes away from the calculations.

When you calculate combinations, it gets exponentially slower. The first 50% wont take long at all, but near the end with the last 100 or so combinations (Out of a couple thousands) it takes absolutely forever since its random. If this was a progress bar, it would jump up to 70% quickly then just sit forever and slowly creep its way up for a minute. I just thought this would be boring to the user.

1 Like

When you do I/O, it slows down everything a lot. (Whether displaying something on screen, logging to a file, writing to a database).

I just thought it would be cool to show the user just a few basic numbers on what is happening rather then a spinning progress bar would be better.

If you really want to update the user that something is going on, you can just display/update every nth value. Say 10th or 100th value will be displayed on screen. Or every 1 second elapsed time, something will be displayed on screen.

Or just “fake it”… have an animated gif that seems to be displaying random numbers on screen… while you do your computation behind the scenes, then just replace the gif with the final answer.

1 Like

I edited it so it does it every 1%.

I have ran into another issue - the fact that codepen just crashes until my program is done. I just get a white or black screen.

Or I get the page un-responsive screen.

Is their anyway i can tell the browser that the program is indeed working? It just seems to attempt the program as fast as possible then can’t handle it and crashes. I can’t do it by adding a 10 millisecond pause between each combination attempt since I would need to rewrite my entire program with setInterval (their is no simple wait function in JS).

repl.it doesn’t crash, why does Codepen have the inability to handle much of anything?

Devs usually work on code on their own machine, and not using codepen or replit.

I suggest using Visual Studio Code, download an Extension/plugin called “Live Server”. Then preview your webpage locally on your machine. VS Code will launch a local web server (at some port #) to serve your page.

1 Like

Two words:

Research WebSockets.

I downloaded it, set it up, put my program on it, etc.

The live server thing isn’t working. I downloaded the extension, but have no idea where the button is. Every tutorial I see, their is a go live button at the bottom of the page on the footer. for me, their Is not.

I also couldn’t get my JS to link despite it being in the same folder.

Create a subdirectory
Copy all your files to that subdirectory.
Open that Folder in VSCode (not just open the html file)
You should see Go Live at the bottom of VSCode editor.
Click Go Live.
Then preview your file (either it’s already opened on editor, or right-click on file you want to preview)

There are a few things here, and @owel has covered most of them. But you were originally expecting to get 375 frames per second performance. This should be obviously unfeasible.

If you drop that to 1%, that’s 37.5 fps, which turns out to be feasible in a browser, particularly if the work is being delegated to the GPU on your computer. But it isn’t: you’re updating HTML, not rendering 3D graphics. You could probably shift the code to rendering whatever you want to show in a <canvas> element. That will give you a way to get what you want, although seems a huge amount of work for not very much.

Also, your JS is single-threaded. You aren’t delegating the work to another thread, so it is going to block everything else. If you try to update the browser 30 odd times a second on that main thread, in lockstep with your expensive calculation, you shouldn’t be too surprised if the browser just says nope. Particularly if on top of that you’re basically trying to run the code in what is a virtual browser with hobbled performance.

console.log works fine because it’s hardly doing anything: implementation-wise, it’ll be a tiny piece of C++ code that listens to processes & stdout/stderr. In comparison, with the HTML update, you’re asking the browser to do huge amounts of work.

2 Likes

When I do massive numbers like 9! (362,000 combinations) then it takes a couple of minutes in between each HTML update if i did it every 1%.

Yet if i try and do this on the codepen it still just lags out completely and wont update.

Should i avoid using codepen and try to do it locally on my computer?

It’s not going to make a huge amount of difference, although it’ll work a lot better because you have control over the environment, there isn’t a lot of other JS code running at the same time, and it isn’t going to stop you from doing something silly. It will still freeze because what you’re doing is running something that takes a [relatively] very large amount of computing resource, and expecting that to cause a browser to rerender many multiple times per second on one thread. You can not use the DOM for a start (it isn’t designed to do what you’re trying to do in any way, shape or form), and render the update information to <canvas>, that will help. But you’re still running something that takes a large amount of resource to calculate on one thread. You can use a web worker to move the computation to another thread, then pass a message every n calculations. Then the bottleneck becomes the message passing between the worker and the main thread – I have no idea what the constraints on that are. What you’re tring to do is abnormal, regardless of what language/environment you’re using – there are actual physical constraints here.

Don’t do the calculations on client., do it on server & use websockets to display realtime updates in DOM.

This really isn’t that hard.

Yes, fine (and “just use websockets and do this on a server” isn’t really simple is it?) but that’s not the issue. Moving it to a seperate thread will achieve exactly the same thing without a server, but OP is talking about lag in HTML, that issue will still be present regardless.

The difference is the client will not experience the freezing nor would their resources be causing their experience to freeze. Websockets can update your DOM instantly without any freezing.

As for moving the calculations to server, it may even better to let C++ handle it.

client (websocket) (html) <—> server (websocket) (stdin/stdout with c++) < — > c++

Yes, it will experience freezing, because the DOM is being manually rebuilt multiple times a second. Websockets do not say anything about updating the DOM, they just provide a bidirectional networking socket. Again, moving the calculation to a seperate thread will achieve almost exactly the same result, but that isn’t the issue. OP is trying to provide some visual feedback to a user for a tiny (if resource intensive) program that does a calculation: saying “just write a C++ application, sit a websocket server on top, and plug the client into that” is an insanely complex solution for what they are trying to do.

Give me an example of an intensive calculation & I’ll build an example of it right now… with the DOM updating.

Would displaying numbers from 0 to 2 million in DOM be good enough of an example for you?

Sure, the calculation should run for a few minutes and append a new element to the DOM 300 times a second, in real time please, no increasing lag time

You mean update, not append right?