Deft
Ask AI

Search

Search skills, authors and topics

vercel-labs / agent-skills

vercel-react-native-skills

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

Install

npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-native-skills
title
Animate Transform and Opacity Instead of Layout Properties
impact
HIGH
impactDescription
GPU-accelerated animations, no layout recalculation
tags
animation, performance, reanimated, transform, opacity

Animate Transform and Opacity Instead of Layout Properties

Avoid animating width, height, top, left, margin, or padding. These trigger layout recalculation on every frame. Instead, use transform (scale, translate) and opacity which run on the GPU without triggering layout.

Incorrect (animates height, triggers layout every frame):

tsx
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
function CollapsiblePanel({ expanded }: { expanded: boolean }) {  const animatedStyle = useAnimatedStyle(() => ({    height: withTiming(expanded ? 200 : 0), // triggers layout on every frame    overflow: 'hidden',  }))
  return <Animated.View style={animatedStyle}>{children}</Animated.View>}

Correct (animates scaleY, GPU-accelerated):

tsx
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
function CollapsiblePanel({ expanded }: { expanded: boolean }) {  const animatedStyle = useAnimatedStyle(() => ({    transform: [      { scaleY: withTiming(expanded ? 1 : 0) },    ],    opacity: withTiming(expanded ? 1 : 0),  }))
  return (    <Animated.View style={[{ height: 200, transformOrigin: 'top' }, animatedStyle]}>      {children}    </Animated.View>  )}

Correct (animates translateY for slide animations):

tsx
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
function SlideIn({ visible }: { visible: boolean }) {  const animatedStyle = useAnimatedStyle(() => ({    transform: [      { translateY: withTiming(visible ? 0 : 100) },    ],    opacity: withTiming(visible ? 1 : 0),  }))
  return <Animated.View style={animatedStyle}>{children}</Animated.View>}

GPU-accelerated properties: transform (translate, scale, rotate), opacity. Everything else triggers layout.