【テクニカル・上級編】Figmaが重い・動かないときの原因と対策!動作を劇的に軽くする10のチェックポイント – UI/UX・デザインツール活用バイブル

Figmaが重い、動かない。その時、真のアーキテクトはどうコードとメモリを支配するか

Figmaが「ただのデザインツール」だと思っていたなら、今すぐその認識を改めろ。
Webブラウザ(またはC++ベースのElectronラッパー)上で動作するFigmaは、巨大なデザインシステムや数千のインスタンスを抱えた瞬間、単なるフロントエンドアプリケーションの枠を超え、「極限まで肥大化したDOM/Scene Graph構造体」へと変貌する。

メモリリーク、GPUのオーバードロー、そして不毛な再レンダリング。
これらはデザイナーの「レイヤー整理の甘さ」ではない。システムアーキテクチャの敗北だ。

本稿では、UI/UXエンジニアおよびデザインシステムのガバナンスを担うDevOps/リードエンジニアに向け、Figmaの内部挙動(Scene Graphとメモリモデル)を解剖し、パフォーマンスを物理的限界まで引き上げる10の極限チェックポイントと、それを自動化するAPI/CLIハックを叩き込む。

—

Ⅰ. Figmaの内部アーキテクチャとメモリ枯渇のメカニズム

なぜFigmaは重くなるのか? 根本原因を理解せずして最適化は語れない。

1. Scene Graphの肥大化: Figmaのファイルは、実質的に巨大なJSONツリー構造(Scene Graph)だ。ノード数が10万を超えたあたりから、差分検知(Diffing)アルゴリズムの計算量が爆発する。
2. GPUテクスチャメモリの圧迫: 未最適化の巨大なPNG/JPEG画像が配置されると、VRAMを直接食いつぶす。ブラウザのWebGLコンテキストがロストし、あの悪名高い「Out of Memory」クラッシュを引き起こす。
3. 過剰なネスト(DOM/Component Depth): 深すぎるオートレイアウトのネストは、レイアウト計算のパイプライン(Cassowaryソルバーの系譜)に致命的な負荷をかける。

これを手動の「お片付け」で解決しようなどと考えるのは、手動でガベージコレクションをやろうとするようなものだ。システムで殴れ。

—

Ⅱ. パフォーマンスを劇的に改善する10のチェックポイント

1. ノード数(Scene Graph Nodes)のハードリミット設定

  • 症状: 1ファイルあたりのノード数が50,000を超えると、操作のたびにメインスレッドがブロックされる。
  • 対策: 1ファイル、1ページの限界値を明確に規定せよ。巨大なワイヤーフレームや全画面フローは、絶対に単一ファイルに収めるな。

2. コンポーネントライブラリの「ポータビリティ」分離

  • 症状: アプリケーションの実装コードと同様、デザインシステムも単一モノリス(Monolith)にすると崩壊する。
  • 対策: Foundations(トークン)、Primitives(原子パーツ)、Patterns(分子)を厳密に別ファイル(別チーム)に切り出し、ライブラリとしてパブリッシュ(Publish)せよ。ローカルでのオーバライドの嵐を防げ。

3. 未使用スタイル・コンポーネントの完全消去

  • 症状: 「いつか使うかも知れない」というエンジニアの悪癖が、Figma内でもメモリを蝕む。
  • 対策: プラグインやAPIを使い、インベントリから参照されていない(`remote` ではない、かつローカルで参照ゼロの)スタイルを容赦なく purge(削除)しろ。

4. オートレイアウトのネスト深度制限(最大3階層まで)

  • 症状: 「とりあえずAuto Layoutに入れとけ」精神が生む、10階層以上の深いネスト。
  • 対策: 再帰的なレイアウト計算コストは $O(N)$ 以上で跳ね上がる。コンポーネントをフラットに再設計し、ネストは最大3階層以内に強制せよ。

5. 画像テクスチャの強制ダウンサンプリング

  • 症状: デザイナーが無加工の4Kディスプレイ用スクリーンショット(数MB)をそのまま貼り付ける。
  • 対策: Figmaに持ち込む前に、CLIで適切な解像度(Retinaであれば2xまで)に圧縮・リサイズするパイプラインを強制しろ。

6. ベクターネットワークの極限までのパス単純化

  • 症状: イラストレーターからインポートした複雑なSVG。何千ものアンカーポイントを持つパスデータがGPUを殺す。
  • 対策: パスファインダーで結合し、不要な隠しレイヤーやオーバーラップパスをFlatten(統合)しろ。

7. バリアント(Variants)の過剰生成の禁止

  • 症状: すべての状態(State)やサイズを1つのコンポーネントのバリアントに詰め込み、バリアント数が数百に達する。
  • 対策: 組み合わせ爆発を起こすバリアントは分割せよ。本当に必要なプロパティだけに絞る。

8. 「ページ分割」のモジュール化設計

  • 症状: 1つのファイルに「表紙」「ワイヤー」「詳細デザイン」「プロトタイプ」「アーカイブ」が同居している。
  • 対策: ページ(Page)単位でドメインを完全に分離せよ。Figmaはアクティブなページ以外の重いシーンを一部遅延ロードするが、ファイル全体のインデックス負荷は軽減されない。

9. 非表示レイヤー(Hidden Layers)のパージ

  • 症状: 「ボツ案」や「将来のアイデア」と称して、非表示にしたまま放置された数千のレイヤー。
  • 対策: 非表示であってもScene Graphのメモリには常駐する。ボツ案は別ファイルに退避(Export)し、即座に削除しろ。

10. クラウドキャッシュとローカルハードウェアの最適化

  • 症状: ブラウザタブのメモリ肥大化。
  • 対策: 重いデザイン作業を行う際は、ブラウザ版ではなくFigmaデスクトップアプリの専用インスタンスを使用し、定期的にキャッシュディレクトリ(`~/Library/Application Support/Figma/`等)をクリーニングせよ。

—

Ⅲ. 【独自ハック】Figma REST API & CLIによる「パフォーマンス自動監査」スクリプト

手動のチェックポイントなど、人間の意志に頼るプロセスは3日ていどで崩壊する。
真のエンジニアは、CI/CDパイプライン(または定期実行スクリプト)でFigmaファイルを監視し、重すぎるファイルを自動検知・警告する仕組みを構築する。

以下に、Figma REST APIを叩いてファイルの「ノード数」「画像過多」「深すぎるネスト」を静的解析し、Slackへアラートを飛ばす Node.js スクリプトを提示する。これを叩き込め。

/

  • Figma Performance Auditor (Figma Performance CI Script)
  • 指定されたFigmaファイルのJSONツリーを解析し、
  • ノード数、ネスト深度、重い画像を検知してメトリクスを出力する。
  • 実行要件: Node.js, node-fetch

/

const fetch = require(‘node-fetch’);

// 環境変数からの設定
const FIGMA_TOKEN = process.env.FIGMA_ACCESS_TOKEN;
const FILE_KEY = process.env.FIGMA_FILE_KEY; // FigmaのURLから取得
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;

// 閾値設定(アーキテクチャの安全基準)
const THRESHOLDS = {
maxNodes: 25000, // 最大ノード数
maxDepth: 6, // 最大ネスト深度
maxImages: 50 // 許容画像数
};

async function auditFigmaFile() {
if (!FIGMA_TOKEN || !FILE_KEY) {
console.error(‘Error: FIGMA_ACCESS_TOKEN and FIGMA_FILE_KEY must be set.’);
process.exit(1);
}

console.log(`[Audit] Fetching Figma file metadata for: ${FILE_KEY}…`);

try {
const response = await fetch(`https://api.figma.com/v1/files/${FILE_KEY}?depth=4`, {
headers: { ‘X-Figma-Token’: FIGMA_TOKEN }
});

if (!response.ok) {
throw new Error(`Figma API Error: ${response.statusText}`);
}

const data = await response.json();

// 解析メトリクスの初期化
let metrics = {
totalNodes: 0,
maxObservedDepth: 0,
imageCount: 0,
warnings: []
};

// 再帰的にノードを走査する関数
function traverse(node, currentDepth = 1) {
metrics.totalNodes++;
if (currentDepth > metrics.maxObservedDepth) {
metrics.maxObservedDepth = currentDepth;
}

// 画像の検知 (FILLにIMAGEタイプが含まれるか)
if (node.fills && node.fills.some(fill => fill.type === ‘IMAGE’)) {
metrics.imageCount++;
}

// 子ノードの再帰処理
if (node.children) {
for (const child of node.children) {
traverse(child, currentDepth + 1);
}
}
}

// ドキュメントルートから走査開始
traverse(data.document, 1);

console.log(‘— Figma Architecture Audit Report —‘);
console.log(`Total Nodes: ${metrics.totalNodes} (Limit: ${THRESHOLDS.maxNodes})`);
console.log(`Max Nest Depth: ${metrics.maxObservedDepth} (Limit: ${THRESHOLDS.maxDepth})`);
console.log(`Image Count: ${metrics.imageCount} (Limit: ${THRESHOLDS.maxImages})`);

// 閾値チェックと警告の生成
if (metrics.totalNodes > THRESHOLDS.maxNodes) {
metrics.warnings.warn(`[CRITICAL] Node count exceeds threshold: ${metrics.totalNodes}`);
}
if (metrics.maxObservedDepth > THRESHOLDS.maxDepth) {
metrics.warnings.push(`[WARNING] Max nest depth is too deep: ${metrics.maxObservedDepth}`);
}
if (metrics.imageCount > THRESHOLDS.maxImages) {
metrics.warnings.push(`[WARNING] High image count detected: ${metrics.imageCount}`);
}

// 警告が存在する場合はSlack等へ通知
if (metrics.warnings.length > 0) {
console.log(‘Performance bottlenecks detected. Sending alerts…’);
await sendSlackAlert(metrics.warnings);
} else {
console.log(‘All metrics within acceptable performance limits.’);
}

} catch (error) {
console.error(‘Audit failed:’, error);
process.exit(1);
}
}

async function sendSlackAlert(warnings) {
if (!SLACK_WEBHOOK_URL) return;

const payload = {
text: `🚨 Figma Performance Alert 🚨\nFile: \`${FILE_KEY}\`\n\`\`\`\n${warnings.join(‘\n’)}\n\`\`\“
};

await fetch(SLACK_WEBHOOK_URL, {
method: ‘POST’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify(payload)
});
}

auditFigmaFile();

—

Ⅳ. 結び:ツールに支配されるな、システムを支配せよ

Figmaが重いと感じた瞬間、それはデザインの複雑性がツールの処理限界を超えたというシステムからのアラートだ。
デザイナーに「レイヤーを綺麗にして」と頼むのは、プログラマーに「コードを綺麗にして」と抽象的な精神論を説くのと同じくらい無意味である。

アーキテクトよ、構造を定義しろ。ルールをコード化し、APIで監視せよ。
ツールを限界までチューニングし、一瞬たりとも思考を止めない最高速のプロトタイピング・パイプラインを死守するのだ。

タイトルとURLをコピーしました