Back to JavaScript Performance

Cache Repeated Function Calls

javascriptcachememoizationperformance
28.0k🕒 2026-06-10Source ↗

Install this skill

npx skills add vercel-labs/agent-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

Caching repeated function calls optimizes performance by storing the output of expensive computations in a persistent data structure, typically a module-level Map. When the application requests the same result for a set of inputs, the system retrieves the value directly from memory instead of re-executing logic. This pattern minimizes redundant CPU cycles, particularly during high-frequency operations like list rendering, data transformation, or heavy string manipulation. By keeping the cache outside of the component lifecycle, the data remains accessible across event handlers, standard utility functions, and background services without the constraints of React hooks. This approach ensures consistent behavior across the codebase and prevents the performance bottlenecks often introduced by naive recalculation methods inside tight loops or frequently updated UI components.

When to Use This Skill

  • Transforming large arrays of strings into slugs or formatted IDs
  • Processing complex client-side filter logic for large data sets
  • Checking authentication status or session cookies repeatedly
  • Calculating expensive layout metrics inside list mapping functions

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • Optimize this function to stop redundant calculations
  • How do I prevent re-running this logic during list renders?
  • Implement a module-level cache for these repeated function calls
  • Speed up this expensive transformation logic in my loop
  • Cache the results of this helper function globally

What this skill does

  • Stores computed results in memory using a Map for O(1) retrieval
  • Preserves cached state outside the component render lifecycle
  • Supports arbitrary utility functions and event-driven logic
  • Enables manual cache invalidation for dynamic data updates
  • Reduces total execution time for deterministic high-latency operations

When not to use it

  • When the function relies on volatile external state that changes frequently
  • When the input space is infinite and could lead to memory bloat
  • When the function execution cost is lower than the Map lookup overhead

Example workflow

  1. Identify a pure function executed repeatedly with identical inputs
  2. Declare a module-scoped Map to store input-output pairs
  3. Create a wrapper function that checks the Map before executing the original logic
  4. Update the wrapper to store the computation result in the Map if not present
  5. Replace existing function calls with the new cached wrapper
  6. Implement an invalidation mechanism if the underlying data source changes

Prerequisites

  • Deterministic functions (pure functions)
  • Input values that are serializable or cacheable keys

Pitfalls & limitations

  • !Memory leaks if the Map grows indefinitely with unique keys
  • !Stale data if the underlying source changes without cache clearing
  • !Complexity in managing cache lifetime compared to reactive hooks

FAQ

Why use a Map instead of React.useMemo?
React.useMemo is limited to component lifecycles, whereas a module-level Map works in utility files, event handlers, and across any part of the application.
How do I clear the cache?
Since the Map is module-scoped, you can simply call .clear() on it or set it to a new empty Map when you need to invalidate stale entries.
Does this work for asynchronous functions?
You can cache Promises returned by async functions, though you must handle the risk of caching a rejected promise or race conditions.
Is this approach thread-safe?
JavaScript is single-threaded, so standard Map operations are safe. However, ensure your cache logic handles concurrency if your application architecture introduces non-linear execution.

How it compares

Unlike generic memoization that binds to UI lifecycles, this manual pattern provides global, persistent storage that remains performant in non-component environments.

Source & trust

28k stars🕒 Updated 2026-06-10
📄 Full skill instructions — original source: vercel-labs/agent-skills
## Cache Repeated Function Calls

Use a module-level Map to cache function results when the same function is called repeatedly with the same inputs during render.

**Incorrect (redundant computation):**

function ProjectList({ projects }: { projects: Project[] }) {
return (
<div>
{projects.map(project => {
// slugify() called 100+ times for same project names
const slug = slugify(project.name)

return <ProjectCard key={project.id} slug={slug} />
})}
</div>
)
}


**Correct (cached results):**

// Module-level cache
const slugifyCache = new Map<string, string>()

function cachedSlugify(text: string): string {
if (slugifyCache.has(text)) {
return slugifyCache.get(text)!
}
const result = slugify(text)
slugifyCache.set(text, result)
return result
}

function ProjectList({ projects }: { projects: Project[] }) {
return (
<div>
{projects.map(project => {
// Computed only once per unique project name
const slug = cachedSlugify(project.name)

return <ProjectCard key={project.id} slug={slug} />
})}
</div>
)
}


**Simpler pattern for single-value functions:**

let isLoggedInCache: boolean | null = null

function isLoggedIn(): boolean {
if (isLoggedInCache !== null) {
return isLoggedInCache
}

isLoggedInCache = document.cookie.includes('auth=')
return isLoggedInCache
}

// Clear cache when auth changes
function onAuthChange() {
isLoggedInCache = null
}


Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.

Reference: [How we made the Vercel Dashboard twice as fast](https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast)

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/js-cache-function-results/
  3. Save the file as SKILL.md
  4. 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/js-cache-function-results/SKILL.md
  • Cursor: ~/.cursor/skills/vercel-labs/agent-skills/js-cache-function-results/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/vercel-labs/agent-skills/js-cache-function-results/SKILL.md

🚀 Install with CLI:
npx skills add vercel-labs/agent-skills

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid javascript performance issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under JavaScript Performance and is published by Vercel Engineering, maintained in vercel-labs/agent-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.