Throttling function: so your plugin doesn't burn dem WUs

I listened to @keith, stopped optimizing for what didn’t matter, decided to focus on solving an actual problem: autobinding, aka My Nemesis.

When a user set the Tiptap plugin to autobinding, it would start behaving erratically. It would get worse with multiple Tiptaps on a single page. I tried both a poor-man’s debounce function and raw-dogging it. Those didn’t work. Then I found this pretty boy singing the praises of throttling. Naturally, I copied-pasta’ed his code. It worked!

Why and how it works:

Putting it out there so you guys can poke holes at this mess and – hopefully – someone else can benefit from it.

// throttle function: to take it easy on the autobinding.
// 1. writes to autobinding
// 2. then waits a certain delay
// 3. then writes again if the user generated more changes
// source: from https://blog.webdevsimplified.com/2022-03/debounce-vs-throttle/code

instance.data.throttle = (callback, delay = 1000) => {

    instance.data.shouldWait = false
    instance.data.timeoutFunc = () => {

        if (instance.data.waitingArgs == null) {
            instance.data.shouldWait = false

        } else {
            callback(...instance.data.waitingArgs)
            instance.data.waitingArgs = null
            setTimeout(instance.data.timeoutFunc, delay)

        }
    }

    return (...args) => {
        if (instance.data.shouldWait) {            
            instance.data.waitingArgs = args
            return
        }

        callback(...args)
        instance.data.shouldWait = true

        setTimeout(instance.data.timeoutFunc, delay)
    }
}

FYI, this is how I implement it in Tiptap:

instance.data.writeToAutobinding = instance.data.throttle(() => {
  instance.publishAutobinding(instance.data.editor.getHTML());
}, 2000);
3 Likes

I would say this is a very cool idea for plugins like yours that are inputs, @rico.trevisan! My only quick suggestion about this would be to make it such that there’s a default delay but allow adjustment of it in the main interface.

3 Likes