Creating a continuous loop in JavaScript without freezing the browser

I need help with making a loop that keeps running without breaking my webpage. I want to create a button that starts running some code over and over when clicked, and stops when clicked again.

Here’s what I have so far for the button toggle:

const toggleBtn = document.querySelector("#loopToggle");
let isActive = false;

toggleBtn.addEventListener("click", function(){
    if (!isActive) {
        console.log('Starting the loop');
        // need to begin continuous execution here
        isActive = true;
    } else {
        console.log('Stopping the loop');
        // need to end continuous execution here
        isActive = false;
    }
});

The problem is I can’t figure out how to make a loop that runs forever without making the browser freeze up. What’s the right way to do this?

I ran into this exact issue when building a real-time data monitor for a client project. The key is using setInterval and clearInterval instead of traditional loops. Here’s how you can modify your code:

const toggleBtn = document.querySelector("#loopToggle");
let isActive = false;
let intervalId = null;

toggleBtn.addEventListener("click", function(){
    if (!isActive) {
        console.log('Starting the loop');
        intervalId = setInterval(() => {
            // Your repeating code goes here
            console.log('Loop iteration running...');
        }, 100); // Runs every 100ms
        isActive = true;
    } else {
        console.log('Stopping the loop');
        clearInterval(intervalId);
        isActive = false;
    }
});

The setInterval approach works because it schedules your code to run at regular intervals without blocking the main thread. This keeps your browser responsive while maintaining continuous execution. I typically use 16ms intervals for smooth animations or 100-1000ms for less frequent updates depending on what the loop needs to accomplish.

Another approach worth considering is requestAnimationFrame if your loop involves any visual updates or animations. I discovered this method when working on a canvas-based game where setInterval caused stuttering issues.

const toggleBtn = document.querySelector("#loopToggle");
let isActive = false;
let animationId = null;

function gameLoop() {
    if (isActive) {
        // Your continuous code here
        console.log('Animation frame loop running...');
        animationId = requestAnimationFrame(gameLoop);
    }
}

toggleBtn.addEventListener("click", function(){
    if (!isActive) {
        console.log('Starting the loop');
        isActive = true;
        gameLoop();
    } else {
        console.log('Stopping the loop');
        cancelAnimationFrame(animationId);
        isActive = false;
    }
});

The main advantage is that requestAnimationFrame syncs with the browser’s refresh rate (usually 60fps) and automatically pauses when the tab becomes inactive, which saves system resources. For non-visual tasks though, setInterval is typically more appropriate.

setTimeout with recursion works too if you need more control over timing. just call the function again inside itself when isActive is true. prevents the browser lockup issue while being more flexible than setInterval imo.