home / skills / onekeyhq / app-monorepo / 1k-performance

1k-performance skill

/.claude/skills/1k-performance

This skill helps you optimize React and React Native performance by applying proven patterns for memoization, batching, and efficient list rendering.

npx playbooks add skill onekeyhq/app-monorepo --skill 1k-performance

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
2.8 KB
---
name: 1k-performance
description: Performance optimization for React/React Native — re-renders, memoization, FlashList, memory leaks, and bundle size.
allowed-tools: Read, Grep, Glob
---

# OneKey Performance Optimization

Performance optimization patterns and best practices for React/React Native applications in the OneKey monorepo.

## Quick Reference

| Category | Key Optimization | When to Use |
|----------|------------------|-------------|
| **Concurrent Requests** | Limit to 3-5, use `executeBatched` | Multiple API calls, network-heavy operations |
| **Bridge Optimization** | Minimize crossings, batch data | React Native bridge overhead, iOS/Android |
| **List Rendering** | FlashList, windowSize={5}, content-visibility | Lists with 100+ items |
| **Memoization** | memo, useMemo, useCallback | Expensive computations, prevent re-renders |
| **Heavy Operations** | InteractionManager, setTimeout | UI blocking operations |

## Critical Performance Rules

### ❌ FORBIDDEN: Too Many Concurrent Requests

```typescript
// ❌ BAD - Can freeze UI with 15+ requests
const requests = items.map(item => fetchData(item));
await Promise.all(requests);
```

### ✅ CORRECT: Batched Execution with Concurrency Limit

```typescript
async function executeBatched<T>(
  tasks: Array<() => Promise<T>>,
  concurrency = 3,
): Promise<Array<PromiseSettledResult<T>>> {
  const results: Array<PromiseSettledResult<T>> = [];
  for (let i = 0; i < tasks.length; i += concurrency) {
    const batch = tasks.slice(i, i + concurrency);
    const batchResults = await Promise.allSettled(
      batch.map((task) => task()),
    );
    results.push(...batchResults);
  }
  return results;
}

const tasks = items.map(item => () => fetchData(item));
await executeBatched(tasks, 3); // Max 3 concurrent
```

## 🚨 Built-in Optimizations

**Already Optimized - NO ACTION NEEDED:**

| Component | Optimization | Details |
|-----------|--------------|---------|
| `ListView` | `windowSize={5}` | Auto-limits visible items |
| `Tabs` | `contentVisibility: 'hidden'` | Hides inactive tabs |
| `Dialog` | `contentVisibility: 'hidden'` | Hides when closed |

## Detailed Guide

For comprehensive performance optimization strategies, see [performance.md](references/rules/performance.md).

Topics covered:
- Concurrent request control
- React Native bridge optimization
- Heavy operations offloading
- List rendering (windowSize, FlashList, content-visibility)
- Memoization & callbacks
- State updates optimization
- Image optimization
- Async operations & race conditions
- Real-world iOS AppHang case study

## Related Skills

- `/1k-coding-patterns` - General coding patterns and conventions
- `/1k-sentry-analysis` - Sentry error analysis (includes performance issues)
- `/react-native-best-practices` - React Native specific optimizations

Overview

This skill provides targeted performance optimization patterns for React and React Native apps focused on re-renders, memoization, list rendering, bridge cost, memory leaks, and bundle size. It collects practical rules, helper utilities, and built-in component behaviors used to keep UI responsive and reduce resource usage. The guidance is concise and ready to apply to mobile, web, and desktop React projects.

How this skill works

The skill inspects common performance pitfalls and prescribes concrete fixes: batching concurrent requests with a concurrency limiter, minimizing React Native bridge crossings, using FlashList and tuned windowSize for long lists, and applying memo/useCallback to prevent unnecessary renders. It also recommends offloading heavy work via InteractionManager or setTimeout, and highlights components that are already optimized to avoid redundant work.

When to use it

  • When many network requests can overwhelm the UI thread or device (use batched execution).
  • When lists exceed ~100 items or show jank while scrolling (use FlashList and windowSize tuning).
  • When frequent re-renders occur due to unstable props or inline functions (apply memo/useCallback/useMemo).
  • When native bridge calls are frequent or carry large payloads (batch and minimize crossings).
  • When heavy synchronous work blocks frames or causes AppHang on iOS (offload to InteractionManager or schedule async).

Best practices

  • Limit concurrent requests to 3–5; use an executeBatched helper to run Promise-returning tasks in small batches.
  • Prefer FlashList for large lists and set windowSize to 5 for typical mobile use; use contentVisibility to hide inactive views.
  • Memoize expensive computations and callbacks: wrap pure components with memo and use useMemo/useCallback for derived values and handlers.
  • Batch data sent over the React Native bridge and avoid frequent round-trips; serialize less and reduce payload size.
  • Move non-UI heavy work off the main thread using InteractionManager, requestIdleCallback, or background workers where available.

Example use cases

  • Loading assets and account data for dozens of wallets without freezing the UI by running fetches with executeBatched(concurrency=3).
  • Replacing FlatList with FlashList and tuning windowSize for a transaction history screen with 1000+ rows.
  • Fixing repeated re-renders by memoizing a transaction row component and stabilizing handler props with useCallback.
  • Batched native calls when syncing account state to reduce bridge crossings on Android and iOS.
  • Deferring image decoding and heavy parsing to after initial render using InteractionManager to prevent first-frame jank.

FAQ

How many concurrent requests are safe on mobile?

Aim for 3–5 concurrent requests. Adjust downward on low-end devices; use batching to avoid spikes.

When should I prefer FlashList over FlatList?

Use FlashList for long lists (100+ items) or when you observe scrolling jank; tune windowSize to reduce work for offscreen items.