Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

A Modern Vanilla JavaScript Throttle To Replace Lodash

I'm using this function from You-Dont-Need-Lodash-Underscore^ydn^^ to throttle the color selection sliders for my OKLHC Color Picker to prevent performance issues:

JavaScript

function throttle(func, timeFrame) {
  var lastTime = 0;
  return function (...args) {
      var now = new Date();
      if (now - lastTime >= timeFrame) {
          func(...args);
          lastTime = now;
      }
  };
}

const throttleUpdate = throttle((event) => {
  document.querySelector('.exampleOut').innerHTML =
    event.target.value
}, 50)

document.addEventListener('DOMContentLoaded', () => {
  document.querySelector(".exampleIn").addEventListener(
    'input', throttleUpdate
  )
})

HTML

0
<input class="exampleIn" type="range" 
  min="0" max="100" step="0.1" value="0" />

<div class="exampleOut">0</div>

Details

I'm making a Color Picker that uses "OKLCH" to choose the colors^picker^^. OKLCH is the name of a method for converting the values from the picker's sliders into the color itself. Traditional pickers use different methods (like "RGB" and "HSL"). The OKLCH method is nicer. Changing a slider changes the colors in a way that makes more intuitive sense^why^^.

I'm using four significant figures for the Chroma value. At that level, there's an individual value for every individual pixel on the slider. That, in turn, means that every littls movement of the slider causes a signal to be sent to update all the colors on the page. If you whip the slider back and forth it's more than the browser can handle and things bog down.

The fix is to add a "throttle" into the mix.

Throttling

Adding a throttle

uses sliders to control Lightness, Chroma, and Hue. There are several palettes on the page. All of which change when a slider is moved. It was immediately evident that using the default speed of the `change`` event listener caused problems. Things would bog down frequently.

The fix was to add this throttle into the mix:

JavaScript

When you wrap another function inside the `throttle`` it limits how much it's called based on the `timeFrame`` (which is in milliseconds). For example, check out this slider, and the three display values below it:

HTML

0
0
0
<input type="range" class="slider" min="0"
max="100" step="0.01" value="0"/>

<div class="out1">0</div>

<div class="out2">0</div>

<div class="out3">0</div>

JavaScript

const unthrottled = (event) => {
  document.querySelector(".out1").innerHTML = 
    event.target.value
}

const throttled1 = throttle((event) => {
  document.querySelector(".out2").innerHTML = 
    event.target.value
}, 300)

const throttled2 = throttle((event) => {
  document.querySelector(".out3").innerHTML = 
    event.target.value
}, 1500)


document.addEventListener("DOMContentLoaded", () => {
  document.querySelector(".slider").addEventListener(
    'input', unthrottled
  ) 
  document.querySelector(".slider").addEventListener(
    'input', throttled1
  ) 
  document.querySelector(".slider").addEventListener(
    'input', throttled2
  ) 

  document.querySelector(".slider").addEventListener(
    'change', (event) => {
      document.querySelector(".out1").innerHTML = 
        event.target.value
      document.querySelector(".out2").innerHTML = 
        event.target.value
      document.querySelector(".out3").innerHTML = 
        event.target.value
    }
  ) 
})

Footnotes

  • (id:picker)

    I'm still working on it at the time of this post, but it's already one of the favorite things I've built. That's as much to do with the way I'm writing the code (which I think I'm going to call "YAGINP JS" for "You Ain't Gonna Need It Philosophy JS"). Bascially, it's a little set of functions that act as a library for manipulatinng the DOM. Combined with Neopoligen it's been a delight to work with.

  • (id:ydn)

    From the page: Lodash and Underscore are great modern JavaScript utility libraries, and they are widely used by Front-end developers. However, when you are targeting modern browsers, you may find out that there are many methods which are already supported natively thanks to ECMAScript5 [ES5] and ECMAScript2015 [ES6]. If you want your project to require fewer dependencies, and you know your target browser clearly, then you may not need Lodash/Underscore.

  • (id:why)

References