Skip to content
Skillv1.0.0

figma-performance-tuning

Optimize Figma REST API performance with caching, partial fetches, and connection reuse. Use when experiencing slow API responses, reducing bandwidth for large files, or optimizing request throughput

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/figma-pack/skills/figma-performance-tuning/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill figma-performance-tuning. Copyright stays with the author (MIT).

Figma Performance Tuning

Overview

Optimize Figma REST API performance. Large Figma files can return multi-megabyte JSON responses. Key strategies: fetch only what you need, cache aggressively, and batch requests.

Prerequisites

  • Working Figma API integration
  • Understanding of your access patterns (which endpoints, how often)

Instructions

Step 1: Reduce Payload Size

// BAD: fetches the entire file tree (can be 10+ MB for large files)
const file = await fetch(`https://api.figma.com/v1/files/${fileKey}`, {
  headers: { 'X-Figma-Token': token },
}).then(r => r.json());

// GOOD: use depth parameter to limit tree depth
// depth=1 returns only pages (CANVAS nodes), not their children
const fileMeta = await fetch(
  `https://api.figma.com/v1/files/${fileKey}?depth=1`,
  { headers: { 'X-Figma-Token': token } }
).then(r => r.json());

// GOOD: fetch only specific nodes you need
const nodes = await fetch(
  `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${nodeIds.join(',')}`,
  { headers: { 'X-Figma-Token': token } }
).then(r => r.json());

// GOOD: use plugin_data or branch_data params only when needed
// By default, plugin data and branch data are NOT returned

Step 2: Response Caching

import { LRUCache } from 'lru-cache';

// File metadata changes rarely -- cache for 5 minutes
const fileCache = new LRUCache<string, any>({
  max: 100,
  ttl: 5 * 60 * 1000, // 5 minutes
});

async function getCachedFile(fileKey: string, token: string) {
  const cached = fileCache.get(fileKey);
  if (cached) return cached;

  const file = await fetch(
    `https://api.figma.com/v1/files/${fileKey}?depth=1`,
    { headers: { 'X-Figma-Token': token } }
  ).then(r => r.json());

  fileCache.set(fileKey, file);
  return file;
}

// Image URLs expire after 30 days -- cache them but with a shorter TTL
const imageUrlCache = new LRUCache<string, string>({
  max: 1000,
  ttl: 24 * 60 * 60 * 1000, // 1 day (well within 30-day expiry)
});

async function getCachedImageUrl(
  fileKey: string, nodeId: string, format: string, token: string
): Promise<string | null> {
  const cacheKey = `${fileKey}:${nodeId}:${format}`;
  const cached = imageUrlCache.get(cacheKey);
  if (cached) return cached;

  const data = await fetch(
    `https://api.figma.com/v1/images/${fileKey}?ids=${nodeId}&format=${format}`,
    { headers: { 'X-Figma-Token': token } }
  ).then(r => r.json());

  const url = data.images[nodeId];
  if (url) imageUrlCache.set(cacheKey, url);
  return url;
}

Step 3: Webhook-Driven Cache Invalidation

// Instead of polling, use webhooks to know when to re-fetch
// See figma-webhooks-events for full webhook setup

async function handleFileUpdate(fileKey: string) {
  // Invalidate cached data for this file
  fileCache.delete(fileKey);

  // Proactively re-fetch commonly accessed data
  const token = process.env.FIGMA_PAT!;
  await getCachedFile(fileKey, token);

  console.log(`Cache invalidated and refreshed for ${fileKey}`);
}

Step 4: Batch Node Fetches

// The /nodes endpoint accepts multiple IDs -- batch them
// Max practical batch size: ~50-100 IDs per request

async function batchFetchNodes(
  fileKey: string,
  nodeIds: string[],
  token: string,
  batchSize = 50
): Promise<Map<string, any>> {
  const results = new Map<string, any>();

  for (let i = 0; i < nodeIds.length; i += batchSize) {
    const batch = nodeIds.slice(i, i + batchSize);
    const ids = encodeURIComponent(batch.join(','));

    const data = await fetch(
      `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${ids}`,
      { headers: { 'X-Figma-Token': token } }
    ).then(r => r.json());

    for (const [id, node] of Object.entries(data.nodes)) {
      results.set(id, node);
    }
  }

  return results;
}

Step 5: Connection Reuse

import { Agent } from 'undici';

// Reuse HTTP connections to api.figma.com
const figmaAgent = new Agent({
  keepAliveTimeout: 30_000,
  keepAliveMaxTimeout: 60_000,
  connections: 5,
});

// Use with Node.js 18+ built-in fetch
async function optimizedFetch(path: string, token: string) {
  return fetch(`https://api.figma.com${path}`, {
    headers: { 'X-Figma-Token': token },
    // @ts-ignore -- dispatcher is a Node.js fetch option
    dispatcher: figmaAgent,
  });
}

Output

  • Reduced API payload sizes with depth and nodes endpoints
  • Response caching with appropriate TTLs
  • Webhook-driven cache invalidation
  • Batched node fetches reducing request count
  • Connection reuse for lower latency

Error Handling

Issue Cause Solution
Stale cache No invalidation Use webhooks to invalidate on changes
Out of memory Caching full file JSON Use depth=1 or nodes endpoint
Slow image exports Large batch, high scale Reduce scale; batch in groups of 50
Expired image URLs Cached URL older than 30 days Set image cache TTL to <24h

Examples

Measure the win from payload reduction (Step 1) on a real design-system file:

for url in "files/${FIGMA_FILE_KEY}" "files/${FIGMA_FILE_KEY}?depth=1"; do
  curl -s -o /dev/null -w "%{size_download}B  %{time_total}s  ${url}\n" \
    -H "X-Figma-Token: ${FIGMA_PAT}" "https://api.figma.com/v1/${url}"
done
41520883B  6.180s  files/AbC123        ← full tree
38412B     0.310s  files/AbC123?depth=1 ← 1000x smaller, 20x faster

Confirm the version-keyed cache (Step 2) short-circuits repeat fetches:

GET file AbC123  cache MISS  (version 1234567890) → fetched, cached
GET file AbC123  cache HIT   (version unchanged) → 0 API calls
webhook FILE_UPDATE AbC123 → invalidated → next GET refetches

Batching and connection reuse details: references/batch-node-fetches.md, references/connection-reuse.md.

Resources

Next Steps

For cost optimization, see figma-cost-tuning.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-figma-perform-b22127/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-figma-perform-b22127.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-figma-perform-b22127",
  "kind": "skill",
  "name": "figma-performance-tuning",
  "description": "Optimize Figma REST API performance with caching, partial fetches, and connection reuse. Use when experiencing slow API responses, reducing bandwidth for large files, or optimizing request throughput for Figma integrations. Trigger with phrases like \"figma performance\", \"figma slow\", \"figma caching\", \"figma optimize\", \"figma large file\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "saas",
      "figma",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Optimize Figma REST API performance with caching, partial fetches, and connection reuse. Use when experiencing slow API responses, reducing bandwidth for large files, or optimizing request throughput for Figma integrations. Trigger with phrases like \"figma performance\", \"figma slow\", \"figma caching\", \"figma optimize\", \"figma large file\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/figma-pack/skills/figma-performance-tuning/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/figma-pack/skills/figma-performance-tuning/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/figma-pack/skills/figma-performance-tuning/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit"
    ],
    "license": "MIT"
  },
  "instructions": "# Figma Performance Tuning\n\n## Overview\n\nOptimize Figma REST API performance. Large Figma files can return multi-megabyte JSON responses. Key strategies: fetch only what you need, cache aggressively, and batch requests.\n\n## Prerequisites\n\n- Working Figma API integration\n- Understanding of your access patterns (which endpoints, how often)\n\n## Instructions\n\n### Step 1: Reduce Payload Size\n\n```typescript\n// BAD: fetches the entire file tree (can be 10+ MB for large files)\nconst file = await fetch(`https://api.figma.com/v1/files/${fileKey}`, {\n  headers: { 'X-Figma-Token': token },\n}).then(r => r.",
  "cost": {
    "context_tokens": 1535
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-figma-perform-b22127/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.