Deduplicate Global Event Listeners
Install this skill
npx skills add vercel-labs/agent-skillsWorks across Claude Code, Cursor, Codex, Copilot & Antigravity
The Deduplicate Global Event Listeners skill optimizes React applications by centralizing window-level event handling. Standard implementations of event listeners in hooks often create redundant bindings whenever components remount or multiple instances of the same hook are active, leading to memory bloat and performance degradation. By integrating SWR's subscription model with a centralized registry, this pattern ensures that a single event listener handles all active callbacks for a specific event type. This approach prevents the 'N instances equal N listeners' problem, consolidating cross-component communication into one window event stream. It maintains granular control over individual callbacks while reducing the total number of browser-level event attachments, resulting in cleaner event propagation and more predictable behavior during complex user interactions like keyboard shortcuts or global window resizing.
When to Use This Skill
- •Implementing global keyboard shortcuts across distributed components
- •Managing multiple window resize tracking hooks without performance drops
- •Monitoring mouse tracking state for interactive dashboard elements
- •Synchronizing browser focus/blur events across independent widgets
How to Invoke This Skill
Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:
- “Optimize my global event listeners in React
- “How do I prevent duplicate window event listeners
- “Use SWR to manage event listener lifecycle
- “Centralize window event handlers for multiple components
- “Fix memory usage of useEffect keyboard shortcuts
What this skill does
- •Consolidates multiple window event listeners into a single attachment
- •Uses a central Map registry to manage active subscriber callbacks
- •Integrates SWR subscription lifecycle with native DOM event handling
- •Prevents memory leaks from orphaned window event listeners
- •Supports multiple concurrent subscribers for a single event type
When not to use it
- ✕When components require unique event capture phases or specific stopPropagation logic
- ✕In simple applications where only one instance of an event listener is ever created
- ✕If the event frequency is low enough that standard useEffect listeners do not impact performance
Example workflow
- Define a module-level Map to store callback sets keyed by event identifier
- Create a custom hook that registers the current callback into the Map on mount
- Implement the useSWRSubscription hook to attach a single shared window listener
- Update the shared handler to iterate over the Map and execute relevant callbacks
- Cleanup the registry on component unmount to prevent stale callback execution
Prerequisites
- –swr library
- –React Hooks knowledge
- –Understanding of DOM event propagation
Pitfalls & limitations
- !Forgetting to clean up the Set entry in the Map leads to memory leaks
- !Closure staleness if callbacks rely on out-of-date state values
- !The central registry is module-scoped, so it persists for the lifetime of the application
FAQ
How it compares
Manually attaching listeners in every component results in linear performance degradation, whereas this subscription pattern ensures constant complexity regardless of the number of active components.
📄 Full skill instructions — original source: vercel-labs/agent-skills
Use
useSWRSubscription() to share global event listeners across component instances.**Incorrect (N instances = N listeners):**
function useKeyboardShortcut(key: string, callback: () => void) {
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.metaKey && e.key === key) {
callback()
}
}
window.addEventListener('keydown', handler)
return () => window.removeEventListener('keydown', handler)
}, [key, callback])
}When using the
useKeyboardShortcut hook multiple times, each instance will register a new listener.**Correct (N instances = 1 listener):**
import useSWRSubscription from 'swr/subscription'
// Module-level Map to track callbacks per key
const keyCallbacks = new Map<string, Set<() => void>>()
function useKeyboardShortcut(key: string, callback: () => void) {
// Register this callback in the Map
useEffect(() => {
if (!keyCallbacks.has(key)) {
keyCallbacks.set(key, new Set())
}
keyCallbacks.get(key)!.add(callback)
return () => {
const set = keyCallbacks.get(key)
if (set) {
set.delete(callback)
if (set.size === 0) {
keyCallbacks.delete(key)
}
}
}
}, [key, callback])
useSWRSubscription('global-keydown', () => {
const handler = (e: KeyboardEvent) => {
if (e.metaKey && keyCallbacks.has(e.key)) {
keyCallbacks.get(e.key)!.forEach(cb => cb())
}
}
window.addEventListener('keydown', handler)
return () => window.removeEventListener('keydown', handler)
})
}
function Profile() {
// Multiple shortcuts will share the same listener
useKeyboardShortcut('p', () => { /* ... */ })
useKeyboardShortcut('k', () => { /* ... */ })
// ...
}How to Use This Skill Unit
Option A: Project-Specific (Recommended)
- Click "Download" above
- In your project, create the directory:
.agent/skills/client-event-listeners/ - Save the file as
SKILL.md - The agent will automatically discover the skill based on its description.
Option B: Global Installation (All Agents)
Save the file to these locations to make it available across all projects:
- Claude Code:
~/.claude/skills/vercel-labs/agent-skills/client-event-listeners/SKILL.md - Cursor:
~/.cursor/skills/vercel-labs/agent-skills/client-event-listeners/SKILL.md - Antigravity:
~/.gemini/antigravity/skills/vercel-labs/agent-skills/client-event-listeners/SKILL.md
🚀 Install with CLI:npx skills add vercel-labs/agent-skills