تحدد مواصفات PerformanCetimeline الطرق التي يمكن لمطوري الويب من خلالها قياس جوانب محددة من تطبيقات الويب الخاصة بهم لجعلها أسرع. يقدم طريقتين رئيسيتين للحصول على هذه القياسات: عبر طرق Getter من واجهة الأداء وعبر واجهة PerformanceObserver. هذا الأخير هو الطريقة الموصى بها لتقليل تأثير أداء الاستعلام عن هذه القياسات.
يمكن لكائن الأداء استضافة بيانات الأداء لمقياس معين. يحتوي الأداء على 4 سمات: name ، entryType ، startTime ، duration . لا تحدد هذه المواصفات كائنات الأداء الخرسانية. أمثلة المواصفات التي تحدد أنواعًا ملموسة جديدة من كائنات الأداء هي توقيت الطلاء وتوقيت المستخدم وتوقيت الموارد وتوقيت التنقل.
يتم زيادة واجهة الأداء بثلاث طرق جديدة يمكنها إرجاع قائمة كائنات الأداء:
getEntries() : إرجاع جميع الإدخالات المتاحة لكائن الأداء.getEntriesByType(type) : إرجاع جميع الإدخالات المتاحة لكائن الأداء الذي يتطابق entryType .getEntriesByName(name, type) : إرجاع جميع الإدخالات المتاحة لكائن الأداء الذي يتطابق name اسمه . إذا تم تحديد نوع المعلمة الاختيارية ، فإنه يعيد فقط إدخالات تطابق نوع entryType . يوضح المثال التالي كيف يمكن استخدام getEntriesByName() للحصول على معلومات الطلاء الأولى:
// Returns the FirstContentfulPaint entry, or null if it does not exist.
function getFirstContentfulPaint ( ) {
// We want the entry whose name is "first-contentful-paint" and whose entryType is "paint".
// The getter methods all return arrays of entries.
const list = performance . getEntriesByName ( "first-contentful-paint" , "paint" ) ;
// If we found the entry, then our list should actually be of length 1,
// so return the first entry in the list.
if ( list . length > 0 )
return list [ 0 ] ;
// Otherwise, the entry is not there, so return null.
else
return null ;
} يمكن أن يخطر كائن PerformanceObserver بكائنات الأداء الجديدة ، وفقًا لقيمة entryType الخاصة بهم. يجب أن يتلقى مُنشئ الكائن رد اتصال ، والذي سيتم تشغيله كلما قام وكيل المستخدم بإرسال إدخالات جديدة تتطابق مع قيمة entryType واحدة من تلك التي يلاحظها المراقب. لا يتم تشغيل رد الاتصال هذا مرة واحدة لكل أداء أو فور إنشاء أداء. بدلاً من ذلك ، تكون الإدخالات "قائمة انتظار" في PerformanceObserver ، ويمكن لوكيل المستخدم تنفيذ رد الاتصال لاحقًا. عند تنفيذ رد الاتصال ، يتم تمرير جميع الإدخالات في قائمة الانتظار على الوظيفة ، ويتم إعادة تعيين قائمة الانتظار لـ PerformanceObserver. لا يراقب الأداء في البداية أي شيء: يجب استدعاء طريقة observe() لتحديد نوع كائنات الأداء التي يجب ملاحظتها. يمكن استدعاء طريقة observe() إما باستخدام صفيف "إدخال" أو سلسلة "نوع واحد" ، على النحو المفصل أدناه. لا يمكن خلط تلك الأوضاع ، أو سيتم طرح استثناء.
تم نقل رد الاتصال على PerformanceObserver عند الإنشاء هو أداء PerformanceObserverCallback . إنه رد اتصال باطل مع المعلمات التالية:
entries : كائن PerformanceObserverEntryList يحتوي على قائمة الإدخالات التي يتم إرسالها في رد الاتصال.observer : كائن PerformanceObserver الذي يتلقى الإدخالات أعلاه.hasDroppedEntries : A boolean الذي يشير إلى ما إذا كان observer يراقب حاليًا عملية entryType تم إدخالها على الأقل بسبب امتلاء المخزن المؤقت المقابل. انظر قسم العلم المخزنة. supportedEntryTypes يقوم PerformanceObserver.supportedEntryTypes الثابت entryType . يمكن استخدامه للكشف عن الدعم لأنواع محددة.
observe(entryTypes) في هذه الحالة ، يمكن لـ PerformanceObserver تحديد قيم entryTypes المختلفة مع مكالمة واحدة observe() . ومع ذلك ، لا يُسمح بأي معلمات إضافية في هذه الحالة. ستعمل مكالمات observe() على تجاوز أنواع الكائنات التي يتم ملاحظتها. مثال على المكالمة: observer.observe({entryTypes: ['resource', 'navigation']}) .
observe(type) في هذه الحالة ، يمكن لـ PerformanceObserver تحديد نوع واحد لكل مكالمة على طريقة observe() . يسمح المعلمات الإضافية في هذه الحالة. ستتم ترسيب مكالمات observe() متعددة ، ما لم يتم إجراء مكالمة للمراقب نفس type في الماضي ، وفي هذه الحالة سيتم تجاوزها. مثال على المكالمة: observer.observe({type: "mark"}) .
buffered يتم تعريف معلمة واحدة يمكن استخدامها مع observe(type) في هذه المواصفات: العلامة buffered ، والتي يتم ضبطها افتراضيًا. عندما يتم تعيين هذه العلامة ، يقوم وكيل المستخدم بإرسال السجلات التي تم تخزينها قبل إنشاء PerformanceObserver ، وبالتالي يتم استلامها في رد الاتصال الأول بعد حدوث مكالمة observe() . يمكّن ذلك مطوري الويب من تسجيل PerformanceObservers عندما يكون من المناسب القيام بذلك دون فقدان الإدخالات التي تم إرسالها في وقت مبكر أثناء تحميل الصفحة. مثال على مكالمة باستخدام هذه العلامة: observer.observe({type: "measure", buffered: true}) .
كل entryType له خصائص خاصة حول التخزين المؤقت ، الموصوفة في السجل. على وجه الخصوص ، لاحظ أن هناك حدود لأرقام إدخالات كل نوع مخزنة. عندما يصبح المخزن المؤقت entryType ممتلئًا ، لا يتم تخزين أي إدخالات جديدة. قد يستفسر PerformanceObserver ما إذا كان قد تم إسقاط إدخال (غير مخزنة) نظرًا لكون المخزن المؤقت ممتلئًا عبر معلمة hasDroppedEntry الخاصة بعملية رد الاتصال.
disconnect()يمكن استدعاء هذه الطريقة عندما لا ينبغي إخطار PerformanceObserver بعد الآن.
takeRecords() تقوم هذه الطريقة بإرجاع قائمة من الإدخالات التي تم تصنيعها في قائمة الانتظار لـ PerformanceObserver ولكن لم يتم تشغيل رد الاتصال من أجله. كما يتم إفراغ قائمة انتظار الإدخالات من أجل الأداء. يمكن استخدامه جنبًا إلى جنب مع disconnect() للتأكد من معالجة جميع الإدخالات حتى نقطة محددة.
يقوم المثال التالي بتسجيل جميع توقيت المستخدم ، وإدخالات توقيت الموارد باستخدام PerformanceObserver الذي يصادف المراقبون ويقيمون.
// Helper to log a single entry.
function logEntry ( entry => {
const objDict = {
"entry type" : , entry . entryType ,
"name" : entry . name ,
"start time" : , entry . startTime ,
"duration" : entry . duration
} ;
console . log ( objDict ) ;
} ) ;
const userTimingObserver = new PerformanceObserver ( list => {
list . getEntries ( ) . forEach ( entry => {
logEntry ( entry ) ;
} ) ;
} ) ;
// Call to log all previous and future User Timing entries.
function logUserTiming ( ) {
if ( ! PerformanceObserver . supportedEntryTypes . includes ( "mark" ) ) {
console . log ( "Marks are not observable" ) ;
} else {
userTimingObserver . observe ( { type : "mark" , buffered : true } ) ;
}
if ( ! PerformanceObserver . supportedEntryTypes . includes ( "measure" ) ) {
console . log ( "Measures are not observable" ) ;
} else {
userTimingObserver . observe ( { type : "measure" , buffered : true } ) ;
}
}
// Call to stop logging entries.
function stopLoggingUserTiming ( ) {
userTimingObserver . disconnect ( ) ;
}
// Call to force logging queued entries immediately.
function flushLog ( ) {
userTimingObserver . takeRecords ( ) . forEach ( entry => {
logEntry ( entry ) ;
} ) ;
}