◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-03-30上級

Rork × React Native Reanimated & Gesture Handler 実践ガイド — 60fps を維持するアニメーション設計と高度なジェスチャーインタラクション

Reanimated 3 と Gesture Handler で 60fps を保つ設計を、壁紙・癒し系アプリの実運用で踏んだ落とし穴とともに整理しました。runOnJS の発火遅延、useDerivedValue キャッシュ、FlashList との併用、cancelAnimation 漏れなど、公式ドキュメント外の知見を実測値付きで共有します。

Reanimated10Gesture Handlerアニメーション10パフォーマンス33UI/UX3React Native239Rork585

✦ プレミアム記事

取り組みの背景 — なぜ Reanimated と Gesture Handler が必要なのか

モバイルアプリの品質を決定づける要素のひとつが、アニメーションの滑らかさとジェスチャーの反応速度です。ユーザーはスクロール、スワイプ、ピンチズームといった操作を無意識に行っており、わずかなカクつきや遅延でも「このアプリは使いにくい」と感じてしまいます。

React Native の標準 Animated API は基本的なアニメーションには十分ですが、複雑なジェスチャー連動アニメーションや 60fps を維持する高度なトランジションには限界があります。ここで登場するのが React Native Reanimated 3 と React Native Gesture Handler です。

Reanimated はアニメーションロジックを UI スレッド(ネイティブ側) で直接実行する仕組みを持ち、JavaScript スレッドのボトルネックを完全に回避します。Gesture Handler はネイティブレベルでジェスチャーを認識し、Reanimated と組み合わせることで「指に吸いつくような」操作感を実現します。

私は 2013 年から個人で iOS / Android アプリを運営していて、壁紙系・癒し系・引き寄せ系といった「静かに毎日触ってもらう」ユーティリティを中心に育ててきました。こうしたアプリでは派手な演出は要らない代わりに、スワイプやピンチの一瞬の引っかかりがそのまま離脱につながります。Reanimated と Gesture Handler を実際のプロダクトに入れてきて、公式ドキュメントどおりに書いても本番でだけ崩れる場面に何度もぶつかりました。この記事では、基本のアーキテクチャと4つの実装パターンに加えて、その「ドキュメント外の落とし穴」を実測値とともにまとめています。


Reanimated 3 のアーキテクチャ — Worklet と Shared Value の仕組み

なぜ従来の Animated API では不十分なのか

React Native の標準 Animated API は、アニメーションの値変更を JS スレッドで計算し、ブリッジ経由で UI スレッドに送信します。このアーキテクチャでは、JS スレッドが重い処理(API コール、データ変換など)で忙しいとき、アニメーションがカクつきます。

Reanimated 3 はこの問題を Worklet という概念で解決します。Worklet とは、UI スレッド上で直接実行される JavaScript 関数です。'worklet' ディレクティブを関数の先頭に記述するだけで、その関数は自動的に UI スレッドにシリアライズされて実行されます。

Shared Value — スレッド間の高速なデータ共有

useSharedValue で作成された値は、JS スレッドと UI スレッドの両方から安全にアクセスできます。従来のブリッジを経由しないため、値の更新がフレーム落ちなく反映されます。

import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  withTiming,
  Easing,
} from 'react-native-reanimated';
 
// コンポーネント内で使用
// Shared Value を作成(UIスレッドとJSスレッドの両方からアクセス可能)
const translateX = useSharedValue(0);
const scale = useSharedValue(1);
 
// アニメーションスタイルを宣言的に定義
// この関数はUIスレッドで実行されるため、JSスレッドのブロックを回避
const animatedStyle = useAnimatedStyle(() => ({
  transform: [
    { translateX: translateX.value },
    { scale: scale.value },
  ],
}));
 
// スプリングアニメーションで値を更新
// damping: 振動の減衰速度、stiffness: バネの硬さ
const handlePress = () => {
  translateX.value = withSpring(200, {
    damping: 15,      // 低い値 = より多くバウンド
    stiffness: 150,   // 高い値 = より速い動き
    mass: 1,          // 質量(慣性に影響)
  });
  scale.value = withTiming(1.2, {
    duration: 300,
    easing: Easing.bezier(0.25, 0.1, 0.25, 1),
  });
};
 
// JSX で使用
// <Animated.View style={[styles.box, animatedStyle]} />

Derived Value — 計算済みアニメーション値

useDerivedValue を使うと、他の Shared Value に基づいた計算値を UI スレッド上で自動的に更新できます。

import { useDerivedValue, interpolate } from 'react-native-reanimated';
 
// translateX に基づいて回転角度を自動計算
const rotation = useDerivedValue(() => {
  // translateX が -200〜200 のとき、回転を -30〜30 度にマッピング
  return interpolate(
    translateX.value,
    [-200, 0, 200],
    [-30, 0, 30],
    'clamp' // 範囲外の値をクランプ
  );
});
 
// 透明度も連動して変化
const opacity = useDerivedValue(() => {
  return interpolate(
    Math.abs(translateX.value),
    [0, 150, 200],
    [1, 0.8, 0.3]
  );
});

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦壁紙グリッドの初期描画を 820ms から 310ms、メモリを 180MB から 96MB に下げた FlashList と単一 Shared Value の併用パターン
✦runOnJS の発火遅延・useDerivedValue キャッシュ・cancelAnimation 漏れなど、Crashlytics と実機計測で気づいた本番運用の落とし穴6つ
✦累計5,000万DLの個人開発で固めた withSpring プリセット2種と、ScrollView とジェスチャーが競合したときの実機チェックリスト
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⬡ 開発ツール2026-04-25
Rork アプリでスケルトンスクリーンを実装する — 読み込み中の体感速度を改善する実践パターン
Rork で作ったアプリの「読み込み中」が、ただのぐるぐるスピナーで終わっていませんか。スケルトンスクリーンと Shimmer エフェクトを取り入れるだけで、体感速度と離脱率は大きく変わります。実装の型と注意点を整理しました。
⬡ 開発ツール2026-07-24
同じ通信が同時に何本も飛ぶのを1本に束ねる — 参照カウント付きシングルフライト層の設計
起動直後に同じ API へ何本ものリクエストが同時に飛ぶ多重フェッチを、進行中の Promise を共有して1本に束ねる設計です。束ねる範囲を決めるキーの組み立て方、失敗した Promise を配り続けてしまう罠、呼び出し側の中断が全体を巻き込む罠、そして束ね率を数えて回帰を止めるテストまで、参照カウント付きシングルフライト層の実装を実測の通信ログとともに残します。
⬡ 開発ツール2026-05-02
FlatList でカクつき始めたら読む — Rork アプリを FlashList v2 で快適にする実装手順
Rork で生成したアプリの長いリストが重くなったとき、FlashList v2 へ移行することでスクロールが大幅に滑らかになります。estimatedItemSize が不要になった v2 の思想を踏まえた、現実的な移行手順を解説します。