概要
Granolaアプリで 高いCPU・GPU使用率 の原因が 小さなCSSアニメーション であることを発見。 Chrome DevTools で高コストなアニメーションの特定方法と最適化手法を解説。 height などのレイアウトプロパティのアニメーションが特に高コストである理由を説明。 transform を使ったアニメーション最適化による大幅なパフォーマンス改善例を紹介。 ブラウザの レンダリングパイプライン 理解がパフォーマンス向上に不可欠であることを強調。
Granolaアプリの高負荷問題と原因特定
- Granolaは Electron製ノートアプリ
- M2 MacBook でCPU 60%、GPU 25%使用を確認
- Chrome DevTools のPerformanceタブで、主な処理はJavaScriptでなく「Rendering」と「Painting」
- Layersタブで「アクションバー」レイヤーが毎フレーム再描画されている
- Renderingタブで「Paint Flashing」「Layout Shift Regions」を有効化し、 音量ビジュアライザー のアニメーションが原因と判明
- ビジュアライザーの「踊るバー」3本が常に再レイアウト・再描画される現象
- DOM更新頻度を下げても効果なし。 CSSアニメーション がボトルネック
- Performanceタブで「Animation」ジョブ3つ(バーごとに1つ)を確認
- 問題のCSS:
transition: height 300ms ease-in-out;
ブラウザのレンダリングパイプラインとアニメーションコスト
- レンダリングパイプラインは Layout → Paint → Composite の順
- height アニメーションは「Layout」再計算→「Paint」→「Composite」と全工程が発生
- レイアウトプロパティ(例:height, width, top, left)はアニメーションコストが非常に高い
- ペイントプロパティ(例:SVGのfillやstroke)はレイアウトなしでPaintとComposite
- 最も安価なプロパティは Compositeプロパティ (例:transform, opacity)
- これらはLayoutもPaintも発生せずCompositeのみ
transformによるアニメーション最適化
- heightアニメーション を transform: scaleY() に置換することでパフォーマンス大幅改善
- ただし、 scaleY は角丸が歪むなど見た目の問題が発生
- 解決策として、 2つの矩形を上下から移動 させて1本のバーに見せる手法を採用
- 各端に1つずつ矩形を配置し、それぞれ逆方向にtranslate
- これにより、 Layout・Paintフェーズをスキップ し、Compositeのみで動作
- 最適化後、CPU・GPU使用率が大幅減少(CPU 6%、GPU 1%未満)
パフォーマンス改善のポイントと今後
- レンダリングパイプライン理解 と 適切なCSSプロパティ選択 が重要
- Chromeの about://tracing ツールでさらに詳細なパフォーマンス分析が可能
- Granolaの最適化版ビジュアライザーは実際にアプリで体験可能
- パフォーマンス最適化に興味がある方は採用情報も要チェック