frontend-perf について
frontend-perfは、ブラウザーやElectronの性能改善に取り組む開発者向けのリファレンススキルです。指標、ボトルネックのパターン、バージョン別の指針、最適化の優先順位をまとめ、perf-workflowと併用できます。
主な機能
- 01RAIL、Web Vitals、Electronの指標
- 02フロントエンドのボトルネックパターン
- 03React、Angular、Electronのバージョン別指針
- 04最適化項目の優先順位
- 05分析と検証の基準
活用シーン
- 01フロントエンド性能の定量的な基準設定
- 02リフロー、長時間タスク、メモリー増加の特定
- 03ReactやAngularの改善計画
- 04Electronの起動時間とIPC性能の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fudesign2008/ open-skills --skill frontend-perfインストール後、Claude Code で/frontend-perfを入力して読み込まれたか確認します。
同梱ファイルreference.md
詳細
フロントエンドパフォーマンス最適化ナレッジベース
perf-workflow との関係
このスキルは perf-workflow のナレッジレイヤーであり、perf-workflow はプロセスレイヤーです。両者を組み合わせて使用します。
| perf-workflow のステージ | このスキルが提供するフロントエンド固有の内容 |
|---|---|
| ステージ 1:パフォーマンスの根拠 | 定量的なベースライン:RAIL/Web Vitals/Electron の指標しきい値 |
| ステージ 2:パフォーマンスの局所化 | フロントエンドのボトルネックパターン表、レンダリングパイプラインの局所化ルール |
| ステージ 3:パフォーマンスの仮説 | フロントエンド固有の根本原因(リフロー/長時間タスク/IPC/メモリリーク) |
| ステージ 4:パフォーマンスのモニタリング | 適用可能なツールと計測ポイント |
| ステージ 5:パフォーマンスの最適化 | 最適化の優先順位の参考(P0 → P1 → P2) |
| ステージ 6:パフォーマンスの検証 | 合格基準(LCP/INP/CLS/起動時間) |
定量基準のクイックリファレンス
RAIL モデル(Google Chrome チーム、W3C 推奨)
| フェーズ | 正式名称 | ユーザーが体感するしきい値 | 主な最適化の方向性 |
|---|---|---|---|
| R | 応答 | インタラクション → フィードバック < 100ms | 軽量なイベントハンドラーを使用し、メインスレッドをブロックしない |
| A | アニメーション | 安定して 60fps、フレームあたり < 16ms | transform/opacity のみを使用し、リフローを回避する |
| I | アイドル | アイドル時の作業を < 50ms のチャンクに分割する | requestIdleCallback を使って緊急性の低いタスクをスケジュールする |
| L | 読み込み | 最初のコンテンツ表示 < 2s、使用可能になるまで < 5s | クリティカルリソースの数とサイズを減らす |
Web Vitals:3 つのコア指標(2024 年版)
| 指標 | 正式名称 | 良好 | 要改善 | 最適化の重点 |
|---|---|---|---|---|
| LCP | Largest Contentful Paint | < 2.5s | > 4s | ファーストビューの読み込み、クリティカルレンダリングパス |
| INP | Interaction to Next Paint | < 200ms | > 500ms | メインスレッドの長時間タスク、インタラクションの応答性 |
| CLS | Cumulative Layout Shift | < 0.1 | > 0.25 | レイアウトの安定性、画像サイズの事前確保 |
Electron デスクトップの拡張指標
| 指標 | 合格しきい値(業界標準) | 局所化ツール |
|---|---|---|
| コールドスタート時間 | Windows < 2s、macOS < 1.5s | Electron DevTools/計測タイミング |
| ウォームスタート時間 | < 500ms | 計測タイミング |
| IPC のラウンドトリップ時間 | 呼び出しあたり < 50ms(頻繁な呼び出しの場合) | IPC ログの計測 |
| レンダラープロセスのメモリ | 継続的な増加がなく、ベースラインが安定 | Chrome DevTools の Memory パネル |
| メインスレッドの CPU 使用率 | アイドル時はほぼ 0、長時間タスクなし | Chrome DevTools の Performance パネル |
フロントエンド固有のボトルネックパターン
perf-workflow の Stage 3 にある汎用パターン表を補足します。以下は、フロントエンドコードでよく見られる具体的な例です。
| パターン | フロントエンドでの具体的な現れ方 | よくある発生シナリオ(フロントエンド) | 特定ツール |
|---|---|---|---|
| リフロー(レイアウト) | 幾何学的プロパティの読み書きによって、描画パイプライン全体が再実行されます | 幅/高さ/位置の変更、offsetWidth/scrollTop の読み取り後に DOM へ書き込み | Performance パネルの Layout マーカー |
| 再描画(ペイント) | 視覚的なプロパティの変更によって、Layout をスキップして再描画が発生します | 色/影/背景の変更 | Performance パネルの Paint マーカー |
| メインスレッドの長時間タスク | 50 ms を超える単一のタスクがイベントループをブロックし、INP が目標値を超えます | メインスレッドでの重いデータ処理/複雑な計算/同期 IPC | Performance パネルの Long Task マーカー |
| 不要な再レンダリング | コンポーネントの props/state が変わっていないのに、再レンダリングが発生します | 不安定な props の参照、粒度が粗すぎるグローバル状態、過剰な context の更新 | React Profiler/Vue DevTools |
| IPC のブロッキング | Electron の同期 IPC や高頻度の IPC によって、メインスレッドが飽和します | sendSync の呼び出し、スクロール/入力ハンドラー内での高頻度な IPC 送信 | Electron のログ+Performance パネル |
| メモリ使用量の継続的な増加 | メモリが解放されず、GC で回収できないため、最終的にジャンク/クラッシュが発生します | イベントリスナーの解除漏れ、タイマーのクリア漏れ、クロージャによる大きなオブジェクトの保持 | Memory パネルの Heap Snapshot |
| レイアウトスラッシング | DOM プロパティの読み取りと書き込みを交互に行い、書き込みのたびに同期レイアウトが強制されます | ループ内で DOM の幾何情報を交互に読み取り/変更 | Performance パネルで密集した Layout マーカーを確認 |
| React Concurrent 機能の活用不足 | React 18 以降のプロジェクトで、長時間の計算が引き続き同期パスで実行され、ユーザー入力への応答がブロックされます | useTransition/startTransition を使って低優先度の更新を指定していない | React DevTools Profiler のタイムライン |
| Angular Zone の過剰なトリガー | Zone.js がすべての非同期処理をインターセプトし、ツリー全体の変更検出をトリガーします | NgZone.runOutsideAngular() を使って高頻度イベントを分離していない | Angular DevTools Profiler |
フレームワークのバージョン別の主な最適化機能
分析/最適化の際は、まずフレームワークのバージョンを確認し、それに合った戦略を選んでください。バージョンによって戦略は大きく異なります。
React のバージョン
| バージョン | 主なパフォーマンス機能 | 最適化の効果 |
|---|---|---|
| 16.x | PureComponent/shouldComponentUpdate/クラスコンポーネント | 再レンダリングを手動で制御できます。Hooks はありません |
| 16.8+ | useMemo/useCallback/useRef/React.memo | 関数コンポーネントで細かなメモ化ができます |
| 18 | Concurrent Rendering/自動バッチ処理/useTransition/useDeferredValue | 優先度に基づくスケジューリング、複数の setState 呼び出しの自動統合、長時間タスクの低優先度指定が可能です |
| 19 | React Compiler(自動メモ化)/use() | コンパイラーが参照の安定性を自動的に処理するため、ほとんどの場合、手動でメモ化を記述する必要がなくなります |
Angular のバージョン
| バージョン | 主なパフォーマンス機能 | 最適化による効果 |
|---|---|---|
| 9+ | Ivy コンパイラー | バンドルの縮小、コンパイルの高速化、ツリーシェイキングとの親和性向上 |
| 14+ | スタンドアロンコンポーネント | NgModule のオーバーヘッドを削減し、より細かい単位で遅延読み込みが可能 |
| 16+ | Signals (signal() / computed() / effect()) | きめ細かなリアクティビティを実現し、Zone.js の変更検知を回避できます |
| 17+ | @defer ブロック / @for ... track | 遅延レンダリングを標準でサポートし、trackBy をテンプレート構文に組み込み |
| 18+ | Zoneless 変更検知(実験的) | Zone.js のパッチを取り除き、Zone によって発生するオーバーヘッドを完全に排除 |
Electron のバージョン
| バージョン | 主なパフォーマンス機能 | 最適化による効果 |
|---|---|---|
| 12+ | remote モジュールが非推奨に、contextIsolation がデフォルトで有効 | contextBridge の使用が必須となり、remote の同期 IPC オーバーヘッドを排除 |
| 20+ | sandbox: true がデフォルトで有効 | レンダラープロセスの初期化が軽量化され、preload スクリプトの調整が必要 |
| 22+ | UtilityProcess API | CPU 負荷の高いタスクに適した実行場所として、child_process.fork を置き換え |
| 28+ | レンダラープロセスでネイティブ ESM をサポート | ネイティブの import() を使用でき、より徹底したツリーシェイキングが可能 |
ブラウザーのレンダリングパイプラインの要点
レンダリング経路:DOM → CSSOM → Style → Layout (reflow) → Paint (repaint) → Composite
| 操作の種類 | 発生する最もコストの高いフェーズ | 代表的な CSS プロパティ | パフォーマンス階層 |
|---|---|---|---|
| 幾何学的な変更 | Layout (reflow) | width / height / top / margin | 最も遅い |
| 視覚的な変更 | Paint (repaint) | color / background / box-shadow | 中程度 |
| 合成の変更 | Composite のみ | transform / opacity | 最も速い |
基本ルール:アニメーションとスクロールには transform / opacity のみを使用してください。それ以外のプロパティの変更はまとめて行い、最小限に抑えてください。
Electron のマルチプロセスに関する要点
| プロセスの種類 | 主な役割 | ブロッキングによる影響 | 最適化のレッドライン |
|---|---|---|---|
| メインプロセス | アプリのライフサイクル、ウィンドウ管理、システム API | すべてのウィンドウがフリーズまたは応答不能になる | 同期 IO、CPU 負荷の高いタスク、タイトなループは禁止 |
| レンダラープロセス | ウィンドウ UI のレンダリング、JS の実行、ユーザー操作 | 現在のウィンドウがフリーズする | Web フロントエンドと同じルールを適用し、同期 IPC を使用しない |
| GPU プロセス | 3D 描画、ハードウェアアクセラレーション、コンポジターレイヤーのレンダリング | アニメーションのカクつき、画面のティアリング | ハードウェアアクセラレーションの過剰な使用を避け、コンポジターレイヤーの増えすぎを防ぐ |
| Worker プロセス | CPU 負荷の高いタスク、ファイル IO、バックグラウンド計算 | UI スレッドに影響しない | 時間のかかるタスクはすべて、この種類のプロセスまたは Worker で実行する |
基本的な IPC ルール:ipcRenderer.sendSync は絶対に使用しないでください。高頻度イベントでの IPC はスロットリングし、大きなデータのゼロコピー転送には SharedArrayBuffer を使用してください。
最適化の優先順位クイックリファレンス
時間の大部分を占めるステップを優先してください。全体の 10% 未満を占めるステップを 100 倍高速化しても、全体としての改善は限定的です(アムダールの法則)。
P0:最初に実施(効果が高く、コストが低い)
- 長時間タスクを分割する:50ms を超える同期タスクを 50ms 未満のチャンクに分割し、
requestIdleCallbackでスケジュールする - 仮想スクロール:長いリスト(100 項目超)では必須です。react-window / vue-virtual-scroller を使用する
- リフローを避ける:アニメーションには transform/opacity のみを使用し、DOM の読み取りをまとめてから書き込みをまとめて行う
- 非同期 IPC:Electron の IPC をすべて非同期にし、
sendSyncをすべて削除する - Web Worker:大量データの解析、暗号化、複雑な計算をメインスレッドから移す
P1:次のステップ(コストは中程度、効果は明確)
- コンポーネントのメモ化:React.memo / useMemo / useCallback を使用して、props と関数参照を安定させます
- 状態の粒度:過度に大まかなグローバル状態を分割し、不要な再レンダリングの範囲を縮小します
- コード分割:ルート単位/コンポーネント単位で動的インポートを行い、初回画面の JS サイズを縮小します
- Electron の起動:メインプロセスのエントリーポイントを可能な限り軽量に保ち、初回画面に表示されないモジュールは非同期で読み込みます
P2:任意(エンジニアリング面での効果、長期的な取り組み)
- キャッシュ戦略:静的アセットに長期の強力なキャッシュとハッシュ付きファイル名を使用し、Service Worker でオフラインキャッシュを行います
- バンドルサイズの削減:ツリーシェイキングを行い、大容量ライブラリは必要に応じてインポートし、画像には WebP/AVIF を使用します
- パフォーマンス予算と CI/CD のゲート:LCP/INP/バンドルサイズをパイプラインに組み込み、予算を超えたリリースをブロックします
詳しい実装方法については、reference.md を参照してください。
分析ツールのクイックリファレンス
| シナリオ | 推奨ツール |
|---|---|
| メインスレッドの長時間タスク | Chrome DevTools → Performance パネル → Long Tasks |
| レンダリングのボトルネック | Chrome DevTools → Performance → Rendering パネル |
| React の再レンダリング | React DevTools Profiler(フレームグラフ+ランキングチャート) |
| React 18 以降のスケジューリング優先度 | React DevTools Profiler → タイムライン表示で Concurrent 優先度マーカーを確認 |
| Angular の変更検知 | Angular DevTools → Profiler(変更検知の回数と所要時間を確認) |
| Angular Signals | Angular DevTools 17 以降 → Signal の依存関係グラフ表示(実験的機能) |
| メモリリーク | Chrome DevTools → Memory → Heap Snapshots を比較 |
| Web Vitals | Lighthouse / Chrome DevTools → Performance Insights |
| Electron のプロセス概要 | app.getAppMetrics() でプロセスごとの CPU/メモリ使用量を確認。システムリソースモニターも使用 |
| Electron IPC のタイミング | カスタムログの計測+Chrome DevTools Performance パネル |
| バンドルサイズの分析 | webpack-bundle-analyzer / vite-plugin-inspect |