worker-timers

repository·master·Indexed 20 days ago

https://github.com/chrisguttandin/worker-timers

A replacement for the standard Web WindowTimers API (setInterval and setTimeout) that uses Web Workers to prevent timer throttling in unfocused browser windows. It provides a drop-in replacement for native timer functions to ensure high-frequency timers continue running when the browser window loses focus.

Tokens
1.1K
Snippets
4
Records
6
Agent score
21%

What's inside worker-timers

  1. How worker-timers handles intervals and timeouts

    master

    Unlike native WindowTimers which use a single list for all timers, worker-timers maintains two separate internal lists: one for intervals and one for timeouts.

    Important: You cannot use clearTimeout() to cancel an interval, nor can you use clearInterval() to cancel a timeout. Doing so will fail to cancel the intended timer because the IDs are stored in different lists.

    const periodicWork = () => {};
    
    // This will stop the interval.
    const windowId = window.setInterval(periodicWork, 100);
    window.clearTimeout(windowId);
    
    // This will NOT cancel the interval. It may cancel a timeout instead.
    const workerId = setInterval(periodicWork, 100);
    clearTimeout(workerId);
  2. Server-Side Rendering (SSR) considerations

    master

    worker-timers is designed for the browser and requires Web Worker support. It does not provide a fallback for environments like Node.js.

    If you are using SSR (e.g., in a React app), you must ensure that worker-timers is replaced with standard timers or a compatible shim on the server side to prevent errors, as the server environment does not support Web Workers.

  3. Using worker-timers with Angular and Zone.js

    master

    When using worker-timers in an Angular application, Zone.js (which handles change detection) will not automatically detect callback invocations because it only patches the native setInterval() and setTimeout() functions.

    To ensure the UI updates correctly, you must manually notify Angular about state changes that occur inside a worker-timers callback.

  4. Use worker-timers in your code

    master

    Import the exported functions from worker-timers. The API is designed to be a drop-in replacement for the global setInterval() and setTimeout() functions, maintaining the same signatures.

    import { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers';
    
    const intervalId = setInterval(() => {
        // do something many times
    }, 100);
    
    clearInterval(intervalId);
    
    const timeoutId = setTimeout(() => {
        // do something once
    }, 100);
    
    clearTimeout(timeoutId);
  5. Use worker-timers for setInterval and setTimeout

    master

    The worker-timers module provides a drop-in replacement for the standard browser setInterval and setTimeout APIs, but executes the timers within a Web Worker. This prevents timers from being throttled or paused when the main thread is busy or the tab is in the background.

    To use these functions, import them from the module. They follow the same signature as the native window APIs:

    • setTimeout(callback, delay, ...args): Executes the callback after the specified delay.
    • setInterval(callback, delay, ...args): Repeatedly executes the callback with a fixed time delay between each call.
    • clearTimeout(timerId): Cancels a timeout previously established by setTimeout.
    • clearInterval(timerId): Cancels a interval previously established by setInterval.
    import { setInterval, setTimeout, clearInterval, clearTimeout } from 'worker-timers';
    
    // Example: Set a timeout
    const timerId = setTimeout(() => {
      console.log('This runs in a worker-backed timer');
    }, 1000);
    
    // Example: Clear a timeout
    clearTimeout(timerId);
    
    // Example: Set an interval
    const intervalId = setInterval(() => {
      console.log('This interval is not throttled by the main thread');
    }, 5000);
    
    // Example: Clear an interval
    clearInterval(intervalId);