rn-skia について
React Native Skia でグラフィックスやアニメーションを開発する人向けの実践ガイドです。描画モードの選択、パフォーマンス上の注意点、コードレビュー手順をまとめています。
主な機能
- 01保持モードと即時モードの指針
- 02Reanimated のアニメーションパターン
- 03描画・テキスト・画像・エフェクトの資料
- 04パフォーマンス規則とアンチパターン確認
- 05構造化されたコードレビュー報告
活用シーン
- 01Skia コードの性能問題の確認
- 02チャートやパーティクル向け描画モードの選択
- 03共有値を使ったアニメーションの作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ imfa-solutions/ skills --skill rn-skiaインストール後、Claude Code で/rn-skiaを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/advanced-patterns.mdanimations.mdcanvas-rendering.mdfilters-effects.mdgetting-started.mdimages-media.mdperformance.mdshaders-gradients.mdshapes-drawing.mdtext-fonts.md詳細
React Native Skia — ベストプラクティスとパフォーマンスガイド
@shopify/react-native-skia 2.x / React Native >= 0.79 / React >= 19 / Reanimated v3+
重要なルール
- JSX のレンダー中に
.valueを読み取らないでください — 共有値はプロパティに直接渡します:<Circle cx={x} />とし、<Circle cx={x.value} />とはしません。 - レンダー中に Skia オブジェクトを作成しないでください — Paint、Path、PictureRecorder、RuntimeEffect には
useMemoを使用します。 useDerivedValueのコールバック内では、必ずワークレット関数に"worklet"ディレクティブを付けてください。- 構造ではなくプロパティをアニメーションさせてください — コンポーネントツリーを静的に保ち、数値や色のプロパティのみをアニメーションさせます。
- 類似要素が 10 個以上ある場合は Atlas を使用してください — N 個の個別コンポーネントより、単一の描画呼び出しのほうが効率的です。
- Paint と PictureRecorder のオブジェクトを再利用してください — フレームごとに作成すると、GC の負荷とフレーム落ちが発生します。
- UI アニメーションには保持モードを優先してください(FFI コストはほぼゼロです)。即時モード(Picture API)は、描画コマンド数が変化する場合(パーティクル、ジェネレーティブアート、ゲーム)にのみ使用します。
- 単純な図形には Blur より BlurMask を使用してください — より低コストです。
- フィルターは低コストのものから順に適用してください — MatrixColorFilter を Blur より前にします。
- コンポーネントレベルで
useFont/useImageを使ってフォントや画像を読み込んでください — レンダリング前に、読み込み中の null 状態を処理します。
バージョン互換性
| React Native Skia | React Native | React | iOS | Android |
|---|---|---|---|---|
| 2.x | >= 0.79 | >= 19 | >= 14 | API >= 21 |
| 1.12.4 | <= 0.78 | <= 18 | >= 14 | API >= 21 |
動画をサポートするには Android API 26 以上が必要です。
インストール
npm install @shopify/react-native-skia
# Postinstall downloads prebuilt Skia binaries — must run
# Bun: bun add --trust @shopify/react-native-skia
# pnpm v10+: add to pnpm.onlyBuiltDependencies in package.json
iOS:cd ios && pod install を実行します。Android の ProGuard には、-keep class com.shopify.reactnative.skia.** { *; } を追加します。
必須のインポート
import {
Canvas, Circle, Rect, RoundedRect, Line, Path, Group, Fill,
Text, Paragraph, Image, ImageSVG,
LinearGradient, RadialGradient, SweepGradient,
Blur, BlurMask, Shadow, BackdropBlur, MatrixColorFilter,
RuntimeShader, FractalNoise, Turbulence, ImageShader,
Atlas, Picture, Vertices, Patch, DiffRect, FitBox, Box,
useFont, useImage, useSVG, useCanvasRef,
Skia, vec, rect, rrect, drawAsImage,
usePathInterpolation, useRSXformBuffer, useRectBuffer, useClock,
interpolateColors,
} from "@shopify/react-native-skia";
import {
useSharedValue, useDerivedValue, withTiming, withSpring,
withRepeat, withSequence, withDelay, withDecay, cancelAnimation,
} from "react-native-reanimated";
基本パターン — 保持モードのアニメーション
const x = useSharedValue(0);
const scale = useSharedValue(1);
useEffect(() => {
x.value = withSpring(200);
scale.value = withSpring(1.5);
}, []);
return (
<Canvas style={{ flex: 1 }}>
<Group transform={[{ translateX: x }, { scale }]}>
<Circle cx={0} cy={100} r={50} color="cyan" />
</Group>
</Canvas>
);
レンダリングモードの選択
| シナリオ | モード | 理由 |
|---|---|---|
| UI アニメーション | 保持 | FFI コストはほぼゼロ、ディスプレイリストをキャッシュ |
| チャートとグラフ | 保持 | 構造は静的で、プロパティをアニメーション可能 |
| パーティクルシステム | 即時 | 描画コマンド数が変化 |
| ゲーム | 即時 | フレームごとの完全な制御 |
| ジェネレーティブアート | 即時 | シーンの変化が予測不能 |
| 混在 | 両方 | パーティクルには Picture、UI には Group |
パフォーマンス早見表
Fastest (use freely): Circle, Rect, Line, Group transforms, MatrixColorFilter
Fast (use moderately): Path (simple), BlurMask, LinearGradient
Slow (use sparingly): BackdropBlur, RuntimeShader, DisplacementMap, Blur (large radius)
目標:60fps の予算は 16.67ms、120fps の予算は 8.33ms です。メモリは 100MB 未満。JS スレッドは 50% 未満。
見つけたらすぐ修正するアンチパターン
| アンチパターン | 修正 |
|---|---|
JSX 内の cx={x.value} | cx={x} — 共有値を直接渡します |
レンダー本体内の Skia.Paint() | useMemo(() => Skia.Paint(), []) で囲みます |
レンダー本体内の Skia.Path.Make() | useMemo で囲みます |
10 個以上のアイテムに対する {items.map(i => <Circle .../>)} | useRSXformBuffer とともに Atlas を使用します |
<Blur blur={0} /> | 削除します — 何もしないフィルターが処理サイクルを浪費します |
| フレームごとに変化する動的なコンポーネントリスト | 即時モード(Picture API)を使用します |
Skia アニメーションを制御する useState | useSharedValue を使用します |
useDerivedValue に "worklet" がない | 最初の文としてディレクティブを追加します |
| フォント/画像の null チェックがない | if (!font) return null でガードします |
広い領域を囲む <BackdropBlur> | クリップ領域を制限するか、BlurMask を使用します |
コードレビュー時の対応
Skia コードのレビュー、監査、確認を依頼された場合:
@shopify/react-native-skiaをインポートしているすべてのファイルをスキャンします。- 重要なルールとアンチパターンの表に照らして確認します。
- 次の表形式で報告します:
| File | Line | Issue | Severity | Fix | - 重要度:CRITICAL(クラッシュ/レンダリングの破損)、HIGH(フレーム落ち)、MEDIUM(最適ではない)、LOW(スタイル)。
- 問題が確認された場合はすべて修正し、再スキャンして違反がゼロであることを確認します。
参考ファイル
API の詳細なドキュメント、例、パターンが必要な場合は、以下を参照してください。
- はじめに:インストール(npm/yarn/Expo/Bun/pnpm)、プラットフォームのセットアップ(iOS/Android/Web)、postinstall スクリプト、Hello World、Canvas コンポーネント、Skia オブジェクト API、プロジェクト構成、ビルドエラーのトラブルシューティング、バンドルサイズ。
- Canvas とレンダリングモード:リテインドモード(宣言型コンポーネント、ディスプレイリスト、ほぼゼロの FFI)、イミディエイトモード(Picture API、PictureRecorder、直接描画コマンド)、両モードの組み合わせ、オフスクリーン/ヘッドレスレンダリング、Canvas のスナップショット、カスタムレンダラー、プラットフォームに関する考慮事項。
- 図形と描画:すべての図形コンポーネント(Circle、Rect、RoundedRect、Oval、Line、Points、Fill、SVG 記法を使った Path、Atlas/RSXform によるスプライトのバッチ処理、Vertices、Patch、DiffRect)、Group の変換/ブレンドモード/クリッピング、Paint コンポーネント、FitBox、影付き Box、パスのトリミングアニメーション。
- アニメーション:Reanimated v3 との統合(共有値を直接プロパティとして使用)、アニメーションの種類(timing/spring/decay/repeat/sequence)、派生値、Skia フック(usePathInterpolation、usePathValue、useClock、useRectBuffer、useRSXformBuffer)、色のアニメーション(interpolateColors)、ジェスチャーとの統合(パン/ピンチ/回転/マルチタッチ)、完全なサンプル(脈打つボタン、スピナー、弾むボール)。
- シェーダーとグラデーション:Linear/Radial/Sweep/TwoPointConical グラデーション、アニメーション付きグラデーション、FractalNoise/Turbulence、カスタム SkSL ランタイムシェーダー(波形歪み、色収差、グロー、オーロラ、水面の波紋)、ShaderLib 関数、ImageShader によるテクスチャリング、シェーダーの合成、パフォーマンス(半精度、プログラムのキャッシュ)。
- フィルターとエフェクト:イメージフィルター(Blur、Offset、Morphology、DisplacementMap、Shadow、RuntimeShader)、マスクフィルター(BlurMask のスタイル:normal/solid/outer/inner)、カラーフィルター(グレースケール/セピア/反転/明るさ/コントラストの各マトリックスを使った MatrixColorFilter、BlendColor、LumaColorFilter、Lerp)、パスエフェクト(Discrete、Dash、Corner、Path1D、Path2D、Line2D、Sum)、BackdropBlur/BackdropFilter、Mask(アルファ/輝度)、すりガラス/ネオングロー/ビンテージ写真のサンプル。
- テキストとフォント:Text コンポーネント(ベースラインによる配置)、useFont フック、システムフォント、matchFont、Paragraph ビルダー(リッチテキスト、スタイル、配置)、TextPath(曲線に沿ったテキスト)、TextBlob、Glyphs、フォントのメトリクス/測定、アニメーション付きテキスト(位置、フォントサイズ)、マーキー/タイプライター/影のサンプル。
- 画像とメディア:useImage フック(require/URL/バンドル)、Image コンポーネント(フィットモード、サンプリング)、プログラムによる画像生成(base64、生ピクセル、drawAsImage)、画像の操作(リサイズ、エンコード、ピクセルの読み取り)、AnimatedImage(GIF/WebP)、SVG(useSVG、ImageSVG、文字列からの読み込み)、動画再生(useVideo、コントロール)、Skottie/Lottie(アニメーション、動的プロパティ、スロット)、Canvas のスナップショット、画像エフェクト。
- パフォーマンスの最適化:レンダリングパイプライン(JS→UI→GPU)、60fps/120fps のフレーム予算、リテインドモードとイミディエイトモードの特性、アニメーションのパフォーマンス(共有値、派生値、バッチ処理、ワークレット)、コンポーネント構造の最適化(フラットなツリー、Group、静的な Picture)、メモリ管理(オブジェクトの再利用、画像の破棄、リサイズ)、高パフォーマンスなレンダリング向けの Atlas、フィルターのコスト階層、プラットフォーム固有のヒント(iOS Metal、Android OpenGL/androidWarmup、Web CanvasKit)、プロファイリング(useFrameCallback による FPS カウンター、React DevTools、ネイティブプロファイラー)、よくある落とし穴のチェックリスト。
- 高度なパターン:アーキテクチャ(コンポーネントの合成、DrawingContext、アトミック/モレキュラーコンポーネント、カスタムフック、レンダープロップ)、実用例(インタラクティブな棒グラフ、Atlas を使ったパーティクルシステム、ジェスチャー対応の描画 Canvas、プログレスリング、波形ビジュアライザー)、デザインシステムとの統合(Skia カラーを使ったテーマプロバイダー)、テスト(ユニットテスト、ビジュアルリグレッション)、デバッグ(視覚的なグリッドオーバーレイ、パフォーマンスモニター)、よく使われるパターン(スケルトンローディング、波紋エフェクト、紙吹雪)。
コメント
Markdown 対応