BRUCE_FEBRUCE_FE

EN/CH Mode

BRUCE_FE JS Interview Notes - Implement Throttle Function for Data Fetching Optimization

Learn how to implement throttle functions to control high-frequency event trigger rates, optimize scroll loading, frequent API requests, and other frontend performance issues.

影片縮圖

Lazy to read articles? Then watch videos!

What is Throttle?

Throttle is an optimization technique used to limit the execution frequency of functions over a period of time. Unlike debounce which only executes the last operation, throttle ensures that a function executes at most once within a specified time interval.

Core principle: Execute the function only once within a fixed time interval, regardless of how frequently the event is triggered, similar to controlling water flow from a faucet.

Throttle Application Scenarios

  • 1. Scroll event handling (such as scroll loading, fixed navigation bar)
  • 2. Listen to resize events to adjust layout
  • 3. Update interface during drag operations
  • 4. Frequent data requests or API calls
  • 5. Key response in real-time games
  • 6. Canvas drawing operations

Basic Implementation: Throttle Function

Below are two common implementation methods: timestamp method and timer method.

Method 1: Timestamp Implementation

function throttle(func, delay = 300) {
  let lastTime = 0;
  
  return function(...args) {
    const now = Date.now();
    
    // Check if enough time has passed since last execution
    if (now - lastTime >= delay) {
      func.apply(this, args);
      lastTime = now;
    }
  };
}

Method 2: Timer Implementation

function throttle(func, delay = 300) {
  let timer = null;
  
  return function(...args) {
    // If no timer is running, set a new timer
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

Method 3: Comprehensive Method (No Loss of First and Last Calls)

function throttle(func, delay = 300) {
  let timer = null;
  let lastTime = 0;
  
  return function(...args) {
    const now = Date.now();
    const remaining = delay - (now - lastTime);
    
    // Clear timer and execute immediately
    if (remaining <= 0) {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      
      func.apply(this, args);
      lastTime = now;
    } else if (!timer) {
      // Set timer to ensure the last operation is executed
      timer = setTimeout(() => {
        func.apply(this, args);
        lastTime = Date.now();
        timer = null;
      }, remaining);
    }
  };
}

Practical Application: Throttle Optimization for Data Requests

Below are some practical applications of throttle functions in data requests:

Case 1: Scroll Loading Data

// Load more data when page scrolls
function loadMoreData() {
  console.log('Loading more data...');
  
  // Calculate scroll position
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
  const clientHeight = document.documentElement.clientHeight || window.innerHeight;
  
  // Load more when scrolling near the bottom
  if (scrollTop + clientHeight >= scrollHeight - 100) {
    fetch('/api/posts?page=' + currentPage)
      .then(response => response.json())
      .then(data => {
        // Process data and add to page
        displayData(data);
        currentPage++;
      });
  }
}

// Use throttle function to optimize scroll events
const throttledLoadMore = throttle(loadMoreData, 500);

window.addEventListener('scroll', throttledLoadMore);

Case 2: Real-time Search Suggestions

// Send search request
function fetchSearchResults(query) {
  console.log('Search:', query);
  
  fetch(`/api/search?q=${encodeURIComponent(query)}`)
    .then(response => response.json())
    .then(results => {
      // Update search results display
      updateSearchResults(results);
    })
    .catch(error => {
      console.error('Search error:', error);
    });
}

// Use throttle function to limit request frequency
const throttledSearch = throttle(fetchSearchResults, 300);

// Bind to input event
document.querySelector('#search-input').addEventListener('input', (e) => {
  const query = e.target.value.trim();
  if (query.length > 2) {
    throttledSearch(query);
  }
});

Throttle vs Debounce Comparison

Both throttle and debounce are methods to limit event processing frequency, but they are suitable for different scenarios:

FeatureThrottleDebounce
Execution TimingExecute at most once within a fixed timeExecute after waiting for specified time, restart timer if triggered again during wait
Execution FrequencyStable fixed frequencyExecute only once after events stop
Applicable ScenariosScroll loading, drag effects, frequent API callsSearch suggestions, form validation, window resizing
AnalogyFaucet flow controlElevator waits for everyone to enter before starting