إنّ Long Animation Frames API (اختصارها Lo-Af الذي يُسمّى Lo-Af) تمثّل تعديلاً على Long Tasks API لتوفير فهم أفضل لتحديثات واجهة المستخدم (UI) البطيئة. ويمكن أن يكون ذلك مفيدًا في تحديد إطارات الصور المتحركة البطيئة التي من المحتمل أن تؤثر في مقياس مدى استجابة الصفحة لتفاعلات المستخدم (INP) الأساسي الذي يقيس مدى الاستجابة، أو لتحديد البيانات غير المرغوب فيها لواجهة المستخدم الأخرى التي تؤثر في السلاسة.
حالة واجهة برمجة التطبيقات
بعد فترة تجريبية للمصدر من Chrome 116 إلى Chrome 122، تم شحن LoAF API من Chrome 123.
الخلفية: واجهة Long Tasks API
واجهة برمجة تطبيقات Long Animation Frames API هي بديل لواجهة برمجة تطبيقات Long Task API التي كانت متاحة في Chrome منذ فترة (منذ Chrome 58). وكما يوحي اسمها، تتيح لك Long Task API مراقبة المهام الطويلة، وهي المهام التي تشغل سلسلة التعليمات الرئيسية لمدة 50 ملّي ثانية أو أكثر. يمكن تتبُّع المهام الطويلة باستخدام واجهة PerformanceLongTaskTiming
من خلال PeformanceObserver
:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'longtask', buffered: true });
من المرجح أن تتسبب المهام الطويلة في حدوث مشكلات في الاستجابة. وإذا حاول أحد المستخدمين التفاعل مع صفحة، مثلاً من خلال النقر على زر أو فتح قائمة، ولكن سلسلة المحادثات الرئيسية تتعامل حاليًا مع مهمة طويلة، سيتم عندئذٍ تأخير تفاعل المستخدم في انتظار اكتمال تلك المهمة.
لتحسين سرعة الاستجابة، يُنصح غالبًا بتقسيم المهام الطويلة. إذا تم تقسيم كل مهمة طويلة بدلاً من ذلك إلى سلسلة من المهام المتعددة والأصغر، فقد يسمح ذلك بتنفيذ مهام أكثر أهمية بينها لتجنب التأخيرات الكبيرة في الاستجابة للتفاعلات.
لذلك عند محاولة تحسين سرعة الاستجابة، غالبًا ما يكون أول جهد هو إجراء تتبُّع الأداء والنظر في المهام الطويلة. ويمكن أن يكون ذلك من خلال أداة تدقيق معملية مثل Lighthouse (التي تحتوي على عملية تدقيق تجنّب المهام الطويلة في سلسلة التعليمات الرئيسية)، أو من خلال الاطّلاع على المهام الطويلة في "أدوات مطوري البرامج في Chrome".
غالبًا ما يكون الاختبار المستند إلى المختبر هو نقطة انطلاق سيئة لتحديد مشاكل الاستجابة، لأنّ هذه الأدوات قد لا تشمل التفاعلات، فهي تشكّل مجموعة فرعية صغيرة من التفاعلات المحتمَلة. من الناحية المثالية، ستقيس أسباب التفاعلات البطيئة في المجال.
عيوب واجهة برمجة التطبيقات Long Tasks API
يعد قياس المهام الطويلة في الميدان باستخدام "راقي الأداء" مفيدًا إلى حد ما. في الواقع، لا يوفر ذلك الكثير من المعلومات بخلاف حقيقة وقوع مهمة طويلة والمدة التي استغرقتها.
وغالبًا ما تستخدم أدوات "مراقبة المستخدمين" (RUM) هذه القيمة لمؤشر عدد المهام الطويلة أو مدتها أو لتحديد الصفحات التي تتم فيها، ولكن بدون التفاصيل الأساسية لسبب تنفيذ المهمة الطويلة، يمكن استخدام هذه الطريقة بشكل محدود فقط. لا تحتوي واجهة برمجة التطبيقات Long Tasks API إلا على نموذج تحديد مصدر أساسي، والذي يطلعك في أحسن الأحوال على الحاوية التي حدثت فيها المهمة الطويلة (مستند المستوى الأعلى أو <iframe>
)، ولكن ليس النص البرمجي أو الوظيفة التي استدعت هذه المهمة، كما هو موضح في إدخال نموذجي:
{
"name": "unknown",
"entryType": "longtask",
"startTime": 31.799999997019768,
"duration": 136,
"attribution": [
{
"name": "unknown",
"entryType": "taskattribution",
"startTime": 0,
"duration": 0,
"containerType": "window",
"containerSrc": "",
"containerId": "",
"containerName": ""
}
]
}
تُعد واجهة Long Tasks API أيضًا عرضًا غير مكتمل، لأنها قد تستبعد أيضًا بعض المهام المهمة. تحدث بعض التحديثات - مثل العرض - في مهام منفصلة يجب تضمينها بشكل مثالي مع عملية التنفيذ السابقة التي تسببت في أن التحديث يقيس "إجمالي العمل" بدقة لذلك التفاعل. لمزيد من التفاصيل حول قيود الاعتماد على المهام، راجع "حيث تقصر المهام الطويلة" على في قسم الشرح
المشكلة الأخيرة هي أن قياس المهام الطويلة يحتوي فقط على تقارير حول المهام الفردية التي تستغرق وقتًا أطول من حد 50 مللي ثانية. يمكن أن يتكون إطار الصورة المتحركة من عدة مهام يقل حجمها عن 50 مللي ثانية كحد أقصى، ولكن تظل جميعها تمنع قدرة المتصفح على العرض.
واجهة برمجة تطبيقات Long Animation Frames
واجهة برمجة التطبيقات Long Animation Frames API (LoAF) هي واجهة برمجة تطبيقات جديدة تهدف إلى معالجة بعض أوجه القصور في واجهة Long Tasks API لتمكين المطوّرين من الحصول على إحصاءات أكثر قابلية للاستخدام من أجل المساعدة في معالجة مشاكل الاستجابة وتحسين INP.
تعني الاستجابة الجيدة أن الصفحة تستجيب بسرعة للتفاعلات التي تتم معها. ويشمل ذلك القدرة على عرض أي تحديثات يحتاجها المستخدم في الوقت المناسب، وتجنُّب حظر حدوث هذه التحديثات. بالنسبة إلى مقياس INP، يُنصَح بالاستجابة خلال 200 ملّي ثانية أو أقلّ، ولكن مع التعديلات الأخرى (مثل الصور المتحركة) حتى تلك التي قد تكون طويلة جدًا.
وتُعد واجهة برمجة تطبيقات Long Animation Frames أسلوبًا بديلاً لقياس أعمال الحظر. بدلاً من قياس المهام الفردية، تقيس واجهة برمجة التطبيقات Long Animation Frames API، كما يوحي اسمها، إطارات الصور المتحركة الطويلة. يحدث إطار الرسوم المتحركة الطويل عندما يتأخر تحديث العرض لأكثر من 50 مللي ثانية (وهو نفس الحد المسموح به لواجهة برمجة تطبيقات Long Tasks).
يمكن ملاحظة إطارات الصور المتحركة الطويلة بطريقة مشابهة للمهام الطويلة باستخدام PerformanceObserver
، مع مراعاة النوع long-animation-frame
بدلاً من ذلك:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'long-animation-frame', buffered: true });
يمكن أيضًا طلب البحث عن إطارات الصور المتحركة الطويلة السابقة من المخطط الزمني للأداء كما يلي:
const loafs = performance.getEntriesByType('long-animation-frame');
ومع ذلك، هناك maxBufferSize
لإدخالات الأداء يتم بعدها استبعاد الإدخالات الجديدة، وبالتالي فإنّ أسلوب PerformanceObserver هو الأسلوب المقترَح. تم ضبط حجم المخزن المؤقت long-animation-frame
على 200، كما هو الحال في long-tasks
.
مزايا النظر إلى الإطارات بدلاً من المهام
تتمثل الميزة الرئيسية للنظر في هذا من منظور إطار بدلاً من منظور المهام، في أن الرسوم المتحركة الطويلة يمكن أن تتكون من أي عدد من المهام التي نتج عنها بشكل تراكمي إطار رسوم متحركة طويل. يعالج هذا النقطة الأخيرة المذكورة سابقًا، حيث قد لا يتم عرض مجموع العديد من المهام الأصغر التي تمنع العرض قبل إطار الصورة المتحركة من خلال واجهة برمجة التطبيقات Long Tasks API.
ومن المزايا الأخرى لهذا العرض البديل في المهام الطويلة القدرة على توفير تقسيمات التوقيت للإطار بالكامل. بدلاً من تضمين startTime
وduration
فقط، مثل Long Tasks API، يتضمن LoAF تقسيمًا أكثر تفصيلاً للأجزاء المختلفة من مدة عرض اللقطة، بما في ذلك:
startTime
: وقت بدء إطار الرسوم المتحركة الطويل بالنسبة إلى وقت بدء التنقّل.duration
: مدة إطار الصورة المتحركة الطويل (لا تشمل وقت العرض التقديمي)renderStart
: وقت بدء دورة العرض، الذي يتضمن استدعاءاتrequestAnimationFrame
، وحساب الأنماط والتنسيق، وتغيير حجم أداة المراقب، وعمليات استدعاء أداة مراقبة التقاطع.styleAndLayoutStart
: بداية الفترة الزمنية التي يتم قضاؤها في عمليات احتساب الأنماط والتصميمات.firstUIEventTimestamp
: وقت الحدث الأول في واجهة المستخدم (الماوس/لوحة المفاتيح وما إلى ذلك) خلال فترة عرض هذا الإطارblockingDuration
: المدة بالمللي ثانية التي تم خلالها حظر إطار الحركة.
تتيح هذه الطوابع الزمنية تقسيم إطار الصورة المتحركة الطويل إلى توقيتات:
التوقيت | العملية الحسابية |
---|---|
وقت البدء | startTime |
وقت الانتهاء | startTime + duration |
مدة العمل | renderStart ? renderStart - startTime : duration |
مدة العرض | renderStart ? (startTime + duration) - renderStart: 0 |
العرض: مدة التخطيط المسبق | styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0 |
العرض: مدة النمط والتنسيق | styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0 |
لمزيد من التفاصيل حول هذه التوقيتات الفردية، يمكنك الاطّلاع على الشرح الذي يقدّم تفاصيل دقيقة عن النشاط الذي يساهم في عرض لقطات متحرّكة طويلة.
تحديد المصدر بشكل أفضل
يتضمّن نوع الإدخال long-animation-frame
بيانات إحالة أفضل لكل نص برمجي ساهم في إنشاء إطار طويل للصور المتحركة.
على غرار واجهة برمجة التطبيقات Long Tasks API، سيتم توفير ذلك في مجموعة من إدخالات تحديد المصدر، لكل منها تفاصيل:
- وكلاهما يعرض
name
وEntryType
ويعرض القيمةscript
. - تمثّل هذه السمة
invoker
معنى يشير إلى كيفية تسمية النص البرمجي (مثل'IMG#id.onload'
أو'Window.requestAnimationFrame'
أو'Response.json.then'
). invokerType
لنقطة إدخال النص البرمجي:user-callback
: يشير هذا المصطلح إلى معاودة اتصال معروفة مسجَّلة من خلال واجهة برمجة تطبيقات لمنصة الويب (مثلsetTimeout
وrequestAnimationFrame
).event-listener
: أداة استماع إلى حدث على المنصة (مثلclick
وload
وkeyup
)resolve-promise
: الجهة المسؤولة عن معالجة وعود منصة (على سبيل المثال،fetch()
) يُرجى العِلم أنّه في حال الوعود، يتم مزج كل الجهات التي تعالج هذه الوعود ضمن "نص نصي" واحد..
reject-promise
: وفقًا لـresolve-promise
، ولكن بالنسبة إلى الرفض.classic-script
: تقييم النص البرمجي (على سبيل المثال،<script>
أوimport()
)module-script
: مماثلة لـclassic-script
لكن للنصوص البرمجية للوحدات.
- فصل بيانات التوقيت لهذا النص البرمجي:
startTime
: وقت استدعاء دالة الإدخالduration
: المدة بينstartTime
ووقت الانتهاء من معالجة قائمة انتظار المهام الصغيرة اللاحقة.executionStart
: الوقت الذي يلي استخدام الفيديو لتجميع المحتوىforcedStyleAndLayoutDuration
: إجمالي الوقت المستغرَق في معالجة التنسيق والنمط المفروضة داخل هذه الدالة (راجِع التقسيم).pauseDuration
: إجمالي الوقت المستغرَق في "الإيقاف المؤقت" العمليات المتزامنة (تنبيه، XHR متزامن).
- تفاصيل مصدر النص البرمجي:
sourceURL
: اسم مورد النص البرمجي حيثما كان متاحًا (أو فارغًا إذا لم يتم العثور عليه).sourceFunctionName
: اسم دالة النص البرمجي عندما يكون متاحًا (أو فارغًا إذا لم يتم العثور عليه).sourceCharPosition
: موضع حرف النص البرمجي حيثما كان ذلك متاحًا (أو -1 في حال عدم العثور عليه).
windowAttribution
: الحاوية (مستند المستوى الأعلى أو<iframe>
) الذي يظهر فيه إطار الصور المتحركة الطويلwindow
: إشارة إلى نافذة المصدر نفسه
عند توفير الإدخالات المصدر، تتيح إدخالات المصدر للمطوّرين معرفة كيفية استدعاء كل نص برمجي في إطار الصورة المتحركة الطويل، وصولاً إلى موضع الحرف في النص البرمجي للاستدعاء. يوضح ذلك الموقع الدقيق في مورد JavaScript الذي نتج عنه عرض الصورة المتحركة الطويل.
مثال على إدخال أداء long-animation-frame
فيما يلي مثال كامل على إدخال أداء long-animation-frame
، يتضمن نصًا برمجيًا واحدًا:
{
"blockingDuration": 0,
"duration": 60,
"entryType": "long-animation-frame",
"firstUIEventTimestamp": 11801.099999999627,
"name": "long-animation-frame",
"renderStart": 11858.800000000745,
"scripts": [
{
"duration": 45,
"entryType": "script",
"executionStart": 11803.199999999255,
"forcedStyleAndLayoutDuration": 0,
"invoker": "DOMWindow.onclick",
"invokerType": "event-listener",
"name": "script",
"pauseDuration": 0,
"sourceURL": "https://web.dev/js/index-ffde4443.js",
"sourceFunctionName": "myClickHandler",
"sourceCharPosition": 17796,
"startTime": 11803.199999999255,
"window": [Window object],
"windowAttribution": "self"
}
],
"startTime": 11802.400000000373,
"styleAndLayoutStart": 11858.800000000745
}
يتّضح مما سبق أنّ هذه البيانات توفّر كمية غير مسبوقة من البيانات للمواقع الإلكترونية لتتمكن من فهم سبب تأخُّر التعديلات في العرض.
استخدام واجهة برمجة تطبيقات Long Animation Frames في الحقل
إنّ أدوات مثل "أدوات مطوري البرامج في Chrome" وLighthouse مفيدة في اكتشاف المشاكل وإعادة إنتاجها، هي أدوات اختبارية قد تفتقد إلى جوانب مهمة من تجربة المستخدم لا يمكن أن توفّرها سوى البيانات الميدانية.
تم تصميم واجهة برمجة تطبيقات Long Animation Frames لاستخدامها في المجال لجمع البيانات السياقية المهمة لتفاعلات المستخدم التي لا تستطيع واجهة برمجة تطبيقات Long Tasks API القيام بها. يمكن أن يساعدك ذلك في تحديد وإعادة إنتاج المشاكل المتعلّقة بالتفاعل التي ربما لم تكتشفها بطريقة أخرى.
رصد الميزات المتوافقة مع واجهة برمجة التطبيقات Long Animation Frames
يمكنك استخدام الرمز التالي لاختبار ما إذا كانت واجهة برمجة التطبيقات متوافقة:
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
// Monitor LoAFs
}
رابط إلى أطول تفاعل لـ INP
وتتمثل حالة الاستخدام الأكثر وضوحًا لواجهة برمجة التطبيقات Long Animation Frames API في المساعدة في تشخيص مشاكل مدى استجابة الصفحة لتفاعلات المستخدم (INP) وإصلاحها، وكان ذلك أحد الأسباب الرئيسية لتطوير فريق Chrome لواجهة برمجة التطبيقات هذه. إنّ مدى استجابة الصفحة لتفاعلات المستخدم (INP) جيّد عندما يتم الردّ على كل التفاعلات خلال 200 ملّي ثانية أو أقلّ من التفاعل إلى أن يتم عرض الإطار. وبما أنّ واجهة برمجة تطبيقات Long Animation Frames API تقيس كل اللقطات التي تستغرق 50 ملّي ثانية أو أكثر، يجب أن تتضمّن معظم مقاييس INP المسببة مشاكل بيانات LoAF لمساعدتك في تشخيص تلك التفاعلات.
"مقياس INP LoAF" هو نموذج LoAF الذي يتضمّن تفاعل INP، كما هو موضّح في الرسم البياني التالي:
![أمثلة على إطارات الصور المتحركة الطويلة على الصفحة، مع تمييز "الإطار الفقاعي INP"](https://developer.chrome.com/static/docs/web-platform/long-animation-frames/image/loaf-inp.png?authuser=19&hl=ar)
في بعض الحالات، من الممكن أن يمتد حدث INP إلى عرضين من نوعي LoAF، عادةً إذا حدث التفاعل بعد بدء الإطار جزء العرض من الإطار السابق، وبالتالي معالج الحدث الذي تمت معالجته في الإطار التالي:
![أمثلة على إطارات الصور المتحركة الطويلة على الصفحة، مع تمييز "الإطار الفقاعي INP"](https://developer.chrome.com/static/docs/web-platform/long-animation-frames/image/loaf-inp-two-frames.png?authuser=19&hl=ar)
ومن الممكن أيضًا أن يمتد إلى أكثر من اثنين من الرغبات في بعض الحالات النادرة.
يتيح لك تسجيل بيانات LoAF المرتبطة بتفاعل INP الحصول على مزيد من المعلومات حول تفاعل INP للمساعدة في تشخيصه. يساعد ذلك بشكل خاص في التعرّف على تأخّر الإدخال، لأنّه يمكنك التعرّف على النصوص البرمجية الأخرى التي كانت تعمل في هذا الإطار.
قد يكون من المفيد أيضًا معرفة مدة المعالجة وتأخُّر العرض التقديمي غير المبررة إذا كانت معالِجات الأحداث لا تعيد إنتاج القيم التي تظهر لتلك القيم، لأنّ نصوصًا برمجية أخرى قد تكون قيد التشغيل للمستخدمين، وقد لا يتم تضمينها في الاختبار الخاص بك.
لا لا تتوفّر واجهة برمجة تطبيقات مباشرة لربط إدخال INP بإدخالات أو إدخالات LoAF ذات الصلة، ولكن يمكن إجراء ذلك في الرمز البرمجي من خلال مقارنة وقتَي البدء والانتهاء لكل منهما (يُرجى الاطّلاع على مثال النص البرمجي WhyNp).
تتضمّن مكتبة web-vitals
كل إعلانات LoAF المتقاطعة في السمة longAnimationFramesEntries
الخاصة بواجهة تحديد المصدر INP من الإصدار 4.
بعد ربط إدخال أو إدخالات LoAF، يمكنك تضمين المعلومات باستخدام عملية تحديد INP. يحتوي عنصر scripts
على بعض المعلومات الأكثر قيمة، لأنّه يمكن أن يعرض العناصر الأخرى التي كانت تُعرض في تلك الإطارات، لذا فإنّ إرسال إشارة إلى هذه البيانات إلى خدمة التحليلات يسمح لك بفهم مزيد من المعلومات عن سبب بطء التفاعلات.
من خلال الإبلاغ عن "خيارات تقديم المحتوى بدون انقطاع" المتعلقة بتفاعل "مدى استجابة الصفحة لتفاعلات المستخدم" (INP)، يمكنك معرفة المشاكل الأكثر إلحاحًا بشأن التفاعل على صفحتك. قد يتفاعل كلّ مستخدِم بشكل مختلف مع صفحتك، ومع ما يكفي من بيانات تحديد مصدر مقياس INP، سيتمّ تضمين عدد من المشاكل المحتملة في بيانات تحديد مصدر مقياس INP. يتيح لك ذلك ترتيب النصوص البرمجية حسب وحدة التخزين لمعرفة النصوص البرمجية المرتبطة بمقياس INP البطيء.
الإبلاغ عن المزيد من بيانات الصور المتحركة الطويلة في نقطة نهاية الإحصاءات
من الجوانب السلبية عند النظر فقط إلى نهج INP المنخفض، وهو أنّك قد تفتقد نقاطًا أخرى محتملة للتحسينات قد تؤدي إلى حدوث مشاكل مستقبلية بخصوص INP. قد يؤدّي ذلك إلى شعور بالانزعاج عندما تحلّ مشكلة "مدى استجابة الصفحة لتفاعلات المستخدم" (INP) وأنّك تتوقّع حدوث تحسّن كبير في الأداء، ولكن عليك معرفة أنّ ثاني أبطأ تفاعل يكون أفضل بكثير من ذلك، وبالتالي لن يتحسّن INP كثيرًا.
لذلك، بدلاً من تسليط الضوء على العرض المفصَّل لـ INP، ننصحك بالتفكير في جميع طلبات الدعم على مستوى الصفحة منذ إنشائها:
![صفحة تحتوي على العديد من نماذج LoAF، ويحدث بعضها أثناء التفاعلات حتى لو لم يكن تفاعل INP.](https://developer.chrome.com/static/docs/web-platform/long-animation-frames/image/all-loafs.png?authuser=19&hl=ar)
مع ذلك، يحتوي كل إدخال من إدخالات LoAF على بيانات مهمة، وبالتالي قد لا تريد إعادة الإشارة إلى هذه البيانات كلها. بدلاً من ذلك، سترغب في قصر التحليل على بعض LoAFs أو بعض البيانات.
تشمل بعض الأنماط المقترَحة ما يلي:
- تتبُّع إطارات الصور المتحركة الطويلة من خلال التفاعلات
- ملاحظة إطارات الصور المتحركة التي تزيد مدتها عن حدّ معيّن
- تتبُّع أسوأ إطارات الصور المتحركة الطويلة
- تحديد الأنماط الشائعة في إطارات الصور المتحركة الطويلة
يعتمد النمط الأنسب لك على مدى تقدّمك في رحلة التحسين، ومدى رواج إطارات الصور المتحركة الطويلة. بالنسبة إلى الموقع الذي لم يسبق له تحسين للاستجابة، قد يكون هناك العديد من نماذج LoAF التي قد ترغب في قصرها على LoAFs فقط مع التفاعلات، أو تعيين حد عالٍ، أو النظر فقط إلى أسوأ التفاعلات. وأثناء حل المشاكل الشائعة للاستجابة، يمكنك توسيع ذلك من خلال عدم الاقتصار على التفاعلات فقط وخفض المعايير، أو البحث عن أنماط معينة.
ملاحظة إطارات الصور المتحركة الطويلة مع التفاعلات
للحصول على إحصاءات لا تقتصر على إطار الصور المتحركة الطويل INP، يمكنك الاطّلاع على جميع نماذج LoAF باستخدام التفاعلات (والتي يمكن رصدها من خلال توفُّر قيمة firstUIEventTimestamp
).
ويمكن أن تكون هذه الطريقة أسهل في تتبُّع طلبات البحث بدون موافقة INP بدلاً من محاولة الربط بينهما، الأمر الذي قد يكون أكثر تعقيدًا. في معظم الحالات، سيشمل هذا النوع من الإجراءات "مدى استجابة الصفحة لتفاعلات المستخدم" (INP) لزيارة معيّنة. وفي حالات نادرة، عندما لا يظهر في هذه الحالة تفاعلات طويلة يجب حلّها، لأنّها قد تمثّل تفاعل المستخدمين الآخرين.
يسجل الرمز التالي جميع إدخالات LoAF التي تزيد مدتها عن 150 مللي ثانية حيث حدث التفاعل أثناء الإطار. تم اختيار العدد 150 هنا لأنّه أقل قليلاً من القيمة "جيدة" التي تبلغ 200 ملي ثانية الحدّ الأدنى لمدى استجابة الصفحة لتفاعلات المستخدم (INP). يمكنك اختيار قيمة أعلى أو أقل حسب احتياجاتك.
const REPORTING_THRESHOLD_MS = 150;
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.duration > REPORTING_THRESHOLD_MS &&
entry.firstUIEventTimestamp > 0
) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
ملاحظة إطارات الصور المتحركة التي تزيد مدتها عن حدّ معيّن
تتمثل الإستراتيجية الأخرى في مراقبة جميع LoAFs وتوجيه الإشارات التي تزيد عن حد معين إلى نقطة نهاية تحليلات البيانات لتحليلها لاحقًا:
const REPORTING_THRESHOLD_MS = 150;
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.duration > REPORTING_THRESHOLD_MS) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
نظرًا لأن الإدخالات الطويلة لإطار الصور المتحركة يمكن أن تكون كبيرة جدًا، على المطوّرين تحديد البيانات التي يجب إرسالها من الإدخال إلى الإحصاءات. على سبيل المثال، أوقات تلخيص الإدخال وربما أسماء النصوص البرمجية أو الحد الأدنى الآخر من مجموعة البيانات السياقية الأخرى التي قد تعتبر ضرورية.
ملاحظة أسوأ إطارات صور متحركة طويلة
وبدلاً من وضع حد معين، قد ترغب المواقع في جمع البيانات عن أطول إطار (أو إطارات) للصور المتحركة، وذلك لخفض حجم البيانات التي تحتاج إلى الإشارة إليها. لذا بغض النظر عن عدد إطارات الصور المتحركة الطويلة التي تتم تجربتها في الصفحة، فلا تتم الإشارة إلا إلى البيانات المتعلقة بأسوأ إطار أو خمسة أو العديد من إطارات الرسوم المتحركة الطويلة الضرورية للغاية.
MAX_LOAFS_TO_CONSIDER = 10;
let longestBlockingLoAFs = [];
const observer = new PerformanceObserver(list => {
longestBlockingLoAFs = longestBlockingLoAFs.concat(list.getEntries()).sort(
(a, b) => b.blockingDuration - a.blockingDuration
).slice(0, MAX_LOAFS_TO_CONSIDER);
});
observer.observe({ type: 'long-animation-frame', buffered: true });
يمكن أيضًا دمج هذه الاستراتيجيات، حيث يجب النظر فقط إلى أسوأ 10 تصاميم إعلانات لـ LoAF، مع عرض تفاعلات أطول من 150 ملّي ثانية.
وفي الوقت المناسب (يُفضَّل في حدث visibilitychange
)، يمكنك إرسال إشارة مرة أخرى إلى الإحصاءات. للاختبار المحلي، يمكنك استخدام console.table
بشكل دوري:
console.table(longestBlockingLoAFs);
تحديد الأنماط الشائعة في إطارات الصور المتحركة الطويلة
تتمثل الإستراتيجية البديلة في النظر إلى النصوص البرمجية الشائعة التي تظهر أكثر من غيرها في إدخالات إطارات الرسوم المتحركة الطويلة. يمكن الإبلاغ عن البيانات على مستوى النص البرمجي وموضع الحرف لتحديد المخالفين المتكرّرين.
وقد يكون هذا الأمر مفيدًا بشكل خاص للأنظمة الأساسية القابلة للتخصيص حيث يمكن تحديد المظاهر أو المكوّنات الإضافية التي تتسبب في مشاكل في الأداء عبر عدد من المواقع الإلكترونية.
يمكن تلخيص وقت تنفيذ النصوص البرمجية الشائعة، أو مصادر الجهات الخارجية، في إطارات الصور المتحركة الطويلة، وتسجيلها مرة أخرى لتحديد المساهمين الشائعين في إطارات الصور المتحركة الطويلة على أحد المواقع الإلكترونية أو مجموعة من المواقع الإلكترونية. على سبيل المثال، للاطّلاع على عناوين URL:
const observer = new PerformanceObserver(list => {
const allScripts = list.getEntries().flatMap(entry => entry.scripts);
const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
const scriptsBySource= scriptSource.map(sourceURL => ([sourceURL,
allScripts.filter(script => script.sourceURL === sourceURL)
]));
const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
sourceURL,
count: scripts.length,
totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
}));
processedScripts.sort((a, b) => b.totalDuration - a.totalDuration);
// Example here logs to console, but could also report back to analytics
console.table(processedScripts);
});
observer.observe({type: 'long-animation-frame', buffered: true});
ومثال على هذا الإخراج هو:
(index) |
sourceURL |
count |
totalDuration |
---|---|---|---|
0 |
'https://example.consent.com/consent.js' |
1 |
840 |
1 |
'https://example.com/js/analytics.js' |
7 |
628 |
2 |
'https://example.chatapp.com/web-chat.js' |
1 |
5 |
استخدام واجهة برمجة تطبيقات Long Animation Frames في الأدوات
تتيح واجهة برمجة التطبيقات أيضًا أدوات إضافية للمطوّرين من أجل تصحيح الأخطاء على الجهاز. وعلى الرغم من أنّ بعض الأدوات، مثل Lighthouse وChrome DevTools، تمكّنت من جمع الكثير من هذه البيانات باستخدام تفاصيل تتبُّع البيانات على مستوى أقل، فإنّ استخدام واجهة برمجة التطبيقات ذات المستوى الأعلى هذه قد يتيح لأدوات أخرى الوصول إلى هذه البيانات.
عرض بيانات إطارات الصور المتحركة الطويلة في "أدوات مطوري البرامج"
يمكنك عرض إطارات الصور المتحركة الطويلة في "أدوات مطوري البرامج" باستخدام واجهة برمجة التطبيقات performance.measure()
، والتي يتم عرضها بعد ذلك في مسار توقيتات المستخدم في "أدوات مطوّري البرامج" في تقارير الأداء لإظهار الجوانب التي يجب تركيز جهودك فيها على تحسين الأداء:
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
performance.measure('LoAF', {
start: entry.startTime,
end: entry.startTime + entry.duration,
});
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
وعلى المدى البعيد، من المحتمل أن يتم دمجها في "أدوات مطوري البرامج" نفسها، ولكن يسمح مقتطف الرمز السابق بعرضها هناك في الوقت الحالي.
استخدام بيانات إطارات الصور المتحركة الطويلة في أدوات المطوّرين الأخرى
أظهرت إضافة "مؤشرات أداء الويب" القيمة في معلومات تصحيح الأخطاء المرتبطة بملخّص التسجيل لتشخيص مشاكل الأداء.
ويعرض الآن أيضًا بيانات إطار الصورة المتحركة الطويلة لكل معاودة اتصال بـ INP وكل تفاعل على النحو التالي:
![تسجيل وحدة التحكّم في إضافة مؤشرات أداء الويب](https://developer.chrome.com/static/docs/web-platform/long-animation-frames/image/loaf-web-vitals-extension.png?authuser=19&hl=ar)
استخدام بيانات إطارات الصور المتحركة الطويلة في أدوات الاختبار المبرمجة
على نحو مماثل، يمكن لأدوات الاختبار المبرمَجة في مسارات مرحلة التطوير المستمر (CI) والأقراص المدمجة (CD) عرض تفاصيل حول مشاكل الأداء المحتملة من خلال قياس إطارات الصور المتحركة الطويلة أثناء تشغيل مجموعات اختبار مختلفة.
الأسئلة الشائعة
في ما يلي بعض الأسئلة الشائعة حول واجهة برمجة التطبيقات هذه:
لماذا لا يقتصر الأمر على تمديد استخدام Long Tasks API أو تكراره فقط؟
هذه نظرة بديلة للإبلاغ عن قياس مشابه، ولكن مختلف في النهاية، للمشاكل المحتملة في الاستجابة. من المهم التأكّد من استمرار عمل المواقع الإلكترونية التي تعتمد على واجهة Long Tasks API الحالية لتجنُّب إيقاف حالات الاستخدام الحالية.
على الرغم من أنّ واجهة Long Tasks API قد تستفيد من بعض ميزات LoAF (مثل نموذج تحديد مصدر أفضل)، نعتقد أنّ التركيز على الإطارات بدلاً من المهام يوفّر العديد من المزايا التي تجعل هذه الواجهة مختلفة تمامًا عن واجهة برمجة التطبيقات Long Tasks API الحالية.
لماذا لا تتوفّر لدي إدخالات النص البرمجي؟
وقد يشير ذلك إلى أنّ إطار الصورة المتحركة الطويل لم يكن بسبب JavaScipt، ولكن بسبب عمل العرض الضخم.
يمكن أن يحدث ذلك أيضًا عندما يكون إطار الصورة المتحركة الطويل بسبب JavaScript ولكن لا يمكن تقديم مصدر النص البرمجي لأسباب متعددة بشأن الخصوصية كما هو موضّح سابقًا (في المقام الأول، لا تكون لغة JavaScript مملوكة للصفحة).
لماذا أحصل على إدخالات للنص البرمجي ولكن لا تتوفر معلومات المصدر أو معلومات محدودة عنها؟
وقد يحدث ذلك لعدة أسباب، منها عدم توفّر مصدر جيد للإشارة إليه.
ستكون معلومات النص البرمجي محدودة أيضًا في no-cors cross-origin
نصًا برمجيًا، على الرغم من إمكانية حل هذه المشكلة عن طريق استرجاع هذه النصوص البرمجية باستخدام سياسة مشاركة الموارد المتعددة المصادر (CORS) عن طريق إضافة crossOrigin = "anonymous"
إلى استدعاء <script>
.
على سبيل المثال، النص البرمجي التلقائي لأداة "إدارة العلامات من Google" المطلوب إضافته إلى الصفحة:
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
يمكن تحسينها لإضافة j.crossOrigin = "anonymous"
للسماح بتقديم تفاصيل تحديد المصدر الكاملة في "إدارة العلامات من Google".
هل سيحلّ ذلك محلّ واجهة برمجة التطبيقات Long Tasks API؟
نعتقد أنّ واجهة برمجة تطبيقات Long Animation Frames API أفضل وأكثر اكتمالاً لقياس المهام الطويلة، ولكن في الوقت الحالي، لا نخطط لإيقاف واجهة Long Tasks API نهائيًا.
الملاحظات مطلوبة
يمكن تقديم الملاحظات من خلال قائمة مشاكل GitHub، أو يمكن حفظ الأخطاء في تنفيذ واجهة برمجة التطبيقات في Chrome في أداة تتبُّع المشاكل في Chrome.
الخاتمة
واجهة برمجة التطبيقات Long Animation Frames API هي واجهة برمجة تطبيقات جديدة ومثيرة للاهتمام بها العديد من المزايا المحتملة مقارنةً بواجهة برمجة تطبيقات Long Task API السابقة.
وقد ثبت أنّه أداة رئيسية لمعالجة مشاكل الاستجابة حسب ما يتم قياسه من خلال مقياس INP. ويشكّل INP مقياسًا صعبًا لتحسينه، وتمثّل واجهة برمجة التطبيقات هذه إحدى الطرق التي يسعى فريق Chrome إلى تسهيلها على المطوّرين لتحديد المشاكل ومعالجتها.
مع ذلك، يمتد نطاق واجهة برمجة التطبيقات Long Animation Frames API إلى ما هو أبعد من مقياس INP، ويمكن أن يساعد في تحديد الأسباب الأخرى لبطء التحديثات التي يمكن أن تؤثر في سلاسة تجربة المستخدم على الموقع الإلكتروني بشكل عام.
شكر وتقدير
صورة مصغّرة للفنان هنري بي على إلغاء البداية