Core Web Vitals に影響しないアニメーション設計
LCP(Largest Contentful Paint)を守る
問題: ヒーロー画像にフェードイン演出を入れると、画像が表示されるタイミングが遅れて LCP が悪化する。
対策1: メインコンテンツの初期表示は static で、装飾アニメーションのみ後から追加する。
対策2: <link rel="preload" as="image" href="hero.jpg"> で重要画像を先読み。
対策3: Above the fold のアニメーションは LCP発火後(DOMContentLoaded + 100ms)に開始する。
CLS(Cumulative Layout Shift)を守る
問題: アニメーションで要素のサイズが変わると、周囲の要素が動いて CLS が増加する。
対策: transform と opacity だけを動かす(これらは GPU レイヤーで処理され、レイアウトに影響しない)。
NG例: width: 100px → 200px のアニメーション → 周囲が押し出される。
OK例: transform: scaleX(1) → scaleX(2) → 視覚的には同じだがレイアウトは変わらない。
INP(Interaction to Next Paint)を守る
問題: クリック直後に重い JavaScript 処理が走ると、アニメーション開始が遅れる。
対策: クリックハンドラ内で重い処理は requestIdleCallback に逃がす。
対策: アニメーション開始は同期的に、データ処理は非同期に切り分ける。
目標: クリックから200ms以内に視覚反応を返す。
GPU レイヤー昇格テクニック
will-change: transform — ブラウザに事前に GPU レイヤーを準備させる。
transform: translateZ(0) — レガシーな GPU 昇格テクニック。今は will-change を推奨。
乱用禁止 — 全要素に will-change を付けるとメモリ消費が爆発する。必要な要素にだけ。
アニメーション終了後は外す — element.style.willChange = 'auto'; でクリーンアップ。
60fps を保つチェックリスト
✅ transform / opacity のみを動かしているか
✅ ボックスシャドウのアニメーションを避けているか(重い)
✅ filter: blur() 等の重いCSSプロパティを動かしていないか
✅ JavaScript アニメーションは requestAnimationFrame を使っているか
✅ Chrome DevTools の Performance タブで「Long Frames」を確認したか
FAQ
box-shadow のアニメーションは重い?
filter: blur() のアニメーションは?
Mobile での 60fps 達成は難しい?
Core Web Vitals の計測ツールは?
関連書籍
学びを止めない · Amazonサブスク
※ Amazonアソシエイト・プログラム参加。リンク経由のご購入で運営者が紹介料を受け取る場合があります。