npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

custom-idle-queue

v3.0.1

Published

Optimize the speed of important tasks on limited ressources

Downloads

60,213

Readme

Custom Idle Queue

This is a npm-module that lets you optimize the performance of important tasks by delaying background-tasks. It works a bit like requestIdleCallback but instead of fetching idle-time of the CPU, you can use this for any given limited ressource.

Quickstart

In this example we define database-requests as limited ressource. We create an idleQueue arround all calls to the ressource to ensure our importantTask is as fast as possible and the backgroundTask only runs when no importantTask is using the database.

npm install custom-idle-queue --save

// require
const { IdleQueue } = require('custom-idle-queue');

// OR import
import { IdleQueue } from 'custom-idle-queue';

// create a new queue
const myQueue = new IdleQueue();


// wrap all calls to your limited ressource
const readFromDatabase = key => myQueue.wrapCall(
    () => pseudoDatabaseModule.get(key)
);
const writeToDatabase = (key, value) => myQueue.wrapCall(
    () => pseudoDatabaseModule.set(key, value);
);
const deleteFromDatabase = (key) => myQueue.wrapCall(
    () => pseudoDatabaseModule.delete(key, value);
);

// this is the important task
const importantTask = async function increaseClickNumber() {
    const oldNumber = await readFromDatabase('nr');
    const newNumber = oldNumber++;
    await writeToDatabase('nr', newNumber);
    await writeToDatabase('time_' + newNumber, new Date().getTime());
    return newNumber;
};

// this is the background task
const backgroundTask = async function cleanUpOldClicks() {
    const newest = await readFromDatabase('nr');
    const limitDate = new Date().getTime() - 1000*60*60;
    for (let i = 0; i < newest; i++) {
        const date = await readFromDatabase('time_' + i);
        if(date < limitDate){
            await deleteFromDatabase('time_' + i);
        }
    }
}

// we now run the backgroundTask in an intervall without slowing down the importantTask
(async() => {
    while(true){
        await myQueue.requestIdlePromise(); // wait until database-requests in idle
        await backgroundTask();

        await new Promise(res => setTimeout(res, 2000)); // wait 2 seconds
    }
})();

// if we now run the importantTask, it will not be slowed down by the backgroundTask
document
    .querySelector('#myButton')
    .addEventListener('click', () => {
        const newNr = await importantTask();
        labelDomElement.innerHTML = newNr.toString();
    });

// You can find the full documentation here https://github.com/pubkey/custom-idle-queue/blob/master/docs.md

Use cases

This module can be used on any limited ressource like

  • HTTP-Requests
  • Database-Calls
  • Service-Worker-Calls
  • Animations

Limitations

  • IdleQueue cannot predict the future

When you start a backgroundTask first and the importantTask afterwards, the backgroundTask will slow down the importantTask because it is already running. To prevent this, you should use requestIdlePromise as granular as possible. The backgroundTask-function from the example would be better when it awaits the idle-state before each usage of the limited ressource. This will ensure that the backgroundTask will be paused until the importantTask has finished.

// this is the background task
const backgroundTask = async function cleanUpOldClicks() {
    await myQueue.requestIdlePromise(); // request idle-state each time
    const newest = await readFromDatabase('nr');
    const limitDate = new Date().getTime() - 1000*60*60;
    for (let i = 0; i < newest; i++) {
        await myQueue.requestIdlePromise(); // request idle-state each time
        const date = await readFromDatabase('time_' + i);
        if(date < limitDate){
            await myQueue.requestIdlePromise(); // request idle-state each time
            await deleteFromDatabase('time_' + i);
        }
    }
}
  • You cannot optimize CPU-only ressources

Because javascript runs in a single process, it doesn't make sense to define CPU as limited ressource. For example if you have a CPU-only-Function like calculatePrimeNumber, you should not limit the access to the function with an idle-queue because at the time you call idleQueue.lock() or idleQueue.wrapCall(), the process will instantly run calculatePrimeNumber before it even can change the idle-queue state.

Browser-Support

This module is using the Promise- and the Map-Object. If your runtime does not support them, you have to add them via polyfills.

Read the full documentation here