Performance Optimization ב-React Native

📚 פיתוח Mobile ⏱️ 13 דק׳ 🎓 מתקדם ✓ חינם לגמרי
Performance Optimization ב-React Native

60fps או מוות, למה Performance ב-React Native שונה מה-Web

זה קרה באפליקציה אחת ב-production עם מיליון משתמשים פעילים: מסך מסוים גרם ל-battery drain של 15% בחמש דקות. חנות האפליקציות הציגה ביקורות: "האפליקציה מחממת את הטלפון". הדירוג ירד ל-2.8. הסיבה? FlatList עם תמונות שלא הוטמעו כראוי, animations שרצו על ה-JS thread, ו-useEffect עם dependency array שגוי שגרם ל-loop אינסופי של API calls.

Performance ב-React Native שונה מהווב. יש שני threads: ה-JS thread (לוגיקה, state, event handlers) וה-UI thread (native rendering). כשה-JS thread עמוס, animations מתגמגמות. הדרך לתקן: להעביר כמה שיותר עבודה ל-UI thread, ולהפחית render cycles מיותרים. Claude עוזר לזהות, לנתח, ולתקן את שתי הבעיות במהירות.

עדכון 2025: מאז React Native 0.76, New Architecture מופעלת כברירת מחדל, Fabric renderer, JSI (JavaScript Interface), ו-TurboModules. Fabric מעניק concurrent rendering ו-synchronous JS-native communication. Hermes 1.0 משפר startup ב-40% לעומת JSC. לפני כל micro-optimization, ודאו שה-New Architecture מופעלת.

Prompt ראשון: Audit Performance של Component

הפרומפט הזה שולח קוד ומקבל ניתוח מלא של בעיות performance:

You are a React Native performance expert.
// [1] domain ספציפי, performance, לא general RN

Audit this component for performance issues.
Identify: unnecessary re-renders, expensive computations,
memory leaks, missing memoization, and JS thread blockers.
// [2] checklist מפורש, Claude יכסה כל נושא בנפרד

[PASTE YOUR COMPONENT CODE HERE]

For each issue found:
1. Explain why it causes performance degradation
2. Show the fixed code
3. Estimate impact: low / medium / high
// [3] output מובנה, שלושה חלקים לכל issue

Also identify what to measure with Flipper or
React DevTools Profiler to confirm the fix.
// [4] measurement, performance ללא מדידה היא guessing

FlashList v2, הכלי שמחליף FlatList ב-2025

FlatList מצוינת, אבל FlashList מ-Shopify משיגה ביצועים טובים משמעותית ברשימות ארוכות. במקום למחוק ולייצר components מחדש (virtualization), FlashList ממחזרת components, cell recycling. ב-2025 יצאה FlashList v2, rewrite מלא עבור New Architecture.

מדדFlatList (לפני)FlashList v2 (אחרי)
ממוצע FPS36.956.9 (+54%)
CPU usage198.9%36.5% (-82%)
JS threadמעל 90%מתחת ל-10%
Blank area בגלילהבסיסי50% פחות (vs v1)

מ-Shopify Engineering: "FlashList v2 delivers faster load times, improved scrolling performance, and precise rendering without requiring item size estimates."

Migration מ-FlatList ל-FlashList v2 דורש שלושה שינויים עיקריים: החלפת import, החלפת שם הרכיב, והוספת estimatedItemSize. אם הרשימה שלכם מעל 50 items, שווה את ה-migration.

ה-FlatList שלי איטי, תעזור לי לשפר אותו
Audit this React Native FlatList for performance issues. The list renders 500+ products with images on iOS and Android. Users report jank during fast scrolling on mid-range Android devices. Apply these optimizations: getItemLayout, keyExtractor with stable IDs, renderItem memoization with custom comparison, windowSize=5, removeClippedSubviews on Android. Also evaluate whether migrating to FlashList v2 is justified. Show before/after code, explain why each change improves scroll FPS, and specify which Flipper plugin to use for measurement. [PASTE CODE HERE]

FlatList עם כל ה-Optimizations (כשנשארים)

כשFlashList לא מתאים (למשל, ביישום קיים עם New Architecture מורכבת), הנה FlatList מותאמת מלאה:

import React, { memo, useCallback, useMemo } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

const ITEM_HEIGHT = 88;

// React.memo עם custom comparison, re-render רק אם id או price השתנה
const ProductItem = memo(({ item, onPress }) => (
  <View style={styles.item}>
    <Text numberOfLines={2}>{item.name}</Text>
    <Text>{item.price} ₪</Text>
  </View>
), (prev, next) => prev.item.id === next.item.id && prev.item.price === next.item.price);

export const ProductList = ({ products, onProductPress }) => {
  // useCallback: מונע יצירת function חדשה בכל render
  const renderItem = useCallback(({ item }) => (
    <ProductItem item={item} onPress={() => onProductPress(item.id)} />
  ), [onProductPress]);

  // getItemLayout: FlatList יודע מיקום כל item מראש
  const getItemLayout = useCallback((_, index) => ({
    length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index,
  }), []);

  const keyExtractor = useCallback((item) => item.id, []);

  return (
    <FlatList
      data={products}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      initialNumToRender={10}
      maxToRenderPerBatch={10}
      windowSize={5}              // default 21, גורם לconsume זיכרון מיותר
      updateCellsBatchingPeriod={100}
      removeClippedSubviews={true} // Android only
    />
  );
};

Reanimated, Animations על UI Thread תמיד

// טעות נפוצה: animation על JS thread, מתגמגמת כשJS עמוס
import { Animated } from 'react-native';
const opacity = new Animated.Value(0);
Animated.timing(opacity, { toValue: 1, duration: 300,
  useNativeDriver: false // ❌ מריץ על JS thread
}).start();

// נכון: Reanimated 3, worklet על UI thread, 60fps תמיד
import Animated, { useSharedValue, useAnimatedStyle, withTiming }
  from 'react-native-reanimated';

const opacity = useSharedValue(0);
const animStyle = useAnimatedStyle(() => ({ opacity: opacity.value }));
// withTiming רץ על UI thread כ-worklet, לא נחסם ע"י JS thread כבד
const fadeIn = () => { opacity.value = withTiming(1, { duration: 300 }); };

טעויות נפוצות שClaude עוזר לזהות

FlatList היא מ-React Native; FlashList היא פיתוח של גוגל
FlatList משתמשת ב-virtualization (מחסלת ומייצרת); FlashList ממחזרת pool קבוע של components
FlatList תומכת ב-New Architecture; FlashList עובדת רק על Legacy Architecture
אין הבדל מהותי, שתיהן פועלות בדיוק אותו אופן
Console.log שולח נתונים לשרת המפתח ומאט את החיבור
Console.log מזיק רק ב-development, לא בproduction
כל console.log עובר דרך JSI, מאיט את ה-JS thread, ובגלילה מהירה, זה עשרות calls לשנייה
Console.log גורם לתוצאות לא עקביות בין משתמשים שונים
כי New Architecture דורשת הגדרה ידנית מורכבת שיש לעשות ראשונה
כי Fabric + JSI מספקים concurrent rendering ו-synchronous native communication, baseline חזק שנותן return גבוה על כל optimization אחרת
כי New Architecture מחייבת שימוש ב-FlashList, FlatList לא עובדת עליה
כי New Architecture רק משנה את המראה החיצוני של הapp ללא השפעה על ביצועים

כלי מדידה, מה להפעיל מהיום הראשון

הגדירו את כלי המדידה מהיום הראשון. כשתגיעו ל-battery drain ב-production, תוכלו לזהות את הבעיה תוך דקות, לא ימים.

רוצה ללמוד עם מעקב התקדמות, קוויזים ותעודה?

כל 130 השיעורים פתוחים בחינם, כולל נגן אינטראקטיבי, שמירת התקדמות ותעודה דיגיטלית בסיום.