0Pricing
React Native Academy · 강의

60fps 애니메이션을 위한 useNativeDriver

타이밍 및 스프링 애니메이션에서 useNativeDriver: true를 활성화하여 작업을 네이티브 스레드로 넘기고, 이를 지원하는 속성을 파악하며 성능 향상을 측정합니다.

60fps 애니메이션을 위한 useNativeDriver은(는) CoddyKit의 무료 React Native Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Native Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

The JavaScript Bridge Problem

React Native traditionally communicates between JavaScript and the native layer through a bridge — an asynchronous message channel. During animations, style updates must cross this bridge on every frame. If the JavaScript thread is busy (processing data, rendering, or garbage collecting), frames are dropped and animations stutter.

On a 60fps display, you have only ~16ms per frame to do all work. Any JavaScript overhead beyond that causes visible jank. For animations that update properties like opacity and transform, there is a better way: the native driver.

What useNativeDriver Does

When you set useNativeDriver: true, React Native serializes the animation configuration (start value, end value, duration, easing) and sends it to the native side once before the animation starts. The native layer then runs the animation entirely without touching JavaScript on each frame.

This means the animation continues smoothly even if JavaScript is blocked — loading data, parsing JSON, or running heavy logic. The result is consistently smooth 60fps animations on both iOS and Android.

Animated.timing(opacity, {
  toValue: 1,
  duration: 500,
  useNativeDriver: true, // offloads to native thread
}).start();
// JavaScript thread can now do other work
// without affecting animation smoothness

Which Properties Support Native Driver

Not all style properties can be animated with the native driver. The native driver supports transform (translateX, translateY, scale, rotate) and opacity — properties that can be applied on the GPU without a layout pass. Properties that affect layout like width, height, top, left, padding, margin, and backgroundColor are NOT supported.

If you try to animate an unsupported property with useNativeDriver: true, React Native will log a warning and silently fall back to the JS driver. Always check the property list when migrating animations.

// SUPPORTED with useNativeDriver: true
Animated.timing(opacity, { toValue: 1, useNativeDriver: true, duration: 300 })
Animated.timing(translateX, { toValue: 100, useNativeDriver: true, duration: 300 })
Animated.timing(scale, { toValue: 1.2, useNativeDriver: true, duration: 300 })

// NOT supported - must use useNativeDriver: false
Animated.timing(width, { toValue: 200, useNativeDriver: false, duration: 300 })
Animated.timing(backgroundColor, { toValue: '...', useNativeDriver: false, duration: 300 })

Mixing Native and Non-Native Animations

When you need to animate both native-driver-compatible and incompatible properties simultaneously, you must use two separate Animated.Values — one with useNativeDriver: true and one with useNativeDriver: false. You cannot use the same Animated.Value for both native and non-native driven animations.

A common pattern is running the transform and opacity (native) in a parallel group while running a color change (non-native) in a separate parallel group started at the same time.

// Two separate animations started together
Animated.timing(opacity, {
  toValue: 1,
  duration: 400,
  useNativeDriver: true,  // GPU
}).start();

Animated.timing(bgColor, {
  toValue: 1,
  duration: 400,
  useNativeDriver: false, // JS thread
}).start();

Measuring Animation Performance

React Native DevTools and Flipper can show you the frame rate of your app in real time. Look for the UI thread FPS (native rendering) and the JS thread FPS (JavaScript execution). With useNativeDriver, UI thread FPS should stay at 60 even when JS thread FPS drops.

In development mode, enable the performance monitor from the developer menu (shake device or press Cmd+D/Ctrl+D in simulator). The monitor shows both threads' frame rates overlaid on the app.

// Enable in development via developer menu:
// Shake device > Show Perf Monitor
// Or programmatically:
import { PerfMonitor } from 'react-native';
// Not an actual API - use the developer menu
// or Flipper performance plugin

Native Driver with Spring and Decay

The native driver works with all three animation types — Animated.timing, Animated.spring, and Animated.decay — as well as composition methods like Animated.parallel and Animated.sequence. Just add useNativeDriver: true to every leaf animation in the group.

The rule is: every animation in a composed group must have the same driver setting. Mixing native and non-native animated values inside a single Animated.parallel group will cause an error.

Animated.parallel([
  Animated.spring(scale, {
    toValue: 1,
    tension: 80,
    friction: 8,
    useNativeDriver: true,
  }),
  Animated.timing(opacity, {
    toValue: 1,
    duration: 300,
    useNativeDriver: true,
  }),
]).start();

Easing Functions and Native Driver

Easing functions are fully compatible with the native driver. React Native ships an Easing module with common curves: Easing.linear, Easing.ease, Easing.easeIn, Easing.easeOut, Easing.easeInOut, and configurable curves like Easing.bezier.

The easing curve is serialized and sent to the native side along with the animation config, so easing does not require JavaScript frame-by-frame computation. All the smoothness of custom easing with all the performance of native driving.

import { Animated, Easing } from 'react-native';

Animated.timing(translateY, {
  toValue: 0,
  duration: 500,
  easing: Easing.out(Easing.cubic), // decelerate into place
  useNativeDriver: true,
}).start();

// Custom bezier curve:
Animated.timing(scale, {
  toValue: 1,
  duration: 400,
  easing: Easing.bezier(0.25, 0.46, 0.45, 0.94),
  useNativeDriver: true,
}).start();

Interpolation with Native Driver

Interpolation also works with the native driver. When you call animatedValue.interpolate(), the interpolation config is serialized and evaluated natively alongside the animation. This means you can drive transforms and opacity through interpolation at 60fps without JavaScript involvement.

A common pattern is a single scroll position value (from ScrollView) interpolating into multiple header properties — opacity, scale, translateY — all natively driven for smooth parallax effects.

const scrollY = useRef(new Animated.Value(0)).current;

const headerOpacity = scrollY.interpolate({
  inputRange: [0, 100],
  outputRange: [1, 0],
  extrapolate: 'clamp',
});

const headerScale = scrollY.interpolate({
  inputRange: [0, 100],
  outputRange: [1, 0.8],
  extrapolate: 'clamp',
});

// Both driven natively by scroll position

Animated.event and Native ScrollView

Animated.event maps a native event's value directly to an Animated.Value without passing through JavaScript at all when useNativeDriver: true is set. The scroll offset from a ScrollView can feed directly into animated header effects completely on the native thread.

This is the foundation of native-thread parallax scroll effects — the most complex animation pattern in React Native — achieved without any JavaScript overhead per scroll event.

const scrollY = useRef(new Animated.Value(0)).current;

<Animated.ScrollView
  onScroll={Animated.event(
    [{ nativeEvent: { contentOffset: { y: scrollY } } }],
    { useNativeDriver: true }
  )}
  scrollEventThrottle={16}
>

Common Pitfalls with Native Driver

Common mistakes when adopting the native driver:

  • Animating unsupported properties — causes a silent fallback or error. Test with layout properties separately.
  • Calling setValue mid-animation — setValue works on both drivers but use it before starting, not while running.
  • Missing cleanup — always stop animations on unmount to prevent state updates on unmounted components.
  • Mixing drivers in one Value — one Animated.Value can only be driven by one driver type across its lifetime.

When to Skip Native Driver

You must set useNativeDriver: false for animations that affect layout (width, height, padding) or colors. These require the layout engine to recalculate positions and cannot be pre-serialized. Accept the JS-thread cost for these and ensure JS is not heavily loaded during layout animations.

A practical approach: use native driver for entrance/exit animations (transforms + opacity) and JS driver only for interactive layout changes like expanding accordion panels or resizing inputs. Keep layout animations short (under 300ms) to minimize the window of vulnerability.

// Layout animation: must use JS driver
Animated.timing(height, {
  toValue: 200,
  duration: 250,
  useNativeDriver: false, // required for height
}).start();

// But the card's entrance can still be native:
Animated.timing(opacity, {
  toValue: 1,
  duration: 250,
  useNativeDriver: true,
}).start();

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: useNativeDriver: true serializes animation config to the native thread, enabling 60fps animations even when JavaScript is busy, only transform and opacity properties support the native driver, and Animated.event with useNativeDriver lets scroll position drive animations without any JS overhead per frame. Next up we explore React Native Reanimated 3 for even more powerful gesture-driven animations.

자주 묻는 질문

“60fps 애니메이션을 위한 useNativeDriver” 강의는 무료인가요?

네 — “60fps 애니메이션을 위한 useNativeDriver” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Native Academy 강의 전체를 잠금 해제할 수 있습니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“60fps 애니메이션을 위한 useNativeDriver”에서 뭘 배우나요?

타이밍 및 스프링 애니메이션에서 useNativeDriver: true를 활성화하여 작업을 네이티브 스레드로 넘기고, 이를 지원하는 속성을 파악하며 성능 향상을 측정합니다. 브라우저에서 직접 실행하는 실습 코드로 React Native Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Native Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Native Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“60fps 애니메이션을 위한 useNativeDriver” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Native Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Native Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Animated.Value와 Animated.View
  2. 스프링 및 감쇠 애니메이션
  3. 여러 속성을 병렬 및 순차적으로 애니메이션 처리하기
  4. 60fps 애니메이션을 위한 useNativeDriver
← React Native Academy(으)로 돌아가기