JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html>
    <body>
        <h1>Blocking vs Non-blocking Operations Demo</h1>
        <p>This demo illustrates how JavaScript operations block the UI during intensive blocking operations, like for example, loops</p>
        <p>In contrast, this demo also shows how to use timeouts to "break" the operation so that the interface will continue to be responsive even with an operation ongoing</p>
        <p>To start, click either a Sync Operation or Async Operation. This will loop until 500000, show the count on the text box and display a message. Also, while on that operation, try adding "foo"</p>
        <input type="text" id="counter">
        <input type="button" id="syncop" value="Do A Sync Operation">
        <input type="button" id="asyncop" value="Do An Async Operation">
        <input type="button" id="addfoo" value="Add Foo While Doing Operation">
        <ul id="fooList"></ul>
    
        <script>
            window.onload = function(){
            
                var fooList = document.getElementById('fooList');
                var counter = document.getElementById('counter');
                
                var syncButton = document.getElementById('syncop');
                var asyncButton = document.getElementById('asyncop');
                
                var loopLength = 500000;
                
                //button toggle
                function disabled(on){
                    syncButton.disabled = on ? 'disabled' : '';
                    asyncButton.disabled = on ? 'disabled' : '';
                }
                
                //adds a new item to the list
                function addItem(text){
                    var newFoo = document.createElement('li');
                    var foo = document.createTextNode(text);
                    newFoo.appendChild(foo);
                    fooList.appendChild(newFoo);
                }
                
                //adds the foo
               ...