Skip to content
Back to skills

React Native List Performance

ASecurity

Optimizes React Native FlatList and SectionList performance through windowing, item memoization, getItemLayout, and efficient rendering strategies for smooth scrolling.

  • 4 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added June 12, 2026
documentationgoreactdebugginggitapiperformancedocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned June 12, 2026

npx -y skills add paulpas/agent-skill-router --skill react-native-list-performance --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of React Native List Performance?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for React Native List Performance
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/paulpas-react-native-list-performance/badge)](https://www.skillsdirectory.com/skills/paulpas-react-native-list-performance)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: react-native-list-performance
description: Optimizes React Native FlatList and SectionList performance through windowing, item memoization, getItemLayout, and efficient rendering strategies for smooth scrolling.
license: MIT
compatibility: opencode
archetypes:
  - tactical
  - generation
anti_triggers:
  - brainstorming
  - vague ideation
  - long-form architecture
response_profile:
  verbosity: low
  directive_strength: high
  abstraction_level: operational
metadata:
  version: "1.0.0"
  domain: coding
  triggers: flatlist performance, react native list, list optimization, scroll performance, windowing, getItemLayout, flashlist
  role: implementation
  scope: implementation
  output-format: code
  content-types: [code, guidance, do-dont, examples]
  related-skills: react-native-animation, react-native-navigation, react-native-ui-patterns
  author: https://github.com/vercel-labs
  source: https://github.com/vercel-labs/agent-skills
---

# React Native List Performance

Optimizes FlatList and SectionList rendering through windowed virtualization, fixed-size item layout measurements, memoized item components, and tuned batch rendering parameters. Achieves smooth 60fps scrolling even with thousands of items.

## TL;DR Checklist

- [ ] Use FlatList (not ScrollView with map) for any list over 20 items
- [ ] Extract list item components and wrap with React.memo
- [ ] Implement getItemLayout for fixed-height items
- [ ] Set windowSize (default 21) based on scroll smoothness vs. memory tradeoff
- [ ] Use stable, unique keyExtractor (never index)
- [ ] Profile scroll performance with built-in FPS monitor
- [ ] Consider FlashList for lists exceeding 500 items

---

## When to Use

Use this skill when:

- Rendering any dynamic list exceeding 20 items
- Building infinite-scroll feeds, chat threads, or data tables
- Diagnosing scroll jank or dropped frames in long lists
- Migrating from ScrollView + map() to virtualized lists
- Displaying variable-height items (comments, cards with dynamic content)
- Optimizing initial render time for lists with hundreds of items

---

## When NOT to Use

Avoid this skill for:

- Lists under 20 items with simple content — ScrollView is simpler and sufficient
- Static content that never changes — consider ScrollView for clarity
- Short forms or settings screens — FlatList overhead isn't justified
- Navigation-based lists (use React Navigation's built-in optimized rendering)

---

## Core Workflow

1. **Choose the Right List Component** — FlatList for homogeneous items, SectionList for sectioned data, FlashList for extreme performance needs.

2. **Extract and Memoize Item Components** — Move renderItem logic to a standalone component wrapped with React.memo.

   **Checkpoint:** Verify the item component doesn't create new objects/arrays on each render.

3. **Configure getItemLayout** — Provide fixed item heights to skip measurement.

   **Checkpoint:** Confirm all items are the same height before using getItemLayout.

4. **Tune Virtualization Parameters** — Adjust windowSize, maxToRenderPerBatch, initialNumToRender, and removeClippedSubviews.

5. **Profile** — Enable the FPS monitor and verify 60fps during rapid scrolling.

---

## Implementation Patterns

### Pattern 1: Proper FlatList Setup (BAD vs. GOOD)

```tsx
// ❌ BAD: Inline renderItem, no memo, index as key, no getItemLayout
<FlatList
  data={items}
  renderItem={({ item }) => (
    <View style={styles.item}>
      <Text>{item.name}</Text>
      <Text>{item.description}</Text>
    </View>
  )}
  keyExtractor={(_, index) => String(index)}
/>
```

```tsx
// ✅ GOOD: Memoized item component, stable key, getItemLayout
interface ListItemData {
  id: string;
  name: string;
  description: string;
}

const ListItem = React.memo(function ListItem({ item }: { item: ListItemData }) {
  return (
    <View style={styles.item}>
      <Text style={styles.title}>{item.name}</Text>
      <Text style={styles.subtitle}>{item.description}</Text>
    </View>
  );
});

const ITEM_HEIGHT = 72; // Fixed height for all items

function OptimizedList({ items }: { items: ListItemData[] }) {
  const renderItem = useCallback(
    ({ item }: { item: ListItemData }) => <ListItem item={item} />,
    []
  );

  return (
    <FlatList
      data={items}
      renderItem={renderItem}
      keyExtractor={(item) => item.id}
      getItemLayout={(_, index) => ({
        length: ITEM_HEIGHT,
        offset: ITEM_HEIGHT * index,
        index,
      })}
      windowSize={15}
      maxToRenderPerBatch={10}
      initialNumToRender={12}
      removeClippedSubviews={true}
    />
  );
}
```

### Pattern 2: Avoiding Inline Object Creations in renderItem

```tsx
// ❌ BAD: New style object created on every renderItem call
<FlatList
  data={items}
  renderItem={({ item }) => (
    <View style={{ padding: 16, backgroundColor: item.isActive ? '#eef' : '#fff' }}>
      <Text>{item.name}</Text>
    </View>
  )}
/>
```

```tsx
// ✅ GOOD: Styles extracted, conditional styling via computed value
const styles = StyleSheet.create({
  item: { padding: 16 },
  itemActive: { backgroundColor: '#eef' },
  itemInactive: { backgroundColor: '#fff' },
});

const ListItem = React.memo(function ListItem({ item }: { item: ItemData }) {
  return (
    <View style={[styles.item, item.isActive ? styles.itemActive : styles.itemInactive]}>
      <Text>{item.name}</Text>
    </View>
  );
});
```

### Pattern 3: Variable Height with getItemType

```tsx
// ✅ GOOD: Dynamic item types for variable-height items
type ListItemType = 'header' | 'message' | 'divider';

interface ChatItem {
  id: string;
  type: ListItemType;
  text?: string;
  sender?: string;
}

const ITEM_HEIGHTS: Record<ListItemType, number> = {
  header: 44,
  message: 80,
  divider: 24,
};

function ChatList({ messages }: { messages: ChatItem[] }) {
  const getItemLayout = useCallback(
    (data: ArrayLike<ChatItem> | null, index: number) => {
      const item = data?.[index];
      const length = ITEM_HEIGHTS[item?.type ?? 'message'];
      const offset = calculateOffset(data, index, ITEM_HEIGHTS);
      return { length, offset, index };
    },
    []
  );

  return (
    <FlatList
      data={messages}
      getItemLayout={getItemLayout}
      keyExtractor={(item) => item.id}
      renderItem={renderChatItem}
    />
  );
}

// Helper: precompute offsets for variable heights
function calculateOffset(
  data: ArrayLike<ChatItem> | null,
  index: number,
  heights: Record<string, number>
): number {
  let offset = 0;
  for (let i = 0; i < index; i++) {
    offset += heights[data?.[i]?.type ?? 'message'];
  }
  return offset;
}
```

### Pattern 4: FlashList for Extreme Performance

```tsx
// ✅ GOOD: FlashList for lists over 500 items — better memory and scroll performance
import { FlashList } from '@shopify/flash-list';

function LargeFeed({ posts }: { posts: Post[] }) {
  return (
    <FlashList
      data={posts}
      renderItem={({ item }) => <PostCard post={item} />}
      keyExtractor={(item) => item.id}
      estimatedItemSize={120}
      getItemType={(item) => item.type} // Enables type-based reuse
    />
  );
}
```

---

## Constraints

### MUST DO
- Use FlatList or FlashList for any dynamic list with more than 20 items
- Implement `getItemLayout` when all items share the same height
- Wrap list item components with `React.memo` to prevent unnecessary re-renders
- Use `useCallback` for renderItem to avoid re-creating the function on every render
- Use stable, unique keys in `keyExtractor` — never use the index
- Extract styles and static objects outside the component to avoid re-creation
- Set `removeClippedSubviews={true}` for lists with complex item layouts

### MUST NOT DO
- Use ScrollView with `map()` for lists over 20 items — lacks windowing
- Create new objects, arrays, or functions inside `renderItem`
- Use the array index as the list item key
- Set `windowSize` unnecessarily high (max 31) — consumes more memory
- Inline styles or objects in renderItem — they're recreated on every render
- Forget to memoize item components — they re-render on every parent update

---

## Related Skills

| Skill | Purpose |
|---|---|
| `react-native-animation` | Animate list items with Reanimated for smooth transitions |
| `react-native-navigation` | Navigate to list item detail screens with shared element transitions |
| `react-native-ui-patterns` | Responsive list layouts with Flexbox and useWindowDimensions |

---

## Live References

> Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.

- [React Native FlatList Documentation](https://reactnative.dev/docs/flatlist)
- [React Native SectionList Documentation](https://reactnative.dev/docs/sectionlist)
- [React Native Performance Overview](https://reactnative.dev/docs/performance)
- [Shopify FlashList Documentation](https://shopify.github.io/flash-list/)
- [React Native FPS Monitor](https://reactnative.dev/docs/debugging#fps-monitor)
- [Optimizing FlatList Configuration](https://reactnative.dev/docs/optimizing-flatlist-configuration)
- [React.memo API Reference](https://react.dev/reference/react/memo)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.