# Anima Performance Tuning

> Optimize Anima code generation performance with caching, parallelism, and output tuning. Use when reducing generation latency, optimizing batch component generation, or improving generated code quality for production use. Trigger: "anima performance", "anima slow", "anima optimization", "anima caching".

- Skill: `gabrielmoreira/anima-performance-tuning` (Agent Skill)
- Install (CLI): `npx skillmds@latest add gabrielmoreira/anima-performance-tuning`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gabrielmoreira/anima-performance-tuning/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- License: MIT
- Author: gabrielmoreira (https://skillmd.com/u/gabrielmoreira)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/gabrielmoreira/anima-performance-tuning

---

# Anima Performance Tuning

## Overview

Improve design-to-code throughput without treating cache hits or smaller output
as success unless the result still matches the approved design version,
accessibility expectations, and project build contract.

## Performance Targets

| Operation | Target | Notes |
|-----------|--------|-------|
| Single component generation | < 10s | Depends on complexity |
| Batch (10 components) | < 2 min | With rate limit delays |
| Cache hit | < 10ms | File-based cache |
| Full design system (50 components) | < 15 min | Sequential with 6s delays |

## Prerequisites

- A representative staging fixture and a baseline measurement of generation
  duration, cache hit rate, failure rate, and generated-code validation result.
- A version-aware cache key and retention policy that ties each artifact to
  Figma source version, node ID, and generation settings.
- Review gates for generated output so performance changes cannot automatically
  replace approved components or strip required licenses/accessibility content.

## Instructions

### Step 1: File-Based Generation Cache

```typescript
// src/performance/cache.ts
import crypto from 'crypto';
import fs from 'fs';

class GenerationCache {
  private dir: string;

  constructor(cacheDir = '.anima-cache') {
    this.dir = cacheDir;
    fs.mkdirSync(cacheDir, { recursive: true });
  }

  private hash(fileKey: string, nodeId: string, settings: any): string {
    return crypto.createHash('md5').update(`${fileKey}:${nodeId}:${JSON.stringify(settings)}`).digest('hex');
  }

  async getOrGenerate(
    anima: any,
    params: any,
    maxAgeMs: number = 3600000, // 1 hour
  ): Promise<any> {
    const key = this.hash(params.fileKey, params.nodesId[0], params.settings);
    const path = `${this.dir}/${key}.json`;

    if (fs.existsSync(path)) {
      const stat = fs.statSync(path);
      if (Date.now() - stat.mtimeMs < maxAgeMs) {
        return JSON.parse(fs.readFileSync(path, 'utf8'));
      }
    }

    const result = await anima.generateCode(params);
    fs.writeFileSync(path, JSON.stringify(result));
    return result;
  }

  clearOlderThan(maxAgeMs: number): number {
    let cleared = 0;
    for (const file of fs.readdirSync(this.dir)) {
      const path = `${this.dir}/${file}`;
      if (Date.now() - fs.statSync(path).mtimeMs > maxAgeMs) {
        fs.unlinkSync(path);
        cleared++;
      }
    }
    return cleared;
  }
}

export { GenerationCache };
```

### Step 2: Incremental Generation (Only Changed Components)

```typescript
// src/performance/incremental.ts
// Only regenerate components whose Figma nodes changed

async function getNodeLastModified(fileKey: string, nodeId: string): Promise<string> {
  const res = await fetch(
    `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${nodeId}`,
    { headers: { 'X-Figma-Token': process.env.FIGMA_TOKEN! } }
  );
  const data = await res.json();
  return data.lastModified;
}

async function generateOnlyChanged(
  anima: any,
  fileKey: string,
  nodeIds: string[],
  lastModifiedCache: Map<string, string>,
): Promise<string[]> {
  const changed: string[] = [];

  for (const nodeId of nodeIds) {
    const lastMod = await getNodeLastModified(fileKey, nodeId);
    if (lastMod !== lastModifiedCache.get(nodeId)) {
      changed.push(nodeId);
      lastModifiedCache.set(nodeId, lastMod);
    }
  }

  console.log(`${changed.length}/${nodeIds.length} components changed — regenerating`);
  return changed;
}
```

### Step 3: Output Size Optimization

```typescript
// src/performance/output-opt.ts
// Post-process generated code for smaller bundle size

function optimizeOutput(content: string): string {
  return content
    .replace(/\/\*[\s\S]*?\*\//g, '')         // Remove block comments
    .replace(/^\s*\/\/.*$/gm, '')              // Remove line comments
    .replace(/\n{3,}/g, '\n\n')               // Collapse multiple blank lines
    .trim();
}
```

## Output

- File-based generation cache with TTL
- Incremental generation (only changed components)
- Output size optimization via post-processing

## Examples

Benchmark ten approved staging components once without cache and once with the
cache keyed by source version, node ID, and settings. Compare duration, API
calls, output size, lint/type results, and visual review rather than just cache
hit rate. Regenerate only components whose recorded source version changed, and
keep the prior generated artifact available for diff review. If a cache entry
cannot prove its source version, post-processing changes required behavior, or
rate limits increase, disable the optimization and return to the prior
validated generation path while investigating the aggregate measurements.

## Error Handling

| Failure | Response |
|---------|----------|
| Cache artifact lacks valid source/version metadata | Refuse reuse and regenerate the approved component. |
| Incremental detector cannot determine change state | Treat the affected component as needing controlled regeneration. |
| Optimizer changes semantics or removes required content | Revert the post-processing rule and restore the reviewed artifact. |
| Throughput increases provider failures or rate limits | Reduce concurrency, apply bounded backoff, and preserve user-visible job state. |

## Resources

- [Anima API](https://docs.animaapp.com/docs/anima-api)
- [Figma API Nodes](https://www.figma.com/developers/api#get-file-nodes-endpoint)

## Next Steps

For cost optimization, see `anima-cost-tuning`.

