lottie
WebでパフォーマンスにこだわったLottieアニメーションを実装するための専門的なガイドラインを提供するスキルです。アニメーションの最適化手法やベストプラクティスを踏まえた実装をサポートします。
description の原文を見る
Expert guidelines for implementing performant Lottie animations on the web
SKILL.md 本文
Lottie アニメーション ガイドライン
Lottie アニメーション、ウェブパフォーマンス、JavaScript の専門家です。Lottie アニメーションの実装時に、以下のガイドラインに従ってください。
コア原則
dotLottie フォーマットを使用する
.jsonより.lottie(dotLottie)フォーマットを推奨 - ファイルサイズを最大 90% 削減- dotLottie はすべてのアセット(画像、フォント)を単一の圧縮ファイルにまとめる
- lottiefiles.com の無料 dotLottie コンバーターを使用
インストール
# React 用
npm install @lottiefiles/dotlottie-react
# vanilla JS 用
npm install @lottiefiles/dotlottie-web
React 実装
基本的な使用方法
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function Animation() {
return (
<DotLottieReact
src="/animations/loading.lottie"
loop
autoplay
/>
);
}
アニメーション再生の制御
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import { useState } from "react";
function ControlledAnimation() {
const [dotLottie, setDotLottie] = useState(null);
const dotLottieRefCallback = (dotLottie) => {
setDotLottie(dotLottie);
};
return (
<>
<DotLottieReact
src="/animation.lottie"
dotLottieRefCallback={dotLottieRefCallback}
/>
<button onClick={() => dotLottie?.play()}>再生</button>
<button onClick={() => dotLottie?.pause()}>一時停止</button>
<button onClick={() => dotLottie?.stop()}>停止</button>
</>
);
}
パフォーマンス最適化
遅延読み込み
import { useEffect, useRef, useState } from "react";
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function LazyLottie({ src }) {
const [isVisible, setIsVisible] = useState(false);
const containerRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
observer.disconnect();
}
},
{ rootMargin: "100px" }
);
if (containerRef.current) {
observer.observe(containerRef.current);
}
return () => observer.disconnect();
}, []);
return (
<div ref={containerRef}>
{isVisible && <DotLottieReact src={src} autoplay loop />}
</div>
);
}
適切なレンダラーを選択する
// SVG レンダラー - 最高の品質、シンプルなアニメーションに最適
<DotLottieReact src="/animation.lottie" renderer="svg" />
// Canvas レンダラー - 複雑なアニメーションのパフォーマンスが優れている
<DotLottieReact src="/animation.lottie" renderer="canvas" />
// Canvas を使用する場合:
// - 多くの要素を含む複雑なアニメーション
// - 低性能デバイス
// - フィルター/エフェクト付きアニメーション
DOM 要素を削減する
- After Effects で同一のグラフィック要素を再利用
- パスを単純化し、キーフレームを削減
- 不要なレイヤーを回避
- アニメーションあたり 1000 未満の DOM 要素を目標
アニメーションデザインのベストプラクティス
パフォーマンスが低い機能を回避する
回避すべき機能:
- マスク(アルファマットは控えめに使用)
- 複雑なぼかしエフェクト
- 3D レイヤー
- エクスプレッション
- 未圧縮画像
- 大きな画像アセット
推奨:
- シンプルな図形(塗りつぶし、ストローク)
- トランスフォーム アニメーション(位置、スケール、回転)
- 不透明度の変更
- パス アニメーション
アニメーション内の画像を最適化する
- 表示サイズに合わせて画像を圧縮
- 最大表示サイズが 400x400 の場合、1000x1000 の画像を使用しない
- 可能な場合はベクターグラフィックスを使用
- 画像をシェイプに変換することを検討
インタラクティブ性
カーソル/マウスインタラクション
<DotLottieReact
src="/hover-animation.lottie"
playMode="hover"
/>
スクロール連動アニメーション
import { useScroll, useTransform } from "motion/react";
function ScrollLottie() {
const { scrollYProgress } = useScroll();
const [dotLottie, setDotLottie] = useState(null);
useEffect(() => {
if (!dotLottie) return;
const unsubscribe = scrollYProgress.on("change", (progress) => {
dotLottie.setFrame(progress * dotLottie.totalFrames);
});
return unsubscribe;
}, [dotLottie, scrollYProgress]);
return (
<DotLottieReact
src="/scroll-animation.lottie"
dotLottieRefCallback={setDotLottie}
autoplay={false}
/>
);
}
セグメント再生
function SegmentAnimation() {
const [dotLottie, setDotLottie] = useState(null);
const playSegment = (start, end) => {
dotLottie?.setSegment(start, end);
dotLottie?.play();
};
return (
<>
<DotLottieReact
src="/multi-state.lottie"
dotLottieRefCallback={setDotLottie}
autoplay={false}
/>
<button onClick={() => playSegment(0, 30)}>状態 1</button>
<button onClick={() => playSegment(30, 60)}>状態 2</button>
</>
);
}
アクセシビリティ
縮小モーション設定を尊重する
function AccessibleAnimation() {
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
if (prefersReducedMotion) {
return <img src="/static-fallback.svg" alt="アニメーションの説明" />;
}
return (
<DotLottieReact
src="/animation.lottie"
autoplay
loop
aria-label="装飾的な読み込みアニメーション"
/>
);
}
フォールバックを提供する
function AnimationWithFallback() {
const [hasError, setHasError] = useState(false);
if (hasError) {
return <img src="/fallback.gif" alt="アニメーション" />;
}
return (
<DotLottieReact
src="/animation.lottie"
autoplay
onError={() => setHasError(true)}
/>
);
}
読み込み戦略
大規模アニメーション用のプリローダーを使用する
function AnimationWithPreloader() {
const [isLoaded, setIsLoaded] = useState(false);
return (
<div className="animation-container">
{!isLoaded && (
<img src="/first-frame.webp" alt="" className="preloader" />
)}
<DotLottieReact
src="/large-animation.lottie"
onLoad={() => setIsLoaded(true)}
style={{ opacity: isLoaded ? 1 : 0 }}
autoplay
/>
</div>
);
}
ファイルサイズガイドライン
| アニメーション複雑さ | 目標サイズ | 最大 DOM 要素数 |
|---|---|---|
| シンプルなアイコン | < 10KB | < 100 |
| UI アニメーション | < 50KB | < 500 |
| 複雑なシーン | < 150KB | < 1500 |
| ヒーロー アニメーション | < 300KB | < 2500 |
クリーンアップ
React での適切なクリーンアップ
useEffect(() => {
return () => {
dotLottie?.destroy();
};
}, [dotLottie]);
ベストプラクティス まとめ
- ファイルサイズを削減するため dotLottie フォーマットを使用する
- ビューポート外のアニメーションは遅延読み込みする
- 複雑なアニメーションは Canvas レンダラーを使用する
- マスク、ぼかし、エクスプレッションを回避する
- 画像アセットを圧縮し最適化する
- 縮小モーション設定を尊重する
- エラー時の静的フォールバックを提供する
- アンマウント時にアニメーションをクリーンアップする
- DOM 要素数を少なく保つ
- 大規模アニメーション用のプリローダーを使用する
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- mindrally
- リポジトリ
- mindrally/skills
- ライセンス
- Apache-2.0
- 最終更新
- 不明
Source: https://github.com/mindrally/skills / ライセンス: Apache-2.0
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。