واجهة برمجة مراقب الأداء (Profiler API) في React

من موسوعة حسوب

يُحدد الفاحص Profiler عدد المرات التي يُصيَّر فيها تطبيق ريآكت وما عبء تلك العملية على أداء التطبيق، إذ يهدف ذلك إلى تحديد أجزاء التطبيق الأبطأ والتي قد تحتاج إلى استخدام تقنيات مخصصة لتحسين أدائها مثل تقنية الاستظهار (memoization).

ملاحظة: تُضيف عملية فحص الأداء (Profiling) تكاليف حاسوبية إضافية (أي استهلاك زائد للمعالج والذاكرة) لذا فهي مُعطَّلة افتراضيًا في الإصدار النهائي للتطبيق، لكن إذا أردت تضمينها في النسخة النهائية لتطبيقك فإن React يُتيح إطلاق نُسخة نهائية من التطبيق تضم عملية التعريف. راجع دليل عملية فحص الأداء في React الأجنبي لمزيد من التفاصيل حول كيفية استخدام هذا الإصدار.

كيفية الاستخدام

يمكنك إضافة عملية فحص أداء (مكون Profiler) في أيّ مكان ضمن هيكل React الشجري (tree) لقياس تكلفة تصيير ذلك القسم من الهيكل. يتطلب ذلك استخدام خاصيتين: الأولى هي مُعرّف العملية id والثانية هي دالّة رد نداء (callback function) باسم onRender تُستدعَى تلقائيًا عندما يُجرِي أي مُكوِّن في ذلك الهيكل تحديثًا ما.

على سبيل المثال هكذا سيبدو استعلام تعريف مُكوِّن التنقل Navigation وأجزائه الفرعية:

render(
  <App>
    <Profiler id="Navigation" onRender={callback}>
      <Navigation {...props} />
    </Profiler>
    <Main {...props} />
  </App>
);

يمكنك أيضًا استخدام مُكوِّنات Profiler متعددة لقياس أداء أجزاء مختلفة من التطبيق كما في المثال التالي:

render(
  <App>
    <Profiler id="Navigation" onRender={callback}>
      <Navigation {...props} />
    </Profiler>
    <Profiler id="Main" onRender={callback}>
      <Main {...props} />
    </Profiler>
  </App>
);

يمكنك أيضًا إنشاء مُكوِّنات Profiler مُتداخلة لقياس مُكوِّنات مختلفة ضمن نفس القسم من الهيكل الشجري كما هو موضح أدناه:

render(
  <App>
    <Profiler id="Panel" onRender={callback}>
      <Panel {...props}>
        <Profiler id="Content" onRender={callback}>
          <Content {...props} />
        </Profiler>
        <Profiler id="PreviewPane" onRender={callback}>
          <PreviewPane {...props} />
        </Profiler>
      </Panel>
    </Profiler>
  </App>
);

ملاحظة: مع أنّ المكون Profiler يُعَدّ مكوِّنًا خفيفًا على وحدة المعالجة إلا أنه يُنصح باستخدامه عند الضرورة فقط، إذ يضيف كل استخدام بعض العبء على المُعالج والذاكرة مما قد يؤثِّر على أداء التطبيق ككُل.

دالة المعالجة اللاحقة (onRender Callback)

يتطلب مُراقب الأداء Profiler تحديد دالّة رد نداء (Callback) تُفعّل عند بدء التصيير أو المُعالجة (onRender) كإحدى الخاصيات الممرة إليه. ستستدعي React هذه الدالة في كل مرة يُحدَّث فيها أحد المُكوِّنات المذكورة ضمن المكوِّن Profiler. عندها ستستقبل تلك الدالّة مُعامِلات تصِف ما تم مُعالجته وما الوقت الذي استغرقه ذلك.

function onRenderCallback(
  id, // نص يُمثل خاصية مُعرّف القسم من مراقب الأداء الذي أجرى التحديث

  phase, // إما "mount" إذا كانت العملية نُفِّذت للمرة الأولى أو "update" إذا طرأ تحديث ما تسبب بإعادة التصيير

  actualDuration, // الوقت المُستغرق لتصيير التحديث الحالي

  baseDuration, // الوقت المُقدر لتصيير القسم الفرعي من الهيكل بدون استخدام تقنيات تسريع

  startTime, // الوقت الذي بدأ فيه ريآكت بتصيير التحديث

  commitTime, // الوقت الذي أنهى فيه ريآكت إرسال التحديث

  interactions // مجموعة التفاعلات المتعلقة بالتحديث الحالي
) {
  // سِجل توقيت عمليات التصيير
}

لنُلقِ نظرةً عن تلك الخصائص سابقة الذكر:

  • id (المُعرِّف): هو نص يُمثل خاصية id للقسم المُعين من شجرة Profiler الذي أجرى التحديث. يمكن استخدام هذا المعرف لتحديد أيّ جزء من الهيكل قد حُدّث في حال كنت تستخدم مُعرِّفات متعددة.
  • phase (طُور العملية): تُمثّل هذه الخاصية بإحدى قيمتين (update أو mount) واللذان يُحددان إذا ما كانت العملية التي أُجريت على القسم المُحدد من الهيكل قد نُفِّذت للمرة الأولى أو أُعيد تصييرها نتيجة تحديث أحد الخصائص أو حالة المُكوِّنات أو الأحداث المُرتبطة بها.
  • actualDuration (مُدَّة التنفيذ الفعلية): تُمثّل هذه الخاصية برقم يُعبر عن الوقت المُستغرق لتصيير عملية Profiler ومُكوناتها الداخلية للتحديث الحالي. يُشير هذا الرقم إلى مدى فعالية تقنيات التسريع (مثل React.memo أو useMemo أو shouldComponentUpdate) المستخدَمة في هذا القسم من الهيكل الشجري. في العادة يُفترضانخفاض قيمة هذه الخاصية كثيرًا موازنةً بالقيمة الأولية، لأنّ العديد من المُكوِّنات الداخلية لا تحتاج إلى إعادة التصيير ما لم يطرأ أيّ تغيير على خصائصها.
  • baseDuration (مُدَّة التنفيذ الأساسية): تُمثّل هذه الخاصية أيضًا برقم يُعبر عن الوقت الذي استغرقته آخر عمليات التصيير لكلّ مُكوِّن ضمن الهيكل الشجري. تُستخدم هذه القيمة لتقدير تكلفة التصيير في أسوأ الحالات (مثلًا عند التصيير للمرة الأولى أو في حالة عدم استخدام أيّ تقنيات تسريع).
  • startTime (وقت البدء): وهو رقم يُمثل الطابع الزمني للحظة بدء ريآكت بتصيير التحديث الحالي لإحدى المُكوِّنات.
  • commitTime (وقت التنفيذ): وهو رقم يُمثل الطابع الزمني للحظة تنفيذ ريآكت للتحديث الحالي على أحد المُكوِّنات. تتشارك جميع عمليات التعريف هذه القيمة عند تنفيذ التحديث مما يُتيح تجميعها معًا إذا رغب المُطوِّر في ذلك.
  • interactions (التفاعلات): وهي مجموعة التفاعلات التي يجري تتبُّعها عند جدولة التحديث (مثلًا عند التصيير أو عند تفعيل دالّة setState).

ملاحظة: يمكن استخدام التفاعلات (Interactions) لتحديد سبب التحديث لكن يجدر بك معرفة أنّ واجهة التطوير الخاصة بها لا تزال تحت الاختبار. راجع توثيق تتبع التفاعلات لمزيد من المعلومات عن هذه النقطة.

المصادر