React: حدود الأخطاء وتصحيح الأخطاء

آخر تحديث: 2026-08-26

كان توم مسؤولاً عن البنية الخلفية للتجارة الإلكترونية، التي واجهت مشكلة «الشاشة البيضاء» على الموقع النشط — فقد أبلغ المستخدمون أن صفحة تفاصيل الطلب كانت فارغة تمامًا عند فتحها، وعرضت وحدة التحكم الخطأ Cannot read properties of undefined (reading 'name'). كان السبب هو خطأ في JavaScript لم يتم اكتشافه، أطلقه مكون فرعي أثناء مرحلة العرض، مما تسبب في تعطل شجرة مكونات React بأكملها. يحتاج توم إلى إنشاء نظام حدود الأخطاء داخل التطبيق لضمان ألا يؤثر فشل المكونات الفردية على قابلية استخدام الصفحة بشكل عام.


1. ما ستتعلمه



2. المخططات المفاهيمية

يوضح الشكل أدناه عملية التقاط «حدود الخطأ» وسلسلة التحليل في أداة «Profiler»:

100%
flowchart TD
    A[React Component tree] --> B[Error Boundary]

    B --> C{Is there an error in the rendering of the child component??}
    C -->|No| D[Normal Rendering]
    C -->|is | E[getDerivedStateFromError]

    E --> F[Update state.hasError = true]
    F --> G[Rendering fallback UI]

    G --> H{Click to retry??}
    H -->|is | I[Reset state]
    I --> A
    H -->|No| J[Stay in the lower division UI]

    K[React DevTools Profiler] --> L[Recording Component Rendering]
    L --> M[Flame Pattern Analysis]
    M --> N["Identify Time-Consuming Components(Yellow/Red)"]
    N --> O[React.memo / useMemo Optimization]

    style B fill:#e3f2fd,stroke:#1565c0
    style E fill:#fff3e0,stroke:#e65100
    style G fill:#e8f5e9,stroke:#2e7d32
    style K fill:#f3e5f5,stroke:#7b1fa2


3. سيناريو واقعي

مستوى معالجة الأخطاء النطاق استراتيجية الاستعادة السيناريوهات القابلة للتطبيق
try/catch عملية واحدة غير متزامنة إعادة المحاولة/الخطة البديلة طلبات واجهة برمجة التطبيقات (API)، عمليات Promise
حدود الخطأ خطأ في عرض شجرة المكونات الفرعية واجهة المستخدم الاحتياطية + زر إعادة المحاولة حماية المكون من ظهور الشاشة البيضاء
حالات الرفض غير المعالجة على مستوى النظام أخطاء الـ«Promise» غير المكتشفة إعداد تقارير السجلات المراقبة الشاملة
window.onerror أخطاء التزامن العامة إعداد تقارير السجلات المراقبة الشاملة
React DevTools تصحيح الأخطاء أثناء التطوير حل المشكلات حل مشكلات الأداء/العرض

تتألف صفحة تفاصيل طلب توم من العناصر التالية:

TEXT 📖 للعرض فقط
OrderPage
  ├── OrderHeader      (Order Number、Status)
  ├── OrderItems       (Product List)
  │   └── OrderItem    × N(Single Item,Includes price calculation)
  ├── ShippingInfo     (Shipping Information)
  └── PaymentInfo      (Payment Information)

كان سبب الحادث الذي وقع عبر الإنترنت هو عدم وجود الحقل price في بيانات المنتج الخاصة بطلب معين، وعندما قام المكون OrderItem بالوصول إلى item.price.toFixed(2)، أطلق خطأً TypeError، مما تسبب في ظهور شاشة فارغة في OrderPage بأكمله.

الطريقة الصحيحة هي إحاطة منطقة OrderItems بـ «حدود الخطأ» (Error Boundary) بحيث تظل رأس صفحة الطلب ومعلومات الدفع معروضة بشكل صحيح حتى في حالة فشل عرض قائمة المنتجات. بالإضافة إلى ذلك، يتعين على توم تعلم كيفية استخدام أداة تحليل الأداء (Profiler) في React DevTools لتحديد معوقات الأداء.


(1) حدود الخطأ — شبكة أمان على مستوى المكونات

«حدود الخطأ» (Error Boundary) هي آلية تعريفية لمعالجة الأخطاء توفرها React. عندما يطلق أي مكون في شجرة فرعية خطأً خلال مرحلة العرض، أو في إحدى طرق دورة الحياة، أو في منشئه، يمكن لـ «حدود الخطأ» التقاط هذا الخطأ وعرض واجهة مستخدم بديلة، بدلاً من التسبب في عرض شاشة فارغة في التطبيق بأكمله.

ملاحظة: لا يمكن حاليًا تنفيذ «Error Boundary» إلا باستخدام مكونات الفئات (تخطط React لتوفير نسخة باستخدام Hooks في الإصدارات المستقبلية).

▶ المثال 1: مكون ErrorBoundary عام

TSX
import { Component, ErrorInfo, ReactNode } from 'react'

interface ErrorBoundaryProps {
  children: ReactNode
  /** Custom Downgrade UI */
  fallback?: ReactNode
  /** Error Callback(Submit Sentry etc.) */
  onError?: (error: Error, errorInfo: ErrorInfo) => void
}

interface ErrorBoundaryState {
  hasError: boolean
  error: Error | null
}

class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props)
    this.state = { hasError: false, error: null }
  }

  // Static Methods:Update Based on the Error state
  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error }
  }

  // Life Cycle:Performing side effects after catching an error(Log Reporting)
  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    console.error('ErrorBoundary An error was caught:', error.message)
    console.error('Component Stack:', errorInfo.componentStack)

    // Reported to the error monitoring service
    if (this.props.onError) {
      this.props.onError(error, errorInfo)
    }

    // Can be integrated into actual projects Sentry:
    // Sentry.captureException(error, { extra: errorInfo })
  }

  handleReset = () => {
    this.setState({ hasError: false, error: null })
  }

  render() {
    if (this.state.hasError) {
      // Use Custom fallback Or default to a lower level UI
      if (this.props.fallback) {
        return this.props.fallback
      }

      return (
        <div
          role="alert"
          style={{
            padding: '32px 24px',
            margin: 16,
            background: '#fff2f0',
            border: '1px solid #ffccc7',
            borderRadius: 8,
            textAlign: 'center',
          }}
        >
          <h2 style={{ color: '#ff4d4f', margin: '0 0 12px' }}>
            A component error occurred
          </h2>
          <p style={{ color: '#666', marginBottom: 8, fontSize: 14 }}>
            {this.state.error?.message || 'An unknown error has occurred'}
          </p>
          <button
            onClick={this.handleReset}
            style={{
              padding: '6px 20px',
              background: '#ff4d4f',
              color: '#fff',
              border: 'none',
              borderRadius: 4,
              cursor: 'pointer',
              fontSize: 14,
            }}
          >
            Retry
          </button>
        </div>
      )
    }

    return this.props.children
  }
}

export default ErrorBoundary

استخدام ErrorBoundary في المشاريع العملية

TSX
// Layered Wrapping — Each independent area has its own ErrorBoundary
function OrderPage({ orderId }: { orderId: string }) {
  return (
    <div>
      {/* Order Header Information:It will display correctly even if there is an error below. */}
      <ErrorBoundary fallback={<p>Failed to load order</p>}>
        <OrderHeader orderId={orderId} />
      </ErrorBoundary>

      {/* Product List:Errors in one area do not affect other areas */}
      <ErrorBoundary
        onError={(err) => {
          // Rendering Error in the List of Submitted Products
          fetch('/api/log-error', {
            method: 'POST',
            body: JSON.stringify({ error: err.message, orderId }),
          })
        }}
      >
        <OrderItems orderId={orderId} />
      </ErrorBoundary>

      {/* Payment Information */}
      <ErrorBoundary>
        <PaymentInfo orderId={orderId} />
      </ErrorBoundary>
    </div>
  )
}

▶ المثال 2: مكون UserProfile مع ميزة استعادة البيانات في حالة الخطأ

في السيناريوهات الواقعية، قد لا يكفي أحيانًا عرض واجهة المستخدم الاحتياطية وحدها — فقد يحتاج المستخدمون إلى تحديث بيانات معينة. وفيما يلي مثال على كيفية استخدام حدود الخطأ مع ميزة «إعادة المحاولة»:

TSX
import { useState } from 'react'
import ErrorBoundary from './ErrorBoundary'

// Simulating Data Retrieval That Results in Errors
function fetchUserData(userId: number) {
  return fetch(`/api/users/${userId}`).then(res => {
    if (!res.ok) throw new Error('Failed to retrieve user data')
    return res.json()
  })
}

// Data display components that may have rendering errors
function UserInfo({ userId }: { userId: number }) {
  const [user, setUser] = useState<any>(null)
  const [loading, setLoading] = useState(true)

  useState(() => {
    fetchUserData(userId)
      .then(setUser)
      .finally(() => setLoading(false))
  })

  if (loading) return <p>Loading......</p>

  // If user Data Structure Exception,An error may occur here
  return (
    <div>
      <h3>{user.name}</h3>         {/* possibly:Cannot read properties of undefined */}
      <p>{user.profile.bio}</p>    {/* possibly:Cannot read properties of undefined */}
    </div>
  )
}

// Outer Container:With retries key Mechanism
function UserProfile({ userId }: { userId: number }) {
  const [retryKey, setRetryKey] = useState(0)

  return (
    <ErrorBoundary
      key={retryKey}  // Change key It will unmount and remount the subtree
      fallback={
        <div style={{ padding: 24, textAlign: 'center' }}>
          <p>Error loading user information</p>
          <button onClick={() => setRetryKey(k => k + 1)}>
            Retry Loading
          </button>
        </div>
      }
    >
      <UserInfo userId={userId} />
    </ErrorBoundary>
  )
}

نصيحة مهمة: key={retryKey} اجعل ErrorBoundary يقوم بإلغاء ربط شجرته الفرعية وإعادة إنشائها عند تشغيل عملية إعادة المحاولة، وبذلك يتم إعادة تعيين حالة جميع المكونات التابعة.


(2) الأخطاء التي لا يمكن اكتشافها بواسطة حدود الأخطاء

Error Boundaries are not a panacea; they cannot catch the following four types of errors:

نوع الخطأ السبب الحل
الأخطاء في معالجة الأحداث عدم تنفيذ معالجات الأحداث أثناء مرحلة العرض وضع منطق معالجة الأحداث داخل كتلة try/catch
الأخطاء في الكود غير المتزامن لا تتم عمليات الاستدعاء المرتدة لـ setTimeout و Promise ضمن دورة عرض React استخدم try/catch أو Promise.catch
الأخطاء في العرض من جانب الخادم (SSR) حدود الأخطاء لا تسري إلا على جانب العميل تغليف عملية العرض في كتل try/catch في حالة العرض من جانب الخادم
خطأ خاص بـ «Error Boundary» يُطلق خطأً لا يمكن التقاطه بحد ذاته قم بتغليفه بـ «Error Boundary» آخر في المستوى الخارجي

معالجة الأحداث + المعالجة السليمة للأخطاء في الكود غير المتزامن

TSX
function PaymentForm() {
  async function handleSubmit() {
    try {
      const result = await submitPayment()
      // Processed successfully
    } catch (error) {
      // Asynchronous errors are caught here,Error Boundary That's none of my business
      console.error('Payment Failed:', error)
      // Display Error UI(For example, setting state)
      setError(error instanceof Error ? error.message : 'Payment Failed')
    }
  }

  // Errors in the event must also be used try/catch
  function handleClick() {
    try {
      processPayment()
    } catch (error) {
      setError('Processing Failed,Please try again.')
    }
  }
}

(3) تحليل الأداء باستخدام أداة تحليل الأداء في React DevTools

تُعد علامة التبويب «Profiler» في React DevTools أداة أساسية لتحليل أداء عرض المكونات. فهي تُنشئ «رسمًا بيانيًّا على شكل لهب» يوضح بصريًّا وقت العرض لكل مكون.

تعليمات الاستخدام

TEXT 📖 للعرض فقط
1. Open your browser DevTools → Components Tabs
2. Switch to Profiler Sublabel
3. Click the blue record button(Start Recording)
4. Performing actions on the page(Click、Scrolling, etc.)
5. Click the Stop button(End Recording)
6. View the flame diagram

كيفية تفسير الرسوم البيانية الشعلية

TEXT 📖 للعرض فقط
┌────────────────────────────────────────────┐
│  App (0.3ms)                               │
│  ├── Navbar (0.2ms)                        │
│  ├── OrderPage (2.1ms)                     │
│  │   ├── OrderHeader (0.4ms)  ── Gray     │
│  │   ├── OrderItems (1.5ms)   ── Yellow     │
│  │   │   └── OrderItem × 20 (each 0.3ms)     │
│  │   └── PaymentInfo (0.2ms) ── Gray      │
│  └── Footer (0.1ms)                        │
└────────────────────────────────────────────┘

▶ المثال 3: قياس وقت العرض باستخدام مكون «Profiler»

يمكن لمكون <Profiler> المدمج في React قياس وقت عرض مكون معين في الكود الخاص بك بدقة، مما يجعله مناسبًا للمراقبة الآلية لمقاييس الأداء:

TSX
import { Profiler } from 'react'

type ProfilerPhase = 'mount' | 'update' | 'nested-update'

interface ProfileMetrics {
  id: string
  phase: ProfilerPhase
  actualDuration: number      // Actual rendering time for this render(milliseconds)
  baseDuration: number        // Worst-case runtime for a subtree
  startTime: number           // Render Start Timestamp
  commitTime: number          // Submit to DOM timestamp
  interactions: Set<any>      // Related Interaction Tracking
}

// Performance Monitoring Callbacks
function onRenderCallback(
  id: string,
  phase: ProfilerPhase,
  actualDuration: number,
  baseDuration: number,
  startTime: number,
  commitTime: number,
) {
  // Record to the performance log
  if (actualDuration > 16) {  // More than 16ms = Frame drop threshold (60fps)
    console.warn(
      `[Performance Alerts] ${id} in  ${phase} Time Taken per Stage ${actualDuration.toFixed(1)}ms,` +
      `More than 16ms Frame Budget!`
    )

    // Reported to the performance monitoring system
    // reportPerformance({ id, phase, actualDuration, baseDuration })
  }

  // Output from the development environment to the console
  if (process.env.NODE_ENV === 'development') {
    console.table({
      'Components': id,
      'Phase': phase,
      'Actual time taken(ms)': actualDuration.toFixed(1),
      'Benchmark Duration(ms)': baseDuration.toFixed(1),
    })
  }
}

// Big Data List——Potential Performance Bottlenecks
function ProductList({ products }: { products: Product[] }) {
  return (
    <Profiler id="ProductList" onRender={onRenderCallback}>
      <div style={{ display: 'grid', gap: 16, gridTemplateColumns: 'repeat(3, 1fr)' }}>
        {products.map(product => (
          <ProductCard key={product.id} product={product} />
        ))}
      </div>
    </Profiler>
  )
}

استراتيجيات شائعة لتحسين الأداء

TSX
// 1. React.memo — Avoid Unnecessary Re-rendering
const ProductCard = React.memo(function ProductCard({
  product,
}: {
  product: Product
}) {
  return (
    <div style={{ border: '1px solid #eee', padding: 16, borderRadius: 8 }}>
      <img src={product.image} alt={product.name} width="100%" />
      <h4>{product.name}</h4>
      <p>${product.price}</p>
    </div>
  )
})

// 2. useMemo — Cache the results of expensive computations
function OrderSummary({ items }: { items: OrderItem[] }) {
  const totalPrice = useMemo(() => {
    return items.reduce((sum, item) => {
      // Assuming that complex currency conversions were performed here
      return sum + convertCurrency(item.price, item.currency)
    }, 0)
  }, [items])

  return <p>Total:${totalPrice.toFixed(2)}</p>
}

// 3. useCallback — Stable function references
function OrderList({ orders, onSelect }: {
  orders: Order[]
  onSelect: (id: string) => void
}) {
  // ✅ use  useCallback Keep references consistent
  const handleSelect = useCallback((id: string) => {
    onSelect(id)
  }, [onSelect])

  return orders.map(order => (
    <OrderRow key={order.id} order={order} onSelect={handleSelect} />
  ))
}

(4) تصحيح الأخطاء باستخدام لوحة المكونات في React DevTools

بالإضافة إلى أداة «Profiler»، تُعد لوحة «Components» في React DevTools أيضًا أداة قوية لتصحيح الأخطاء في الاستخدام اليومي:

الميزة الغرض طريقة التشغيل
تصفح شجرة المكونات عرض التسلسل الهرمي للمكونات انقر على DevTools → Components
عرض الخصائص/الحالة في الوقت الفعلي التحقق من الحالة الحالية للمكون اختيار مكون لعرض اللوحة اليمنى
تعديل الحالة مباشرةً اختبار واجهة المستخدم في حالات مختلفة النقر المزدوج على قيمة الحالة لتعديلها مباشرةً
البحث عن المكون البحث السريع عن المكون Ctrl+F أدخل اسم المكون
الانتقال إلى شفرة المصدر عرض تنفيذ المكون النقر على أيقونة <>
TEXT 📖 للعرض فقط
// DevTools Components Panel Examples
<OrderPage>
  <ErrorBoundary>
    <OrderHeader
      orderNumber="ORD-2026-0001"     ← Props Real-time Display
      status="shipped"                 ← Can be edited directly during testing
    />
  </ErrorBoundary>
  <ErrorBoundary>
    <OrderItems>
      <OrderItem product={...} />      ← State Expand to view
      <OrderItem product={...} />
    </OrderItems>
  </ErrorBoundary>
</OrderPage>

▶ المثال 4: التعامل مع أخطاء طلبات واجهة برمجة التطبيقات (API) — استرداد البيانات باستخدام آليات إعادة المحاولة

JSX
function useFetchWithRetry(url, maxRetries = 3) {
  const [data, setData] = useState(null)
  const [error, setError] = useState(null)
  const [loading, setLoading] = useState(true)
  const [retries, setRetries] = useState(0)

  const fetchData = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const res = await fetch(url)
      if (!res.ok) throw new Error(`HTTP ${res.status}`)
      const json = await res.json()
      setData(json)
    } catch (err) {
      if (retries < maxRetries) {
        setRetries(r => r + 1)
        setTimeout(fetchData, 1000 * (retries + 1))
      } else {
        setError(err.message)
      }
    } finally {
      setLoading(false)
    }
  }, [url, retries, maxRetries])

  useEffect(() => { fetchData() }, [url])

  return { data, error, loading, retries, refetch: () => { setRetries(0); fetchData() } }
}

function UserList() {
  const { data: users, error, loading, retries, refetch } = useFetchWithRetry('/api/users')

  if (loading) return <p>Loading... {retries > 0 && `(retry ${retries})`}</p>
  if (error) return (
    <div style={{ padding: 20, textAlign: 'center' }}>
      <p style={{ color: '#ff4d4f' }}>Error: {error}</p>
      <button onClick={refetch} style={{ padding: '8px 16px', cursor: 'pointer' }}>Retry</button>
    </div>
  )

  return (
    <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
  )
}
▶ جرّب الكود

▶ المثال 5: مراقبة الأخطاء على المستوى العام — التكامل مع Sentry

JSX
// lib/errorReporting.ts
const SENTRY_DSN = process.env.NEXT_PUBLIC_SENTRY_DSN

function initErrorReporting() {
  if (typeof window === 'undefined') return
  if (!SENTRY_DSN) return

  // Sentry.init({ dsn: SENTRY_DSN, ... })
  // Simplified Example:Simulation Using Global Event Listeners

  window.addEventListener('unhandledrejection', (event) => {
    console.error('Unhandled Promise:', event.reason)
    reportError({
      type: 'unhandledrejection',
      message: event.reason?.message || String(event.reason),
      stack: event.reason?.stack,
      timestamp: new Date().toISOString(),
    })
  })

  window.addEventListener('error', (event) => {
    console.error('Global Error:', event.error)
    reportError({
      type: 'window.error',
      message: event.message,
      filename: event.filename,
      lineno: event.lineno,
      timestamp: new Date().toISOString(),
    })
  })
}

function reportError(payload) {
  fetch('/api/errors', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  }).catch(() => {})
}

// app/layout.tsx
function RootLayout({ children }) {
  useEffect(() => { initErrorReporting() }, [])
  return <html><body>{children}</body></html>
}
▶ جرّب الكود

❓ أسئلة شائعة

س هل يمكن لـ «Error Boundary» اكتشاف جميع الأخطاء؟
ج لا. لا تكتشف «Error Boundary» سوى الأخطاء التي تحدث أثناء مرحلة العرض، وفي أساليب دورة الحياة، وفي منشئات الكائنات. لا يمكن اكتشاف الأنواع الأربعة التالية من الأخطاء: الأخطاء في معالجات الأحداث (استخدم try/catch)، والأخطاء في الكود غير المتزامن (استخدم Promise.catch)، والأخطاء أثناء العرض من جانب الخادم، والأخطاء داخل حدود الخطأ نفسها. عند تصميم معالجة الأخطاء، تحتاج إلى الجمع بين try/catch وحدود الخطأ في نهج متعدد الطبقات.
س ما الذي يمثله اللونان «الرمادي» و«الأزرق» في الرسم البياني «فلام غراف» (Flame Graph) في أداة Profiler؟
ج يشير اللون الرمادي إلى أن المكون لم يتم إعادة عرضه خلال هذا الالتزام (أداء جيد). يشير اللون الأزرق إلى أن المكون تم إعادة عرضه، لكن الوقت المستغرق كان ضمن النطاق الطبيعي. يشير اللون الأصفر أو الأحمر إلى أن عملية العرض استغرقت وقتًا طويلاً وتحتاج إلى تحسين. الهدف هو الحفاظ على معظم المكونات باللون الرمادي أو الأزرق الفاتح أثناء التفاعلات.
س هل يقوم React.memo بتحسين جميع المكونات تلقائيًا؟
ج لا. لا يقوم React.memo إلا بإجراء مقارنات سطحية. إذا كانت الخصائص (props) تحتوي على كائنات أو مصفوفات، فسيؤدي كل عرض إلى مراجع جديدة، مما يتسبب في فشل الميمو. في هذه الحالة، تحتاج إلى استخدام useMemo / useCallback للحفاظ على استقرار المراجع، أو تمرير حجة ثانية — وهي دالة مقارنة مخصصة React.memo(Comp, (prev, next) => deepEqual(prev, next)) — إلى React.memo.
س هل يؤثر المكون <Profiler> على الأداء في بيئة الإنتاج؟
ج وفقًا للوثائق الرسمية لـ React، يتسبب المكون <Profiler> في زيادة طفيفة في عبء الأداء في بيئة الإنتاج. يُنصح باستخدامه فقط في بيئات التطوير أو التحكم فيه عبر متغيرات البيئة: {process.env.NODE_ENV === 'development' && <Profiler>...}. عندما تكون مراقبة الأداء مطلوبة في بيئة الإنتاج، فكر في استخدام مكتبات مخصصة لمراقبة الأداء (مثل web-vitals) أو ميزات تتبع الأداء في Sentry.
س هل يمكن كتابة «حدود الخطأ» (Error Boundary) كمكون دالة؟
ج لا، ليس في الوقت الحالي. تعتمد «حدود الخطأ» على طريقتين من طرق دورة الحياة، وهما getDerivedStateFromError وcomponentDidCatch، واللتان لا تدعمهما سوى مكونات الفئات. وقد أشار فريق React إلى احتمال توفر نسخة Hook في المستقبل، ولكن في الوقت الحالي (React 18/19)، لا يمكن تنفيذها إلا باستخدام مكونات الفئة. يمكنك إنشاء مكون «حدود الخطأ» قائم على الفئة ثم تغليفه في مكون دالة للتعامل مع منطق استعادة الخطأ.

📖 ملخص


📝 تمارين

  1. قم بإنشاء مكون ErrorBoundary واستخدمه بشكل هرمي ضمن مكونات OrderPage: Wrap OrderHeader, OrderItems, and PaymentInfo in separate ErrorBoundary. قم بتحفيز خطأ في العرض يدويًّا (مثل تمرير خصائص غير صحيحة) للتحقق من أن المنطقة المتأثرة فقط هي التي تعرض واجهة المستخدم الاحتياطية، بينما يتم عرض بقية الواجهة بشكل طبيعي.
  2. استخدم المكون Profiler لقياس وقت عرض مكون يحتوي على 100 عنصر قائمة. بعد إجراء التحسين باستخدام React.memo، قم بقياس وقت العرض مرة أخرى وقارن الفرق في actualDuration بين القياسين للتحقق من فعالية عملية التحسين.
  3. افتح أداة تحليل الأداء (React DevTools Profiler) في متصفح Chrome، وسجل تفاعلًا مع الصفحة (مثل البحث أو التصفية أو الفرز)، وحدد المكون الذي يستغرق أطول وقت في العرض في مخطط اللهب (flame graph)، وحلل السبب، وقم بتحسينه باستخدام useMemo / useCallback.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%