Notoriously Problematic Merge

    TypeScript icon, indicating that this package has built-in type declarations

    1.1.0 • Public • Published

    Ticker Service

    This service is supposed to override all the internal JavaScript timing functions (setTimeout, setInterval and requestAnimationFrame) in order to use a single animation loop to keep all of them in sync.

    The ticker will also add a series of new timing functions that may make your life a little bit easier.

    Timing Functions

    The original timing functions will work exactly the same as before, but as the animation loop is based on the original requestAnimationFrame, timeouts and intervals may not be as precise as they used to be, the callbacks will only be executed when a frame is generated by the browser.

    If for any reason you need that precision back, you can restore the originals by setting:

    ticker.useScopeFunctions = true;

    The followings are new timing functions that the service will add to your project:


    This is very much similar to an interval, except you can limit the execution to a specific amount of executions.

    const id = setCounter((data, delta, count) => {
        console.log(data.test, count);
    }, 100, 5, {"test": "My Test Data"});

    The above will print each of the following lines every 100ms.

    My Test Data, 0
    My Test Data, 1
    My Test Data, 2
    My Test Data, 3
    My Test Data, 4

    Unless you decide to cancel it with the following call.



    This function will create a simple animation loop, allowing you to choose the frame rate at which the callback will be executed at.

    let id = setAnimationLoop(delta => console.log(delta));

    This will print the delta time since the last frame at the maximum frame rate provided by the browser (usually 60fps).

    let id = setAnimationLoop(delta => console.log(delta), 30);

    The above will instead run at 30 frame per seconds. You will be able to stop the loop as follow:


    Working Asynchronously

    The service will provide you with two functions that will allow you to work async:


    The sleep function will delay the execution of a specific amount of time. It will return a promise that will be resolved after the requested time.

    async function myFunction() {
        // Do something
        await sleep(5000);
        // Do something else

    Or if you prefer the chain syntax.

    sleep(5000).then(() => console.log("I'm awake!"));

    Both way you will have a deferred execution of 5 seconds.


    The frame function is similar to the sleep one, with the only difference that it won't take any parameters and it will just wait for the next available frame.

    async function myFunction() {
        // Do something
        await frame();
        // Oh look, a new frame has been rendered


    Using the asynchronous functions will allow you to create intervals or animation loops without the need of a callback.

    async function myInterval() {
        for (let i = 0; i < 100; i++) {
            console.log("Async Interval", i);
            await sleep(100);
    async function myAnimationLoop() {
        while (true) {
            // Make sure that a frame has been provided by the browser.
            await frame();
            // Render something!
            console.log("I'm rendering!");

    Service Control

    You can handle the state of the service using the start and stop methods. The good thing is that all the timeouts or interval will be stopped as well, so that when the service is restarted, they will restart from the exact point they were stopped.

    const initial =;
    setTimeout(() => {
        const final =;
        console.log("Delta", final-initial);
    }, 3000);
    // Stop the service (which will automatically restore the original timing functions).
    // Use the original timeout to restart the service.
    setTimeout(() => ticker.start(), 1000);

    The timeout created at the beginning should run for 3 seconds, but because the service has been stopped and restarted after a second, the function will log a delta of 4 seconds (-ish).


    The service will provide you with a few properties that will allow you to check the state of your application:

    // Check the maximum frame rate provided by the browser.
    // Check the current application frame rate.
    // Check the average frame rate over the last couple of seconds.
    // Provide you with a score between 0 to 100 for your device performance.

    Pick this value as a guide as it is based on how many frames the browser is capable of rendering.

    You can use the score to decide if it's time to reduce the number of process that are running or to reduce the frame rate of your main loop to give the browser a little bit of breathing space.


    You can use npm to install the package

    npm install ticker-service

    or you can checkout the repository and build it on your own by calling

    npm run build

    And finally you just need to import the ticker in every module that needs it.

    // If installed through npm
    import ticker from 'ticker-service';
    // If built manually
    import ticker from './dist/ticker-service'
    // If you want to have it accessible outside modules, just export it into the Window object.
    self.ticker = ticker;


    npm i ticker-service

    DownloadsWeekly Downloads






    Unpacked Size

    102 kB

    Total Files


    Last publish


    • mcastiello