← Back to all hooks

useThrottle

Limit function execution frequency for performance optimization. Perfect for scroll, resize, and mouse events in high-frequency scenarios.

Live Demo

Compare regular vs throttled event handlers. Scroll in the box and resize your window to see the difference.

📊 Event Counters

Regular Scroll:0
Throttled Scroll:0
Regular Resize:0
Throttled Resize:0

📝 Event Log

No events yet. Try scrolling or resizing!

📜 Scrollable Area

Scroll inside this area to see the difference between regular and throttled event handlers.

Scroll item 1 - Keep scrolling to see throttling in action!
Scroll item 2 - Keep scrolling to see throttling in action!
Scroll item 3 - Keep scrolling to see throttling in action!
Scroll item 4 - Keep scrolling to see throttling in action!
Scroll item 5 - Keep scrolling to see throttling in action!
Scroll item 6 - Keep scrolling to see throttling in action!
Scroll item 7 - Keep scrolling to see throttling in action!
Scroll item 8 - Keep scrolling to see throttling in action!
Scroll item 9 - Keep scrolling to see throttling in action!
Scroll item 10 - Keep scrolling to see throttling in action!
Scroll item 11 - Keep scrolling to see throttling in action!
Scroll item 12 - Keep scrolling to see throttling in action!
Scroll item 13 - Keep scrolling to see throttling in action!
Scroll item 14 - Keep scrolling to see throttling in action!
Scroll item 15 - Keep scrolling to see throttling in action!
Scroll item 16 - Keep scrolling to see throttling in action!
Scroll item 17 - Keep scrolling to see throttling in action!
Scroll item 18 - Keep scrolling to see throttling in action!
Scroll item 19 - Keep scrolling to see throttling in action!
Scroll item 20 - Keep scrolling to see throttling in action!
Scroll item 21 - Keep scrolling to see throttling in action!
Scroll item 22 - Keep scrolling to see throttling in action!
Scroll item 23 - Keep scrolling to see throttling in action!
Scroll item 24 - Keep scrolling to see throttling in action!
Scroll item 25 - Keep scrolling to see throttling in action!
Scroll item 26 - Keep scrolling to see throttling in action!
Scroll item 27 - Keep scrolling to see throttling in action!
Scroll item 28 - Keep scrolling to see throttling in action!
Scroll item 29 - Keep scrolling to see throttling in action!
Scroll item 30 - Keep scrolling to see throttling in action!
Scroll item 31 - Keep scrolling to see throttling in action!
Scroll item 32 - Keep scrolling to see throttling in action!
Scroll item 33 - Keep scrolling to see throttling in action!
Scroll item 34 - Keep scrolling to see throttling in action!
Scroll item 35 - Keep scrolling to see throttling in action!
Scroll item 36 - Keep scrolling to see throttling in action!
Scroll item 37 - Keep scrolling to see throttling in action!
Scroll item 38 - Keep scrolling to see throttling in action!
Scroll item 39 - Keep scrolling to see throttling in action!
Scroll item 40 - Keep scrolling to see throttling in action!
Scroll item 41 - Keep scrolling to see throttling in action!
Scroll item 42 - Keep scrolling to see throttling in action!
Scroll item 43 - Keep scrolling to see throttling in action!
Scroll item 44 - Keep scrolling to see throttling in action!
Scroll item 45 - Keep scrolling to see throttling in action!
Scroll item 46 - Keep scrolling to see throttling in action!
Scroll item 47 - Keep scrolling to see throttling in action!
Scroll item 48 - Keep scrolling to see throttling in action!
Scroll item 49 - Keep scrolling to see throttling in action!
Scroll item 50 - Keep scrolling to see throttling in action!

💡 Try This:

  • Scroll rapidly in the blue box - notice how throttled events fire less frequently
  • Resize your browser window - see the difference in resize event counts
  • Throttled events improve performance by limiting function calls

Code Examples

Scroll Event Throttling

import { useThrottle, useEventListener } from "@uiblock/hooks";
import { useState } from "react";

export default function ScrollTracker() {
  const [scrollY, setScrollY] = useState(0);

  const throttledScrollHandler = useThrottle(() => {
    setScrollY(window.scrollY);
  }, 100); // Limit to once per 100ms

  useEventListener('scroll', throttledScrollHandler);

  return <div>Scroll position: {scrollY}px</div>;
}

Resize Event Throttling

import { useThrottle, useEventListener } from "@uiblock/hooks";
import { useState } from "react";

export default function WindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  });

  const throttledResizeHandler = useThrottle(() => {
    setWindowSize({
      width: window.innerWidth,
      height: window.innerHeight
    });
  }, 200);

  useEventListener('resize', throttledResizeHandler);

  return (
    <div>
      Window: {windowSize.width} x {windowSize.height}
    </div>
  );
}

API Calls with Throttling

import { useThrottle } from "@uiblock/hooks";

export default function SearchWithThrottle() {
  const [results, setResults] = useState([]);

  const throttledSearch = useThrottle(async (query) => {
    if (!query) return;
    
    const response = await fetch(`/api/search?q=${query}`);
    const data = await response.json();
    setResults(data);
  }, 500);

  return (
    <input
      onChange={(e) => throttledSearch(e.target.value)}
      placeholder="Search..."
    />
  );
}

How It Works

Here's the implementation:

import { useCallback, useRef } from 'react'

export function useThrottle<T extends (...args: any[]) => any>(
  callback: T,
  delay: number
): T {
  const lastRan = useRef<number>(0)
  const timeoutRef = useRef<NodeJS.Timeout | null>(null)

  return useCallback(
    ((...args: Parameters<T>) => {
      const now = Date.now()
      
      if (now - lastRan.current >= delay) {
        // Execute immediately if enough time has passed
        callback(...args)
        lastRan.current = now
      } else {
        // Clear existing timeout and set a new one
        if (timeoutRef.current) {
          clearTimeout(timeoutRef.current)
        }
        
        timeoutRef.current = setTimeout(() => {
          callback(...args)
          lastRan.current = Date.now()
        }, delay - (now - lastRan.current))
      }
    }) as T,
    [callback, delay]
  )
}

Key Features:

  • Executes immediately if enough time has passed
  • Schedules execution for remaining time if called too soon
  • Cancels previous scheduled executions
  • Preserves function signature and arguments

Throttle vs Debounce

⚡ Throttle (this hook)

  • Executes at regular intervals
  • Good for: scroll, resize, mouse move
  • Ensures consistent execution rate
  • First call executes immediately

⏱️ Debounce

  • Executes after activity stops
  • Good for: search, form validation
  • Waits for "quiet period"
  • Only last call executes

API Reference

Parameters

callback: T

Function to throttle

delay: number

Minimum time between executions in milliseconds

Returns

Throttled version of the callback function

💡 Use Cases

  • Scroll event handlers for parallax effects
  • Window resize handlers for responsive layouts
  • Mouse move tracking for interactive elements
  • API calls that shouldn't fire too frequently
  • Button click protection against rapid clicking
  • Real-time search with rate limiting
  • Game loop optimizations
  • Performance monitoring and analytics