react-native-performance
Use when optimizing React Native app performance. Covers FlatList optimization, memoization, image optimization, bundle size reduction, and profiling techniques.
What this skill does
# React Native Performance
Use this skill when optimizing React Native applications for better performance, faster load times, and smoother user experiences.
## Key Concepts
### List Performance
Optimize FlatList for large datasets:
```tsx
import React, { useCallback } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
interface Item {
id: string;
title: string;
}
const ItemComponent = React.memo(({ item }: { item: Item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
));
function OptimizedList({ data }: { data: Item[] }) {
const renderItem = useCallback(
({ item }: { item: Item }) => <ItemComponent item={item} />,
[]
);
const keyExtractor = useCallback((item: Item) => item.id, []);
const getItemLayout = useCallback(
(data: any, index: number) => ({
length: 80, // Fixed item height
offset: 80 * index,
index,
}),
[]
);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
getItemLayout={getItemLayout}
// Performance optimizations
removeClippedSubviews={true}
maxToRenderPerBatch={10}
updateCellsBatchingPeriod={50}
initialNumToRender={10}
windowSize={5}
/>
);
}
const styles = StyleSheet.create({
item: {
height: 80,
padding: 16,
borderBottomWidth: 1,
borderBottomColor: '#eee',
},
});
```
### Component Memoization
Use React.memo and useMemo:
```tsx
import React, { useMemo } from 'react';
import { View, Text } from 'react-native';
interface UserCardProps {
user: {
id: string;
name: string;
email: string;
};
onPress: () => void;
}
// Memoize component to prevent unnecessary re-renders
const UserCard = React.memo(({ user, onPress }: UserCardProps) => {
return (
<View>
<Text>{user.name}</Text>
<Text>{user.email}</Text>
</View>
);
});
// Memoize expensive computations
function UserList({ users }: { users: User[] }) {
const sortedUsers = useMemo(() => {
return [...users].sort((a, b) => a.name.localeCompare(b.name));
}, [users]);
return (
<View>
{sortedUsers.map(user => (
<UserCard key={user.id} user={user} onPress={() => {}} />
))}
</View>
);
}
```
### Image Optimization
Optimize image loading and caching:
```tsx
import React from 'react';
import { Image, View } from 'react-native';
import FastImage from 'react-native-fast-image';
// Use FastImage for better performance
function OptimizedImage({ uri }: { uri: string }) {
return (
<FastImage
style={{ width: 200, height: 200 }}
source={{
uri,
priority: FastImage.priority.normal,
cache: FastImage.cacheControl.immutable,
}}
resizeMode={FastImage.resizeMode.cover}
/>
);
}
// Lazy load images
function LazyImage({ uri }: { uri: string }) {
return (
<Image
source={{ uri }}
style={{ width: 200, height: 200 }}
resizeMode="cover"
loadingIndicatorSource={require('./placeholder.png')}
/>
);
}
```
## Best Practices
### Use useCallback for Event Handlers
Prevent unnecessary re-renders:
```tsx
import React, { useCallback, useState } from 'react';
import { View, Button, Text } from 'react-native';
function Counter() {
const [count, setCount] = useState(0);
// Bad - Creates new function on every render
// const increment = () => setCount(count + 1);
// Good - Memoized callback
const increment = useCallback(() => {
setCount(c => c + 1);
}, []);
return (
<View>
<Text>{count}</Text>
<Button title="Increment" onPress={increment} />
</View>
);
}
```
### Virtualized Lists Only
Use FlatList/SectionList for scrollable content:
```tsx
// Bad - ScrollView with map (renders all items)
<ScrollView>
{items.map(item => (
<ItemComponent key={item.id} item={item} />
))}
</ScrollView>
// Good - FlatList (virtualizes items)
<FlatList
data={items}
keyExtractor={item => item.id}
renderItem={({ item }) => <ItemComponent item={item} />}
/>
```
### Avoid Anonymous Functions in Render
```tsx
// Bad - Creates new function on every render
<FlatList
data={items}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => console.log(item.id)}>
<Text>{item.title}</Text>
</TouchableOpacity>
)}
/>
// Good - Memoized render function
const renderItem = useCallback(({ item }: { item: Item }) => (
<ItemRow item={item} onPress={handleItemPress} />
), [handleItemPress]);
<FlatList
data={items}
renderItem={renderItem}
/>
```
### Optimize Bundle Size
Reduce JavaScript bundle size:
```bash
# Analyze bundle
npx react-native-bundle-visualizer
# Enable Hermes engine (app.json for Expo)
{
"expo": {
"jsEngine": "hermes"
}
}
# Enable Hermes (android/app/build.gradle for bare React Native)
project.ext.react = [
enableHermes: true
]
# Use ProGuard for Android (android/app/build.gradle)
def enableProguardInReleaseBuilds = true
```
### Code Splitting
Split code for faster initial load:
```tsx
import React, { lazy, Suspense } from 'react';
import { View, ActivityIndicator } from 'react-native';
// Lazy load heavy components
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<ActivityIndicator />}>
<HeavyComponent />
</Suspense>
);
}
```
## Common Patterns
### Debounced Search
```tsx
import React, { useState, useCallback, useEffect } from 'react';
import { TextInput, FlatList } from 'react-native';
function SearchableList({ data }: { data: Item[] }) {
const [query, setQuery] = useState('');
const [debouncedQuery, setDebouncedQuery] = useState('');
// Debounce search
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedQuery(query);
}, 300);
return () => clearTimeout(timer);
}, [query]);
const filteredData = useMemo(() => {
if (!debouncedQuery) return data;
return data.filter(item =>
item.title.toLowerCase().includes(debouncedQuery.toLowerCase())
);
}, [data, debouncedQuery]);
return (
<>
<TextInput
value={query}
onChangeText={setQuery}
placeholder="Search..."
/>
<FlatList
data={filteredData}
keyExtractor={item => item.id}
renderItem={({ item }) => <ItemComponent item={item} />}
/>
</>
);
}
```
### Optimized Animations
Use react-native-reanimated for smooth animations:
```tsx
import React from 'react';
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
} from 'react-native-reanimated';
import { Pressable } from 'react-native';
function AnimatedButton() {
const scale = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
const handlePressIn = () => {
scale.value = withSpring(0.95);
};
const handlePressOut = () => {
scale.value = withSpring(1);
};
return (
<Pressable onPressIn={handlePressIn} onPressOut={handlePressOut}>
<Animated.View style={[styles.button, animatedStyle]}>
<Text>Press Me</Text>
</Animated.View>
</Pressable>
);
}
```
### Pagination
Implement efficient pagination:
```tsx
import React, { useState, useCallback } from 'react';
import { FlatList, ActivityIndicator } from 'react-native';
function PaginatedList() {
const [data, setData] = useState<Item[]>([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
const loadMore = useCallback(async () => {
if (loading) return;
setLoading(true);
const newData = await fetchData(page);
setData(prev => [...prev, ...newData]);
setPage(p => p + 1);
setLoading(false);
}, [loading, page]);
const renderItem = useCallback(
({ item }: { item: Item }) => <ItemComponent item={item} />,
[]
);
const renderFooter = () => {
if (!loading) return nRelated in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.