skip to Main Content

How can I get javascript to update my webpage in real-time?
It seems that my Chrome browser puts all of its processing effort into required computations, and then does the webpage updates. Below is the simplest test HTML file. I would prefer to see sequential counting (instead of just one jump to the final value). What should I replace display.innerHTML = i; with?

I hope the answer is not to break up my computation into many computations using setInterval or something like that. Of course, the breaks this creates will allow display updates, but I prefer not to manage it in such detail…I am hoping that there is a "blocking" display function available, so that the count here will not proceed until the browser renders my display update (or is there is a "flush" command like C provides?). I could use the developer console if needed, but that is also not ideal.

<!DOCTYPE html>
<html>
<body>
<p id="Display"></p>
<script>
const display  = document.getElementById("Display");
for (let i = 0; i <= 3000000000; i++) {
            if (i %   100000000 == 0) display.innerHTML = i; }
</script>
</body>
</html>

2

Answers


  1. requestAnimationFrame way

    Using requestAnimationFrame or setTimeout where you exit the loop to let it allow the UI to be updated and you resume the loop where you left off.

    const display = document.getElementById("Display");
    
    function process() {
    
      let index = 0;
      const max = 3000000000;
      
      function run () { 
        while (index <= max) {
          if (index % 100000000 == 0) {
            display.innerHTML = index;
            break;
          }
          index++;
        }
        if (index++ <= max) window.requestAnimationFrame(run);
      }
      
      run();
    }
    
    process();
    <p id="Display"></p>

    The web worker way

    Put your algorithm in a JS file where it posts a message when it wants an update

    for (let i = 0; i <= 3000000000; i++) {
        if (i %   100000000 == 0) self.postMessage(i);
    }
    

    and in your UI code.

    const display  = document.getElementById("Display");
    const myWorker = new Worker("workerAlgorithm.js");
    myWorker.onmessage = (e) => {
      display.innerHTML = e.data;
    };
    
    Login or Signup to reply.
  2. As @epascarello mentioned in a comment, using a worker is the conventional way to handle computational tasks off of the main thread — in order to prevent blocking renders. Below is a simple example that you can use to reproduce.

    It appears that Stack Overflow won’t execute worker scripts from blob URLs in snippets, so you’ll need to save the code as a local HTML file, serve it with a local http server, and navigate to it in your browser. Here’s a link to a publicly hosted copy of the example: https://jsfiddle.net/zsb7cou5/

    <!doctype html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
    
      <title>Compute on a separate thread</title>
    
      <script type="module">
        const display = document.getElementById("Display");
        
        const workerScriptSource = `
        for (let i = 0; i <= 3_000_000_000; i += 1) {
          if (i % 100_000_000 === 0) self.postMessage(i);
        }
        self.close();
        `;
    
        const workerScriptUrl = URL.createObjectURL(
          new Blob([workerScriptSource], { type: "text/javascript" }),
        );
        
        const worker = new Worker(workerScriptUrl, { type: "module" });
        
        worker.addEventListener("message", (ev) => {
          display.textContent = ev.data;
        });
        
        </script>
    </head>
    
    <body>
      <p id="Display"></p>
    </body>
    
    </html>
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search