Skip to content

feat: throttle #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 25, 2025
Merged

feat: throttle #29

merged 4 commits into from
May 25, 2025

Conversation

stakbucks
Copy link
Member

🚀 feat: Add throttle functionality to event tracking

Summary

This PR introduces comprehensive throttle functionality to the event-tracker library, complementing the existing debounce feature. Throttling ensures that functions are called at most once during a specified time interval, which is essential for performance optimization in high-frequency events like scrolling, resizing, or rapid user interactions.

✨ Features Added

Core Throttle Implementation

  • throttle utility function (src/utils/throttle.ts)
    • Type-safe throttle function with configurable leading/trailing edge execution
    • Cancel and flush methods for fine-grained control
    • Full TypeScript support with proper type inference

Integration with Event Tracking System

  • Seamless API integration - throttle options work with all existing tracking methods
    • track.onClick({ action: "test" }, { throttle: { delay: 100 } })
    • trackWithSchema.onClick(params, { throttle: { delay: 100, trailing: true } })
  • Component-level support - all tracking components now accept throttle props
    • <Track.Click throttle={{ delay: 100 }} />
    • <Track.DOMEvent throttle={{ delay: 100, leading: false }} />
  • Performance optimization with useTimingCache hook for efficient function reuse

Configuration Options

interface ThrottleConfig {
  delay: number;           // Delay in milliseconds
  leading?: boolean;       // Execute on leading edge (default: true)
  trailing?: boolean;      // Execute on trailing edge (default: false)
}

🔄 Key Differences from Debounce

Feature Debounce Throttle
Execution Pattern Delays execution until quiet period Limits execution frequency
Leading Edge Default false true
Trailing Edge Default true false
Use Case Search input, form validation Scroll events, button spam prevention

📝 Usage Examples

Basic Usage

// Throttle click events to prevent spam
track.onClick?.(
  { action: "button_click" }, 
  { throttle: { delay: 1000 } }
);

// Schema-based tracking with throttle
trackWithSchema.onClick?.(
  { schema: "clickSchema", params: { action: "purchase" } },
  { throttle: { delay: 500, leading: true, trailing: true } }
);

Component Usage

// Throttle rapid clicks on buttons
<Track.Click 
  params={{ action: "add_to_cart" }} 
  throttle={{ delay: 1000 }}
>
  <button>Add to Cart</button>
</Track.Click>

// Throttle scroll events for impression tracking
<Track.DOMEvent 
  type="onScroll" 
  params={{ section: "product_list" }}
  throttle={{ delay: 100, trailing: true }}
>
  <div>Scrollable Content</div>
</Track.DOMEvent>

Advanced Configuration

// Leading edge execution (immediate response)
{ throttle: { delay: 100, leading: true, trailing: false } }

// Trailing edge execution (delayed response)
{ throttle: { delay: 100, leading: false, trailing: true } }

// Both edges (immediate + delayed)
{ throttle: { delay: 100, leading: true, trailing: true } }

🏗️ Implementation Details

Type Safety

  • Full TypeScript integration with ThrottleConfig and ThrottledFunction interfaces
  • Union type support in TrackingOptions for both debounce and throttle
  • Type-safe function parameter preservation

Performance Optimizations

  • Function Caching: useTimingCache hook prevents creating new throttled instances on every render
  • Memory Management: Proper cleanup with cancel/flush methods
  • Edge Case Handling: Zero delay, rapid calls, and mixed throttled/non-throttled scenarios

Backward Compatibility

  • ✅ All existing APIs work unchanged
  • ✅ No breaking changes to existing debounce functionality
  • ✅ Graceful fallback when throttle options are not provided

🧪 Testing

Comprehensive test coverage with 20+ test cases covering:

  • ✅ Basic throttling behavior (leading/trailing edges)
  • ✅ Cancel and flush methods
  • ✅ Edge cases (zero delay, rapid calls)
  • ✅ Integration with React components
  • ✅ Function caching and memory optimization
  • ✅ Mixed throttled/non-throttled scenarios
  • ✅ Priority handling (debounce takes precedence when both specified)

🔧 Technical Architecture

File Structure

@stakbucks stakbucks self-assigned this May 25, 2025
@stakbucks stakbucks added the enhancement New feature or request label May 25, 2025
@stakbucks stakbucks merged commit 9153831 into main May 25, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant