الفرق بين المراجعتين لصفحة: «Node.js/perf hooks»

من موسوعة حسوب
انشاء صفحة الجزء الأول
 
ط استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}'
 
(5 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة)
سطر 2: سطر 2:
الاستقرار: 1- تجريبي.
الاستقرار: 1- تجريبي.


تقدم الواجهة البرمجية لتوقيت الأداء تطبيقًا لمواصفات W3C Performance Timeline. الغرض من  الواجهة البرمجية (API) هو دعم مجموعة من مقاييس الأداء عالية الدقة. والتي هي نفس واجهات الأداء المُطبّقة في متصفحات الويب الحديثة.<syntaxhighlight lang="javascript">
تقدم الواجهة البرمجية لتوقيت الأداء تطبيقًا لمواصفات [https://w3c.github.io/performance-timeline/ W3C Performance Timeline]. الغرض من  الواجهة البرمجية (API) هو دعم مجموعة من مقاييس الأداء عالية الدقة. والتي هي نفس واجهات الأداء المُطبّقة في متصفحات الويب الحديثة.<syntaxhighlight lang="javascript">
const { PerformanceObserver, performance } = require('perf_hooks');
const { PerformanceObserver, performance } = require('perf_hooks');


سطر 18: سطر 18:
</syntaxhighlight>
</syntaxhighlight>


== الصنف Performance ==
== الصنف: Performance ==
أُضيف في الإصدار: 8.5.0.
أُضيف في الإصدار: 8.5.0.


=== performance.clearMarks([name‎]‎)‎ ===
=== <code>performance.clearMarks([name‎]‎)‎</code> ===
أُضيفت في الإصدار: 8.5.0
أُضيفت في الإصدار: 8.5.0
* name <string>‎
* <code>name</code> [[JavaScript/String|<string>]]
إذا لم يكن المعامل name مُزودًا، فستُمسَح كل كائنات PerformanceMark من الجدول الزمني للأداء. أما إذا كانت قيمة name مزوّدة، فستُمسح العلامة المسماة فقط.
إذا لم يكن المعامل <code>name</code> مُزودًا، فستُمسَح كل كائنات <code>PerformanceMark</code> من الجدول الزمني للأداء. أما إذا كانت قيمة <code>name</code> مزوّدة، فستُمسح العلامة المسماة فقط.


=== performance.mark([name]‎)‎ ===
=== <code>performance.mark([name]‎)‎</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* name <string>‎
* <code>name</code> [[JavaScript/String|<string>‎]]
تُنشِئ مُدخل  PerformanceMark جديد في الجدول الزمني للأداء .الصنف PerformanceMark هو صنف فرعي من PerformanceEntry وفيه تكون قيمة performanceEntry.entryType دائمًا 'mark' ( مُعلّمًا). وقيمة performanceEntry.duration  دائمًا 0. تُستخدم علامات الأداء لتعليم لحظات محددة مهمة في الجدول الزمني للأداء.
تُنشِئ مُدخل  <code>PerformanceMark</code> جديد في الجدول الزمني للأداء .الصنف <code>PerformanceMark</code> هو صنف فرعي من <code>PerformanceEntry</code> وفيه تكون قيمة <code>performanceEntry.entryType</code> دائمًا <code>'mark'</code> ( مُعلّمًا). وقيمة <code>performanceEntry.duration</code>  دائمًا <code>0</code>. تُستخدم علامات الأداء لتعليم لحظات محددة مهمة في الجدول الزمني للأداء.


=== (performance.measure(name, startMark, endMark ===
=== <code>(performance.measure(name, startMark, endMark</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* name <string>‎
* <code>name</code> [[JavaScript/String|<string>]]
* startMark <string>‎
* <code>startMark</code> [[JavaScript/String|<string>]]
* <endMark <string
* <code>endMark</code> [[JavaScript/String|<string>]]‎
تُنشِئ مُدخل PerformanceMeasure جديد في الجدول الزمني للأداء. الصنف  PerformanceMeasure هو صنف فرعي من الصنف PerformanceEntry فيه الخاصية performanceEntry.entryType ذات قيمة 'measure' (قياس) دائمًا، والخاصية performanceEntry.duration خاصته تقيس عدد الملي ثانية المنقضي منذ startMark و endMark.
تُنشِئ مُدخل <code>PerformanceMeasure</code> جديد في الجدول الزمني للأداء. الصنف  <code>PerformanceMeasure</code> هو صنف فرعي من الصنف <code>PerformanceEntry</code> فيه الخاصية <code>performanceEntry.entryType</code> ذات قيمة <code>'measure'</code> (قياس) دائمًا، والخاصية <code>performanceEntry.duration</code> خاصته تقيس عدد الملي ثانية المنقضي منذ <code>startMark</code> و <code>endMark</code>.


قد يُعرِّف الوسيط startMark أي PerformanceMark موجودة في الجدول الزمني للأداء، أو قد يعرّف أي من خاصيات البصمة الزمنية (timestamp) المقدمة من قبل الصنف PerformanceNodeTiming. إذا كانت قيمة startMark المُسمّاة غير موجودة، حينذاك تُهيأ قيمة المعامل startMark وتُضبَط إلى timeOrigin افتراضيًا.
قد يُعرِّف الوسيط <code>startMark</code> أي <code>PerformanceMark</code> موجودة في الجدول الزمني للأداء، أو قد يعرّف أي من خاصيات البصمة الزمنية (timestamp) المقدمة من قبل الصنف <code>PerformanceNodeTiming</code>. إذا كانت قيمة <code>startMark</code> المُسمّاة غير موجودة، حينذاك تُهيأ قيمة المعامل <code>startMark</code> وتُضبَط إلى [[timeOrigin]] افتراضيًا.


يجب أن يُعرِّف الوسيط endMark أي PerformanceMark موجودة في الجدول الزمني للأداء، أو أي من  خاصيات البصمة الزمنية (timestamp) المقدمة من خلال الصنف PerformanceNodeTiming. إذا كان العامل endMark  المسمّى غير موجود، فسوف يُرمى خطأ.
يجب أن يُعرِّف الوسيط <code>endMark</code> أي <code>PerformanceMark</code> ''موجودة'' في الجدول الزمني للأداء، أو أي من  خاصيات البصمة الزمنية (timestamp) المقدمة من خلال الصنف <code>PerformanceNodeTiming</code>. إذا كان العامل <code>endMark</code>  المسمّى غير موجود، فسوف يُرمى خطأ.


=== performance.nodeTiming ===
=== <code>performance.nodeTiming</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <PerformanceNodeTiming>
* <PerformanceNodeTiming>
* نسخة من الصنف PerformanceNodeTiming  والتي تقدم مقاييس أداء لمراحل تشغيل Node.js محددة.
* نسخة من الصنف <code>PerformanceNodeTiming</code>  والتي تقدم مقاييس أداء لمراحل تشغيل Node.js محددة.


=== performance.now(‎)‎ ===
=== <code>performance.now(‎)‎</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* القيمة المعادة :[[JavaScript/Number|<number>]]
تعيد البصمة الزمنية الحالية عالية الدقة بالميلي ثانية، حيث تمثل القيمة 0 بداية عملية <code>node</code> الحالية.


القيمة المعادة :<number>
=== <code>performance.timeOrigin</code> ===
 
تعيد البصمة الزمنية الحالية عالية الدقة بالميلي ثانية، حيث تمثل القيمة 0 بداية عملية node الحالية.
 
=== performance.timeOrigin ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <number>
* [[JavaScript/Number|<number>]]
تحدد الخاصية timeOrigin بصمة زمنية عالية الدقة بالميلي ثانية والتي بدأت فيها عملية node الحالية، مقاسة بتوقيت يونكس.
تحدد الخاصية [[Node.js/timeOrigin|timeOrigin]] بصمة زمنية عالية الدقة بالميلي ثانية والتي بدأت فيها عملية <code>node</code> الحالية، مقاسة بتوقيت يونكس.


=== performance.timerify(fn)‎ ===
=== <code>performance.timerify(fn)‎</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* fn ‎<‎Function‎>‎
* <code>fn</code> [[JavaScript/Function|<‎Function‎>‎]]
تُغلّف الدالة بدالة جديدة والتي تقيس زمن التشغيل للدالة المُغلّفة. يجب أن تكون قيمة PerformanceObserver مشترِكة ً(subscribed) بنوع الحدث 'function' من أجل إمكانية الوصول لتفاصيل الزمن.<syntaxhighlight lang="javascript">
تُغلّف الدالة بدالة جديدة والتي تقيس زمن التشغيل للدالة المُغلّفة. يجب أن تكون قيمة <code>PerformanceObserver</code> مشترِكة ً(subscribed) بنوع الحدث <code>'function'</code> من أجل إمكانية الوصول لتفاصيل الزمن.<syntaxhighlight lang="javascript">
const {
const {
   performance,
   performance,
سطر 84: سطر 82:
</syntaxhighlight>
</syntaxhighlight>


== الصنف:PerformanceEntry ==
== الصنف PerformanceEntry ==
أُضيف في الإصدار: 8.5.0.
أُضيف في الإصدار: 8.5.0.


=== performanceEntry.duration ===
=== <code>performanceEntry.duration</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <number>
* [[JavaScript/Number|<number>]]
العدد الكلي بالميلي ثانية المنقضي من أجل هذا المُدخل. لن تكون هذه القيمة ذات معنى من أجل جميع أنواع مدخلات الأداء.
العدد الكلي بالميلي ثانية المنقضي من أجل هذا المُدخل. لن تكون هذه القيمة ذات معنى من أجل جميع أنواع مدخلات الأداء.


=== performanceEntry.name ===
=== <code>performanceEntry.name</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <string>
* [[JavaScript/String|<string>]]
اسم مُدخل الأداء.
اسم مُدخل الأداء.


=== performanceEntry.startTime ===
=== <code>performanceEntry.startTime</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <number>
* [[JavaScript/Number|<number>]]
البصمة الزمنية عالية الدقة بالميلي ثانية التي تُشير إلى زمن البداية لمُدخل الأداء.
البصمة الزمنية عالية الدقة بالميلي ثانية التي تُشير إلى زمن البداية لمُدخل الأداء.


=== performanceEntry.entryType ===
=== <code>performanceEntry.entryType</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <string>
* [[JavaScript/String|<string>]]
نوع مُدخل الأداء، حاليًا قد يكون  إما 'node' أو 'mark' أو'measure' أو 'gc' أو'function' أو 'http2'.
نوع مُدخل الأداء، حاليًا قد يكون  إما <code>'node'</code> أو <code>'mark'</code> أو<code>'measure'</code> أو <code>'gc'</code> أو<code>'function'</code> أو <code>'http2'</code>.


=== performanceEntry.kind ===
=== <code>performanceEntry.kind</code> ===
أُضيفت في الإصدار: 8.5.0.
أُضيفت في الإصدار: 8.5.0.
* <number>
* [[JavaScript/Number|<number>]]
عندما تكون قيمة الخاصية performanceEntry.entryType مساويةً إلى 'gc' ، تُعرِّف الخاصية  performance.kind نوع عملية جمع القمامة (تنظيف الذاكرة) التي حصلت.
عندما تكون قيمة الخاصية <code>performanceEntry.entryType</code> مساويةً إلى <code>'gc'</code> ، تُعرِّف الخاصية  <code>performance.kind</code> نوع عملية جمع القمامة (تنظيف الذاكرة) التي حصلت.


يمكن أن تكون القيمة واحدةً مما يلي:
يمكن أن تكون القيمة واحدةً مما يلي:
* perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR
* <code>perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR</code>
* perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR
* <code>perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR</code>
* perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL
* <code>perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL</code>
* perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB
* <code>perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB</code>


== الصنف: PerformanceNodeTiming extends PerformanceEntry ==
== الصنف PerformanceNodeTiming extends PerformanceEntry ==
أُضيف في الإصدار: 8.5.0.
أُضيف في الإصدار: 8.5.0.


يقدم تفاصيل التوقيت لمنصة Node.js نفسها.
يقدم تفاصيل التوقيت لمنصة Node.js نفسها.
=== <code>performanceNodeTiming.bootstrapComplete</code> ===
أُضيفت في الإصدار: 8.5.0.
* [[JavaScript/Number|<number>]]
البصمة الزمنية عالية الدقة بالميلي ثانية والتي أكملت فيها عملية Node.js تمهيد التشغيل. إذا لم ينته تمهيد التشغيل بعد، فستأخد الخاصية القيمة ‎-1.
=== <code>performanceNodeTiming.loopExit</code> ===
أُضيفت في الإصدار: 8.5.0.
* [[JavaScript/Number|<number>]]
بصمة زمنية عالية الدقة بالميلي ثانية والتي انتهت عندها حلقة أحداث Node.js. إذا لم تنتهِ حلقة الأحداث بعد، فستأخذ الخاصية القيمة ‎-1. يمكن فقط أن تأخذ قيمةً لا تساوي ‎-1 في معالج الحدث [[Node.js/process#.D8.A7.D9.84.D8.AD.D8.AF.D8.AB .27exit.27|'exit']].
=== <code>performanceNodeTiming.loopStart</code> ===
أُضيفت في الإصدار: 8.5.0.
* [[JavaScript/Number|<number>]]
البصمة الزمنية عالية الدقة بالميلي ثانية والتي بدأت عندها حلقة أحداث Node.js. إذا لم تبدأ حلقة الأحداث بعد، (على سبيل المثال، في اللحظة الأولى للسكربت الرئيسي)، فستأخذ الخاصية القيمة ‎-1.
=== <code>performanceNodeTiming.nodeStart</code> ===
أُضيفت في الإصدار: 8.5.0.
* [[JavaScript/Number|<number>]]
البصمة الزمنية عالية الدقة بالميلي ثانية والذي هُيئت فيها عملية Node.js.
=== <code>performanceNodeTiming.v8Start</code> ===
أُضيفت في الإصدار: 8.5.0.
* [[JavaScript/Number|<number>]]
البصمة الزمنية عالية الدقة بالميلي ثانية والتي هُيئت فيها منصة V8.
== <code>الصنف: PerformanceObserver</code> ==
=== <code>new PerformanceObserver(callback)‎</code> ===
أُضيف في الإصدار:8.5.0
* <code>callback</code> [[JavaScript/Function|<Function>‎]]
** <code>list</code> [[Node.js/perf hooks#.D8.A7.D9.84.D8.B5.D9.86.D9.81 PerformanceObserverEntryList|<PerformanceObserverEntryList>‎]]
** <code>observer</code> [[Node.js/perf hooks#.D8.A7.D9.84.D8.B5.D9.86.D9.81: PerformanceObserver|<PerformanceObserver>]]‎
تقدم كائنات <code>PerformanceObserver</code> إشعارات عندما تُضاف نسخة <code>PerformanceEntry</code> جديدة إلى الجدول الزمني للأداء.<syntaxhighlight lang="javascript">
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries());
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark'], buffered: true });
performance.mark('test');
</syntaxhighlight>بسبب أن نُسخ <code>PerformanceObserver</code> تقدم عبء أداء إضافي خاص بها، لا ينبغي أن تُترك النسخ مشتركةً في الإشعارات لأجل غير مُسمى. ينبغي على المستخدم قطع اتصال المراقِبات(observers) حالما لا توجد حاجة إليها.
تستدعى دالة رد النداء callback عندما تُبلَّغ <code>PerformanceObserver</code> عن نُسخ <code>PerformanceEntry</code> جديدة. تستقبل دالة رد النداء (callback) نسخة <code>PerformanceObserverEntryList</code> ومرجعًا إلى <code>PerformanceObserver</code>.
=== <code>performanceObserver.disconnect(‎)‎</code> ===
أُضيفت في الإصدار:8.5.0.
تفصل اتصال نسخة <code>PerformanceObserver</code> عن كل الإشعارات.
=== <code>performanceObserver.observe(‎options)‎</code> ===
أُضيفت في الإصدار: 8.5.0.
* <code>options</code> [[JavaScript/Object|<Object>]]‎
** <code>entryTypes</code> [[JavaScript/String|<string[‎]‎>]]‎  مصفوفة من السلاسل النصية مُعرِّفة لأنواع نُسخ <code>PerformanceEntry</code> التي يهتم بها المراقب. إذا لم تكن قيمة هذا المعامل موجودةً فسوف يُرمى خطأ.
** <code>buffered</code> [[JavaScript/Boolean|<boolean>‎]] إذا كانت true، سوف تستدعى دالة رد النداء callback للإشعارات باستخدام <code>setImmediate(‎)</code>‎ وستُخزَّن محليًا العديد من إشعارات  نُسخ <code>PerformanceEntry</code>. إذا كانت <code>false</code>، فسوف تكون الإشعارات آنية ومتزامنة. '''القيمة الافتراضية''': <code>false</code>.
تُؤدي هذه الدالة إلى جعل نسخة الصنف <code>PerformanceObserver</code> مشتركةً بإشعارات النسخ الجديدة من <code>PerformanceEntry</code> المُعرَّفة بواسطة الخاصية <code>options.entryTypes</code>.
عندما تكون قيمة الخاصية <code>options.buffered</code> هي false، فستُستدعى دالة رد النداء <code>callback</code> مرةً لكل نسخة من نسخ <code>PerformanceEntry</code>:<syntaxhighlight lang="javascript">
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const obs = new PerformanceObserver((list, observer) => {
//تُستدعى ثلاث مرات بشكل متزامن. تحوي اللائحة عنصر واحد
});
obs.observe({ entryTypes: ['mark'] });
for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`);
</syntaxhighlight><syntaxhighlight lang="javascript">
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const obs = new PerformanceObserver((list, observer) => {
 
// تُستدعى مرة واحدة.  تحوي اللائحة ثلاثة عناصر
});
obs.observe({ entryTypes: ['mark'], buffered: true });
for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`);
</syntaxhighlight>
== الصنف PerformanceObserverEntryList ==
يُستخدم الصنف <code>PerformanceObserverEntryList</code> لتوفير وصول إلى نسخ <code>PerformanceEntry</code> المُمررة إلى <code>PerformanceObserver</code>.
=== <code>performanceObserverEntryList.getEntries(‎)‎</code> ===
أُضيفت في الإصدار:8.5.0
* القيمة المعادة: [[Node.js/perf hooks#.D8.A7.D9.84.D8.B5.D9.86.D9.81 PerformanceEntry|<‎PerformanceEntry[‎‎]‎>]]
تعيد لائحة من كائنات <code>PerformanceEntry</code> مرتبة زمنيًا بالنسبة إلى <code>performanceEntry.startTime</code>.
=== <code>performanceObserverEntryList.getEntriesByName(‎name[‎, type]‎)‎</code> ===
أُضيف في الإصدار: 8.5.0.
* <code>name</code> [[JavaScript/String|<string>‎]]
* <code>type</code> [[JavaScript/String|<string>]]‎
* القيمة المعادة: [[Node.js/perf hooks#.D8.A7.D9.84.D8.B5.D9.86.D9.81 PerformanceEntry|<‎PerformanceEntry[‎‎]‎>]]
تعيد لائحة من كائنات  <code>PerformanceEntry</code>  مرتبة زمنيًا حسب  <code>performanceEntry.startTime</code>  والتي  فيها قيمة الخاصية <code>performanceEntry.name</code> مساوية إلى <code>name</code>، واختياريًا، تكون قيمة<code>performanceEntry.entryType</code> الخاصة بها مساويةً ل<code>type</code>.
=== <code>performanceObserverEntryList.getEntriesByType(‎type)‎‎</code> ===
* <code>type</code> [[JavaScript/String|<string>‎]]
* القيمة المعادة: [[Node.js/perf hooks#.D8.A7.D9.84.D8.B5.D9.86.D9.81 PerformanceEntry|<‎PerformanceEntry[‎‎]‎>]]
تعيد لائحة من كائنات <code>PerformanceEntry</code> بترتيب زمني بالنسبة إلى <code>performanceEntry.startTime</code> والتي تكون فيها الخاصية <code>performanceEntry.entryType</code> مساويةً إلى <code>type</code>.
== أمثلة ==
=== قياس المُدّة للعمليات غير المتزامنة ===
تستخدم الأمثلة التالية الخطافات غير المتزامنة  وواجهات الأداء (الواجهات البرمجية للأداء Performance APIs) لقياس المدة الفعلية لعملية منتهية المهلة (متضمنة كمية الوقت [المُتطلبة] لتنفيذ دالة رد النداء callback).<syntaxhighlight lang="javascript">
'use strict';
const async_hooks = require('async_hooks');
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const set = new Set();
const hook = async_hooks.createHook({
  init(id, type) {
    if (type === 'Timeout') {
      performance.mark(`Timeout-${id}-Init`);
      set.add(id);
    }
  },
  destroy(id) {
    if (set.has(id)) {
      set.delete(id);
      performance.mark(`Timeout-${id}-Destroy`);
      performance.measure(`Timeout-${id}`,
                          `Timeout-${id}-Init`,
                          `Timeout-${id}-Destroy`);
    }
  }
});
hook.enable();
const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries()[0]);
  performance.clearMarks();
  observer.disconnect();
});
obs.observe({ entryTypes: ['measure'], buffered: true });
setTimeout(() => {}, 1000);
</syntaxhighlight>
=== قياس المدّة المأخوذة لتحميل الاعتماديات ===
يقيس المثال التالي مدة العملية <code>require(‎)‎</code> لتحميل الاعتماديات (dependencies):<syntaxhighlight lang="javascript">
'use strict';
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const mod = require('module');
//  محاكاة تصحيح/تشغيل  الدالة المطلوبة
mod.Module.prototype.require =
  performance.timerify(mod.Module.prototype.require);
require = performance.timerify(require);
//  تفعيل المراقب
const obs = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  entries.forEach((entry) => {
    console.log(`require('${entry[0]}')`, entry.duration);
  });
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'], buffered: true });
require('some-module');
</syntaxhighlight>
== مصادر ==
* [https://nodejs.org/dist/latest-v10.x/docs/api/perf_hooks.html صفحة Performance Timing API في توثيق Node.js الرسمي.]
[[تصنيف:Node.js|{{SUBPAGENAME}}]]

المراجعة الحالية بتاريخ 11:14، 23 أكتوبر 2018

الاستقرار: 1- تجريبي.

تقدم الواجهة البرمجية لتوقيت الأداء تطبيقًا لمواصفات W3C Performance Timeline. الغرض من  الواجهة البرمجية (API) هو دعم مجموعة من مقاييس الأداء عالية الدقة. والتي هي نفس واجهات الأداء المُطبّقة في متصفحات الويب الحديثة.

const { PerformanceObserver, performance } = require('perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ entryTypes: ['measure'] });

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
});

الصنف: Performance

أُضيف في الإصدار: 8.5.0.

performance.clearMarks([name‎]‎)‎

أُضيفت في الإصدار: 8.5.0

إذا لم يكن المعامل name مُزودًا، فستُمسَح كل كائنات PerformanceMark من الجدول الزمني للأداء. أما إذا كانت قيمة name مزوّدة، فستُمسح العلامة المسماة فقط.

performance.mark([name]‎)‎

أُضيفت في الإصدار: 8.5.0.

تُنشِئ مُدخل  PerformanceMark جديد في الجدول الزمني للأداء .الصنف PerformanceMark هو صنف فرعي من PerformanceEntry وفيه تكون قيمة performanceEntry.entryType دائمًا 'mark' ( مُعلّمًا). وقيمة performanceEntry.duration  دائمًا 0. تُستخدم علامات الأداء لتعليم لحظات محددة مهمة في الجدول الزمني للأداء.

(performance.measure(name, startMark, endMark

أُضيفت في الإصدار: 8.5.0.

تُنشِئ مُدخل PerformanceMeasure جديد في الجدول الزمني للأداء. الصنف  PerformanceMeasure هو صنف فرعي من الصنف PerformanceEntry فيه الخاصية performanceEntry.entryType ذات قيمة 'measure' (قياس) دائمًا، والخاصية performanceEntry.duration خاصته تقيس عدد الملي ثانية المنقضي منذ startMark و endMark.

قد يُعرِّف الوسيط startMark أي PerformanceMark موجودة في الجدول الزمني للأداء، أو قد يعرّف أي من خاصيات البصمة الزمنية (timestamp) المقدمة من قبل الصنف PerformanceNodeTiming. إذا كانت قيمة startMark المُسمّاة غير موجودة، حينذاك تُهيأ قيمة المعامل startMark وتُضبَط إلى timeOrigin افتراضيًا.

يجب أن يُعرِّف الوسيط endMark أي PerformanceMark موجودة في الجدول الزمني للأداء، أو أي من  خاصيات البصمة الزمنية (timestamp) المقدمة من خلال الصنف PerformanceNodeTiming. إذا كان العامل endMark  المسمّى غير موجود، فسوف يُرمى خطأ.

performance.nodeTiming

أُضيفت في الإصدار: 8.5.0.

  • <PerformanceNodeTiming>
  • نسخة من الصنف PerformanceNodeTiming  والتي تقدم مقاييس أداء لمراحل تشغيل Node.js محددة.

performance.now(‎)‎

أُضيفت في الإصدار: 8.5.0.

تعيد البصمة الزمنية الحالية عالية الدقة بالميلي ثانية، حيث تمثل القيمة 0 بداية عملية node الحالية.

performance.timeOrigin

أُضيفت في الإصدار: 8.5.0.

تحدد الخاصية timeOrigin بصمة زمنية عالية الدقة بالميلي ثانية والتي بدأت فيها عملية node الحالية، مقاسة بتوقيت يونكس.

performance.timerify(fn)‎

أُضيفت في الإصدار: 8.5.0.

تُغلّف الدالة بدالة جديدة والتي تقيس زمن التشغيل للدالة المُغلّفة. يجب أن تكون قيمة PerformanceObserver مشترِكة ً(subscribed) بنوع الحدث 'function' من أجل إمكانية الوصول لتفاصيل الزمن.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

function someFunction() {
  console.log('hello world');
}

const wrapped = performance.timerify(someFunction);

const obs = new PerformanceObserver((list) => {
  console.log(list.getEntries()[0].duration);
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'] });

// سوف يُنشأ مُدخل الجدول الزمني للأداء
wrapped();

الصنف PerformanceEntry

أُضيف في الإصدار: 8.5.0.

performanceEntry.duration

أُضيفت في الإصدار: 8.5.0.

العدد الكلي بالميلي ثانية المنقضي من أجل هذا المُدخل. لن تكون هذه القيمة ذات معنى من أجل جميع أنواع مدخلات الأداء.

performanceEntry.name

أُضيفت في الإصدار: 8.5.0.

اسم مُدخل الأداء.

performanceEntry.startTime

أُضيفت في الإصدار: 8.5.0.

البصمة الزمنية عالية الدقة بالميلي ثانية التي تُشير إلى زمن البداية لمُدخل الأداء.

performanceEntry.entryType

أُضيفت في الإصدار: 8.5.0.

نوع مُدخل الأداء، حاليًا قد يكون  إما 'node' أو 'mark' أو'measure' أو 'gc' أو'function' أو 'http2'.

performanceEntry.kind

أُضيفت في الإصدار: 8.5.0.

عندما تكون قيمة الخاصية performanceEntry.entryType مساويةً إلى 'gc' ، تُعرِّف الخاصية  performance.kind نوع عملية جمع القمامة (تنظيف الذاكرة) التي حصلت.

يمكن أن تكون القيمة واحدةً مما يلي:

  • perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR
  • perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR
  • perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL
  • perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB

الصنف PerformanceNodeTiming extends PerformanceEntry

أُضيف في الإصدار: 8.5.0.

يقدم تفاصيل التوقيت لمنصة Node.js نفسها.

performanceNodeTiming.bootstrapComplete

أُضيفت في الإصدار: 8.5.0.

البصمة الزمنية عالية الدقة بالميلي ثانية والتي أكملت فيها عملية Node.js تمهيد التشغيل. إذا لم ينته تمهيد التشغيل بعد، فستأخد الخاصية القيمة ‎-1.

performanceNodeTiming.loopExit

أُضيفت في الإصدار: 8.5.0.

بصمة زمنية عالية الدقة بالميلي ثانية والتي انتهت عندها حلقة أحداث Node.js. إذا لم تنتهِ حلقة الأحداث بعد، فستأخذ الخاصية القيمة ‎-1. يمكن فقط أن تأخذ قيمةً لا تساوي ‎-1 في معالج الحدث 'exit'.

performanceNodeTiming.loopStart

أُضيفت في الإصدار: 8.5.0.

البصمة الزمنية عالية الدقة بالميلي ثانية والتي بدأت عندها حلقة أحداث Node.js. إذا لم تبدأ حلقة الأحداث بعد، (على سبيل المثال، في اللحظة الأولى للسكربت الرئيسي)، فستأخذ الخاصية القيمة ‎-1.

performanceNodeTiming.nodeStart

أُضيفت في الإصدار: 8.5.0.

البصمة الزمنية عالية الدقة بالميلي ثانية والذي هُيئت فيها عملية Node.js.

performanceNodeTiming.v8Start

أُضيفت في الإصدار: 8.5.0.

البصمة الزمنية عالية الدقة بالميلي ثانية والتي هُيئت فيها منصة V8.

الصنف: PerformanceObserver

new PerformanceObserver(callback)‎

أُضيف في الإصدار:8.5.0

تقدم كائنات PerformanceObserver إشعارات عندما تُضاف نسخة PerformanceEntry جديدة إلى الجدول الزمني للأداء.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries());
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark'], buffered: true });

performance.mark('test');

بسبب أن نُسخ PerformanceObserver تقدم عبء أداء إضافي خاص بها، لا ينبغي أن تُترك النسخ مشتركةً في الإشعارات لأجل غير مُسمى. ينبغي على المستخدم قطع اتصال المراقِبات(observers) حالما لا توجد حاجة إليها.

تستدعى دالة رد النداء callback عندما تُبلَّغ PerformanceObserver عن نُسخ PerformanceEntry جديدة. تستقبل دالة رد النداء (callback) نسخة PerformanceObserverEntryList ومرجعًا إلى PerformanceObserver.

performanceObserver.disconnect(‎)‎

أُضيفت في الإصدار:8.5.0.

تفصل اتصال نسخة PerformanceObserver عن كل الإشعارات.

performanceObserver.observe(‎options)‎

أُضيفت في الإصدار: 8.5.0.

  • options <Object>
    • entryTypes <string[‎]‎>‎  مصفوفة من السلاسل النصية مُعرِّفة لأنواع نُسخ PerformanceEntry التي يهتم بها المراقب. إذا لم تكن قيمة هذا المعامل موجودةً فسوف يُرمى خطأ.
    • buffered <boolean>‎ إذا كانت true، سوف تستدعى دالة رد النداء callback للإشعارات باستخدام setImmediate(‎)‎ وستُخزَّن محليًا العديد من إشعارات  نُسخ PerformanceEntry. إذا كانت false، فسوف تكون الإشعارات آنية ومتزامنة. القيمة الافتراضية: false.

تُؤدي هذه الدالة إلى جعل نسخة الصنف PerformanceObserver مشتركةً بإشعارات النسخ الجديدة من PerformanceEntry المُعرَّفة بواسطة الخاصية options.entryTypes.

عندما تكون قيمة الخاصية options.buffered هي false، فستُستدعى دالة رد النداء callback مرةً لكل نسخة من نسخ PerformanceEntry:

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
 
//تُستدعى ثلاث مرات بشكل متزامن. تحوي اللائحة عنصر واحد 
});
obs.observe({ entryTypes: ['mark'] });

for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`);
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  
// تُستدعى مرة واحدة.  تحوي اللائحة ثلاثة عناصر 
});
obs.observe({ entryTypes: ['mark'], buffered: true });

for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`);

الصنف PerformanceObserverEntryList

يُستخدم الصنف PerformanceObserverEntryList لتوفير وصول إلى نسخ PerformanceEntry المُمررة إلى PerformanceObserver.

performanceObserverEntryList.getEntries(‎)‎

أُضيفت في الإصدار:8.5.0

تعيد لائحة من كائنات PerformanceEntry مرتبة زمنيًا بالنسبة إلى performanceEntry.startTime.

performanceObserverEntryList.getEntriesByName(‎name[‎, type]‎)‎

أُضيف في الإصدار: 8.5.0.

تعيد لائحة من كائنات  PerformanceEntry  مرتبة زمنيًا حسب  performanceEntry.startTime  والتي  فيها قيمة الخاصية performanceEntry.name مساوية إلى name، واختياريًا، تكون قيمةperformanceEntry.entryType الخاصة بها مساويةً لtype.

performanceObserverEntryList.getEntriesByType(‎type)‎‎

تعيد لائحة من كائنات PerformanceEntry بترتيب زمني بالنسبة إلى performanceEntry.startTime والتي تكون فيها الخاصية performanceEntry.entryType مساويةً إلى type.

أمثلة

قياس المُدّة للعمليات غير المتزامنة

تستخدم الأمثلة التالية الخطافات غير المتزامنة  وواجهات الأداء (الواجهات البرمجية للأداء Performance APIs) لقياس المدة الفعلية لعملية منتهية المهلة (متضمنة كمية الوقت [المُتطلبة] لتنفيذ دالة رد النداء callback).

'use strict';
const async_hooks = require('async_hooks');
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const set = new Set();
const hook = async_hooks.createHook({
  init(id, type) {
    if (type === 'Timeout') {
      performance.mark(`Timeout-${id}-Init`);
      set.add(id);
    }
  },
  destroy(id) {
    if (set.has(id)) {
      set.delete(id);
      performance.mark(`Timeout-${id}-Destroy`);
      performance.measure(`Timeout-${id}`,
                          `Timeout-${id}-Init`,
                          `Timeout-${id}-Destroy`);
    }
  }
});
hook.enable();

const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries()[0]);
  performance.clearMarks();
  observer.disconnect();
});
obs.observe({ entryTypes: ['measure'], buffered: true });

setTimeout(() => {}, 1000);

قياس المدّة المأخوذة لتحميل الاعتماديات

يقيس المثال التالي مدة العملية require(‎)‎ لتحميل الاعتماديات (dependencies):

'use strict';
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const mod = require('module');

//  محاكاة تصحيح/تشغيل  الدالة المطلوبة
mod.Module.prototype.require =
  performance.timerify(mod.Module.prototype.require);
require = performance.timerify(require);

//  تفعيل المراقب
const obs = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  entries.forEach((entry) => {
    console.log(`require('${entry[0]}')`, entry.duration);
  });
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'], buffered: true });

require('some-module');

مصادر