Throttling

Limit execution frequency.

Handler runs at most once every 500ms

clicks: 0   handler ran: 0

html

<div class="thr" data-interval="500">
  <button type="button" class="thr__btn" style="background:#BFD9F2;">Click rapidly</button>
  <p class="thr__interval">Handler runs at most once every 500ms</p>
  <p class="thr__status" role="status">clicks: 0 &nbsp; handler ran: 0</p>
</div>
<script>(function () {
  var el = document.querySelector(".thr");
  if (!el) return;
  var interval = Number(el.dataset.interval);
  var btn = el.querySelector(".thr__btn");
  var status = el.querySelector(".thr__status");
  var clicks = 0, ran = 0, last = 0;
  btn.addEventListener("click", function () {
    clicks++;
    var now = Date.now();
    if (now - last >= interval) {
      last = now;
      ran++;
    }
    status.textContent = "clicks: " + clicks + "   handler ran: " + ran;
  });
})();</script>
<style>
.thr { font: 13px/1.5 system-ui, sans-serif; color: #241430; background: #FAF7F2; padding: 18px; border-radius: 12px; width: 300px; box-sizing: border-box; }
.thr__btn { display: block; width: 100%; border: none; padding: 12px; border-radius: 8px; font: 600 13px system-ui, sans-serif; color: #241430; cursor: pointer; margin-bottom: 8px; }
.thr__interval { margin: 0 0 8px; font-size: 10px; color: #24143099; }
.thr__status { margin: 0; font-size: 12px; font-weight: 600; }
</style>

tailwind

<div class="thrtw font-sans text-[#241430] bg-[#FAF7F2] p-4.5 rounded-xl w-[300px] box-border" data-interval="500">
  <button type="button" class="thrtw__btn block w-full border-none py-3 rounded-lg font-semibold text-[13px] text-[#241430] cursor-pointer mb-2" style="background:#BFD9F2;">Click rapidly</button>
  <p class="m-0 mb-2 text-[10px] text-[#24143099]">Handler runs at most once every 500ms</p>
  <p class="thrtw__status m-0 text-xs font-semibold" role="status">clicks: 0 &nbsp; handler ran: 0</p>
</div>
<script>(function () {
  var el = document.querySelector(".thrtw");
  if (!el) return;
  var interval = Number(el.dataset.interval);
  var btn = el.querySelector(".thrtw__btn");
  var status = el.querySelector(".thrtw__status");
  var clicks = 0, ran = 0, last = 0;
  btn.addEventListener("click", function () {
    clicks++;
    var now = Date.now();
    if (now - last >= interval) {
      last = now;
      ran++;
    }
    status.textContent = "clicks: " + clicks + "   handler ran: " + ran;
  });
})();</script>

react

import { useRef, useState } from "react";

export function Throttling({
  intervalMs = 500,
  buttonLabel = "Click rapidly",
  accent = "#BFD9F2",
  showInterval = true,
}) {
  const [clicks, setClicks] = useState(0);
  const [ran, setRan] = useState(0);
  const last = useRef(0);
  const onClick = () => {
    setClicks((c) => c + 1);
    const now = Date.now();
    if (now - last.current >= intervalMs) {
      last.current = now;
      setRan((r) => r + 1);
    }
  };
  return (
    <div style={{ font: "13px/1.5 system-ui, sans-serif", color: "#241430", background: "#FAF7F2", padding: 18, borderRadius: 12, width: 300, boxSizing: "border-box" }}>
      <button type="button" onClick={onClick} style={{ display: "block", width: "100%", border: "none", padding: 12, borderRadius: 8, fontWeight: 600, fontSize: 13, color: "#241430", cursor: "pointer", marginBottom: 8, background: accent }}>{buttonLabel}</button>
      {showInterval && <p style={{ margin: "0 0 8px", fontSize: 10, color: "#24143099" }}>Handler runs at most once every {intervalMs}ms</p>}
      <p role="status" style={{ margin: 0, fontSize: 12, fontWeight: 600 }}>clicks: {clicks} &nbsp; handler ran: {ran}</p>
    </div>
  );
}