في السابق، كان من الصعب على مطوّري الويب قياس سرعة ظهور المحتوى الرئيسي لصفحة الويب للمستخدمين. لا تعمل المقاييس القديمة، مثل load أو DOMContentLoaded، بشكل جيد لأنّها لا تتوافق بالضرورة مع ما يراه المستخدم على شاشته. أمّا مقاييس الأداء الجديدة التي تركّز على المستخدِم، مثل سرعة عرض المحتوى على الصفحة (FCP)، فلا ترصد سوى بداية تجربة التحميل. إذا كانت الصفحة تعرض شاشة البداية أو مؤشر التحميل، لن تكون هذه اللحظة ملائمة جدًا للمستخدم.
في السابق، كنا نقترح مقاييس الأداء، مثل سرعة عرض أول محتوى مرئي (FMP) ومؤشر السرعة (SI) (كلاهما متاح في Lighthouse) للمساعدة في رصد المزيد من تجربة التحميل بعد عرض الصفحة للمرة الأولى، ولكنّ هذه المقاييس معقّدة ويصعب شرحها وغالبًا ما تكون خاطئة، ما يعني أنّها لا تزال لا تحدّد وقت تحميل المحتوى الرئيسي للصفحة.
استنادًا إلى المناقشات التي أجريناها في مجموعة عمل أداء الويب في W3C والأبحاث التي أجريناها في Google، تبيّن لنا أنّ الطريقة الأكثر دقة لقياس وقت تحميل المحتوى الرئيسي للصفحة هي الاطّلاع على وقت عرض العنصر الأكبر.
ما هو مقياس LCP؟
يشير مقياس LCP إلى الوقت الذي تستغرقه أكبر صورة أو مقطع نصي أو فيديو للظهور ضمن إطار العرض مقارنةً بالوقت الذي انتقل فيه المستخدم إلى الصفحة لأول مرة.
ما هي نتيجة LCP الجيدة؟
لتقديم تجربة جيدة للمستخدم، يجب أن تسعى المواقع الإلكترونية إلى أن تكون سرعة عرض أكبر محتوى مرئي 2.5 ثانية أو أقل. لضمان تحقيق هذا المستهدف لمعظم المستخدمين، يمكنك قياس الشريحة المئوية الخامسة والسبعين من عمليات تحميل الصفحات، مقسّمة على الأجهزة الجوّالة وأجهزة الكمبيوتر المكتبي.
ما هي العناصر التي يتم أخذها في الاعتبار؟
وفقًا لما هو محدّد حاليًا في واجهة برمجة التطبيقات الخاصة بمقياس "سرعة عرض أكبر محتوى مرئي" (LCP)، فإنّ أنواع العناصر التي يتم أخذها في الاعتبار عند احتساب مقياس "سرعة عرض أكبر محتوى مرئي" هي:
<img>
العناصر (يُستخدَم وقت عرض اللقطة الأولى للمحتوى المتحرك، مثل ملفات GIF أو ملفات PNG المتحركة)- عناصر
<image>
داخل عنصر<svg>
- عناصر
<video>
(يتم استخدام وقت تحميل صورة الملصق أو وقت عرض اللقطة الأولى للفيديوهات، أيهما أقرب) - عنصر يحتوي على صورة خلفية تم تحميلها باستخدام الدالة
url()
(بدلاً من تدرّج CSS) - العناصر على مستوى الحظر التي تحتوي على عقد نصية أو عناصر نصية أخرى على مستوى النص المضمّن
يُرجى العِلم أنّه تمّ حصر العناصر بهذه المجموعة المحدودة عن قصد للحفاظ على البساطة في البداية. قد تتم إضافة عناصر إضافية (مثل إتاحة <svg>
بالكامل) في المستقبل بعد إجراء المزيد من الأبحاث.
بالإضافة إلى الأخذ في الاعتبار بعض العناصر فقط، تستخدِم قياسات LCP أساليب استقرائية لاستبعاد عناصر معيّنة يُرجّح أن يراها المستخدمون على أنّها "غير ذات محتوى". بالنسبة إلى المتصفّحات المستندة إلى Chromium، تشمل هذه المتصفحات ما يلي:
- العناصر التي تكون شفافيتها 0، والتي لا تظهر للمستخدم
- العناصر التي تغطي إطار العرض بالكامل، والتي يُحتمل أن تُعتبر خلفية بدلاً من محتوى
- صور نائبة أو صور أخرى ذات محتوى منخفض، ومن المحتمل أنّها لا تعكس المحتوى الفعلي للصفحة
من المرجّح أن تواصل المتصفّحات تحسين هذه الأساليب الاستقرائية لضمان تلبية توقعات المستخدمين بشأن العنصر المحتوي على أكبر قدر من المحتوى.
قد تختلف هذه الأساليب الاستقرائية "المحتوية على محتوى" عن تلك المستخدَمة في سرعة عرض المحتوى على الصفحة (FCP)، والتي قد تأخذ في الاعتبار بعض هذه العناصر، مثل الصور النائبة أو صور إطار العرض الكامل، حتى إذا كانت غير مؤهّلة لتكون مرشّحين لسرعة عرض أكبر جزء من المحتوى على الصفحة. على الرغم من أنّ كلا المقياسَين يستخدمان كلمة "محتوى" في اسمهما، إلا أنّ هدفهما مختلف. يقيس مقياس "سرعة عرض المحتوى على الصفحة" الوقت الذي يتم فيه عرض أي محتوى على الشاشة، ويقيس مقياس "سرعة عرض أكبر محتوى مرئي" الوقت الذي يتم فيه عرض المحتوى الرئيسي، لذا يكون مقياس "سرعة عرض أكبر محتوى مرئي" أكثر انتقائية.
كيف يتم تحديد حجم العنصر؟
عادةً ما يكون حجم العنصر الذي يتم تسجيله في LCP هو الحجم المرئي للمستخدم ضمن إطار العرض. إذا كان العنصر يمتد خارج مساحة العرض، أو إذا تم اقتصاص أي جزء من العنصر أو كان يحتوي على عناصر زائدة غير مرئية، لا يتم احتساب هذه الأجزاء في حجم العنصر.
بالنسبة إلى عناصر الصور التي تم تغيير حجمها من حجمها الأساسي، يكون الحجم الذي يتم تسجيله هو الحجم المرئي أو الحجم الأساسي، أيهما أصغر.
بالنسبة إلى عناصر النص، لا تأخذ مقياس LCP في الاعتبار سوى أصغر مستطيل يمكن أن يحتوي على جميع عقد النص.
لا تأخذ مقياس LCP في الاعتبار الهوامش أو الحشوات أو الحدود المطبَّقة باستخدام CSS في جميع العناصر.
متى يتم تسجيل LCP؟
غالبًا ما يتم تحميل صفحات الويب على مراحل، ونتيجةً لذلك، من المحتمل أن يتغيّر العنصر الأكبر على الصفحة.
للتعامل مع هذا التغيير المحتمل، يُرسِل المتصفّح PerformanceEntry
من النوع largest-contentful-paint
لتحديد أكبر عنصر ذي محتوى بعد أن يعرض المتصفّح الإطار الأول. ولكن بعد عرض اللقطات اللاحقة، سيتم إرسال PerformanceEntry
آخر في أي وقت يتغيّر فيه أكبر عنصر ذي محتوى.
على سبيل المثال، في صفحة تتضمّن نصًا وصورة رئيسية، قد يعرض المتصفّح النص في البداية فقط، وعندئذٍ يُرسِل المتصفّح إدخال largest-contentful-paint
يُرجّح أن تشير سمة element
فيه إلى <p>
أو <h1>
. لاحقًا، بعد انتهاء تحميل صورة العرض الرئيسية، سيتم إرسال إدخال largest-contentful-paint
ثانٍ وسيكون سمة element
الخاصة به تشير إلى <img>
.
لا يمكن اعتبار عنصر معيّن هو أكبر عنصر يتضمّن محتوى إلا بعد أن يتم عرضه ويصبح مرئيًا للمستخدم. لا تُعدّ الصور التي لم يتم تحميلها بعد "معروضة". ولا يتم استخدام خطوط الويب في العقد النصية خلال فترة حظر الخطوط. في هذه الحالات، قد يتم تسجيل عنصر أصغر كأكبر عنصر يتضمّن محتوى، ولكن بعد انتهاء عرض العنصر الأكبر، يتم إنشاء PerformanceEntry
آخر.
بالإضافة إلى الصور والخطوط التي يتم تحميلها بعد وقت طويل، قد تضيف الصفحة عناصر جديدة إلى نموذج DOM عندما يصبح المحتوى الجديد متاحًا. إذا كان أيّ من هذه العناصر الجديدة أكبر من أكبر عنصر يتضمّن محتوى سابقًا، سيتمّ أيضًا الإبلاغ عن PerformanceEntry
جديد.
إذا تمت إزالة أكبر عنصر مرئي من إطار العرض أو حتى من نموذج DOM، سيظل أكبر عنصر مرئي ما لم يتم عرض عنصر أكبر.
سيتوقف المتصفّح عن الإبلاغ عن الإدخالات الجديدة فور تفاعل المستخدم مع الصفحة (من خلال النقر أو الانتقال إلى الأسفل أو الضغط على مفتاح)، لأنّ تفاعل المستخدم غالبًا ما يغيّر ما يظهر للمستخدم (وهو ما ينطبق بشكل خاص على الانتقال إلى الأسفل).
لأغراض التحليل، يجب الإبلاغ عن آخر PerformanceEntry
تم إرساله إلى خدمة الإحصاءات فقط.
وقت التحميل مقارنةً بوقت العرض
لأسباب تتعلّق بالأمان، لا يتم عرض الطابع الزمني لعرض الصور للصور من مصادر مختلفة التي لا تتضمّن العنوان Timing-Allow-Origin
. بدلاً من ذلك، يتم عرض وقت التحميل فقط (لأنّه سبق أن تم عرضه من خلال العديد من واجهات برمجة تطبيقات الويب الأخرى).
ويمكن أن يؤدّي ذلك إلى حدوث موقف يبدو مستحيلاً، حيث تُبلغ واجهات برمجة تطبيقات الويب عن LCP في وقت أبكر من FCP. لا يحدث ذلك، ولكن يبدو أنّه كذلك بسبب هذا القيد الأمني.
ننصحك دائمًا بضبط العنوان Timing-Allow-Origin
كلما أمكن، حتى تكون مقاييسك أكثر دقة.
كيف يتم التعامل مع تغييرات تنسيق العناصر وحجمها؟
للحفاظ على انخفاض الوقت المستغرَق في احتساب إدخالات الأداء الجديدة وإرسالها، لا تؤدي التغييرات في حجم العنصر أو موضعه إلى إنشاء مرشّحين جدد لـ LCP. لا يؤخذ بعين الاعتبار سوى الحجم الأولي للعنصر وموضعه في إطار العرض.
وهذا يعني أنّه قد لا يتم تسجيل الصور التي يتم عرضها في البداية خارج الشاشة ثم تظهر على الشاشة. ويعني ذلك أيضًا أنّ العناصر التي يتم عرضها في البداية في إطار العرض ثم يتم دفعها للأسفل خارج نطاق العرض ستظل تُبلغ عن حجمها الأولي في إطار العرض.
أمثلة
في ما يلي بعض الأمثلة على حالات حدوث سرعة عرض أكبر جزء من المحتوى على الصفحة في بعض المواقع الإلكترونية الرائجة:
في كلتا المخططَين الزمنيَين أعلاه، يتغيّر العنصر الأكبر أثناء تحميل المحتوى. في المثال الأول، تتم إضافة محتوى جديد إلى DOM، ما يؤدي إلى تغيير العنصر الأكبر. في المثال الثاني، يتغيّر التصميم وتتم إزالة المحتوى الذي كان أكبر حجمًا سابقًا من إطار العرض.
على الرغم من أنّ المحتوى الذي يتم تحميله ببطء يكون غالبًا أكبر من المحتوى المعروض على الصفحة، إلا أنّ هذا ليس صحيحًا دائمًا. يعرض المثالان التاليان حدوث LCP قبل تحميل الصفحة بالكامل.
في المثال الأول، يتم تحميل شعار Instagram في وقت مبكر نسبيًا ويظل أكبر عنصر حتى مع عرض المحتوى الآخر تدريجيًا. في مثال صفحة نتائج "بحث Google"، يكون العنصر الأكبر هو فقرة نصية يتم عرضها قبل انتهاء تحميل أي من الصور أو الشعار. وبما أنّ جميع الصور الفردية أصغر من هذه الفقرة، تظل هي العنصر الأكبر طوال عملية التحميل.
كيفية قياس LCP
يمكن قياس LCP في المختبر أو في الميدان، وهو متاح في الأدوات التالية:
أدوات الحقل
- تقرير تجربة المستخدم على Chrome
- PageSpeed Insights
- Search Console (تقرير "مؤشرات أداء الويب الأساسية")
web-vitals
مكتبة JavaScript
أدوات المختبر
قياس LCP في JavaScript
لقياس سرعة عرض أكبر محتوى مرئي (LCP) في JavaScript، يمكنك استخدام Largest Contentful Paint API. يوضّح المثال التالي كيفية إنشاء PerformanceObserver
يستمع إلى إدخالات largest-contentful-paint
ويُسجّلها في وحدة التحكّم.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
في المثال أعلاه، يمثّل كل إدخال largest-contentful-paint
مسجّل العنصر المُحتمَل الحالي لقياس LCP. بشكل عام، تكون قيمة startTime
للقيمة الأخيرة التي تمّ عرضها هي قيمة LCP، ولكنّ هذا ليس صحيحًا دائمًا. ليست كل إدخالات largest-contentful-paint
صالحة لقياس LCP.
يسرد القسم التالي الاختلافات بين ما تُبلغ عنه واجهة برمجة التطبيقات وكيفية احتساب المقياس.
الاختلافات بين المقياس وواجهة برمجة التطبيقات
- ستُرسِل واجهة برمجة التطبيقات
largest-contentful-paint
إدخالًا للصفحات التي يتم تحميلها في علامة تبويب في الخلفية، ولكن يجب تجاهل هذه الصفحات عند احتساب LCP. - ستستمر واجهة برمجة التطبيقات في إرسال إدخالات
largest-contentful-paint
بعد نقل الصفحة إلى الخلفية، ولكن يجب تجاهل هذه الإدخالات عند احتساب LCP (لا يمكن أخذ العناصر في الاعتبار إلا إذا كانت الصفحة في المقدّمة طوال الوقت). - لا تسجّل واجهة برمجة التطبيقات إدخالات
largest-contentful-paint
عند استعادة الصفحة من ذاكرة التخزين المؤقت للرجوع/التقديم، ولكن يجب قياس سرعة عرض أكبر جزء من المحتوى على الصفحة في هذه الحالات لأنّ المستخدمين يواجهونها كزيارات صفحة مختلفة. - لا تأخذ واجهة برمجة التطبيقات في الاعتبار العناصر ضمن إطارات iframe، ولكنّ المقياس يأخذها في الاعتبار لأنّها جزء من تجربة المستخدم للصفحة. في الصفحات التي تتضمّن عنصر LCP ضمن إطار iframe، مثل صورة ملصق على فيديو مضمّن، سيظهر ذلك كاختلاف بين CrUX وRUM. ويجب أخذها في الاعتبار لقياس LCP بشكل صحيح. يمكن للإطارات الفرعية استخدام واجهة برمجة التطبيقات للإبلاغ عن إدخالات
largest-contentful-paint
إلى الإطار الرئيسي للتجميع. - تقيس واجهة برمجة التطبيقات مقياس LCP من بداية التنقّل، ولكن بالنسبة إلى الصفحات التي تمّ عرضها مسبقًا، يجب قياس مقياس LCP من
activationStart
لأنّ ذلك يتوافق مع وقت LCP الذي يراه المستخدم.
بدلاً من حفظ كل هذه الاختلافات الدقيقة، يمكن للمطوّرين استخدام web-vitals
مكتبة JavaScript لقياس LCP، والتي تتعامل مع هذه الاختلافات نيابةً عنك (حيثما أمكن، مع العلم أنّه لا يتمّ تناول مشكلة iframe):
import {onLCP} from 'web-vitals';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
يمكنك الرجوع إلى رمز المصدر onLCP()
للحصول على مثال كامل حول كيفية قياس LCP في JavaScript.
ماذا لو لم يكن العنصر الأكبر هو الأكثر أهمية؟
في بعض الحالات، لا يكون العنصر (أو العناصر) الأكثر أهمية في الصفحة هو نفسه العنصر الأكبر حجمًا، وقد يكون المطوّرون مهتمين أكثر بقياس أوقات عرض هذه العناصر الأخرى بدلاً من ذلك. يمكن إجراء ذلك باستخدام Element Timing API، كما هو موضّح في المقالة حول المقاييس المخصّصة.
كيفية تحسين سرعة LCP
يتوفّر دليل كامل حول تحسين سرعة عرض أكبر محتوى مرئي (LCP) لإرشادك خلال عملية تحديد أوقات LCP في الميدان واستخدام بيانات المختبر للتوغّل فيها وتحسينها.
مراجع إضافية
- الدروس المستفادة من مراقبة الأداء في Chrome بقلم آني سوليفان على performance.now() (2019)
سجلّ التغييرات
في بعض الأحيان، يتم اكتشاف أخطاء في واجهات برمجة التطبيقات المستخدَمة لقياس المقاييس، وفي بعض الأحيان في تعريفات المقاييس نفسها. ونتيجةً لذلك، يجب إجراء تغييرات في بعض الأحيان، ويمكن أن تظهر هذه التغييرات كتحسينات أو تراجعات في التقارير ولوحات البيانات الداخلية.
لمساعدتك في إدارة ذلك، سيتم عرض جميع التغييرات التي تطرأ على تنفيذ هذه المقاييس أو تعريفها في سجلّ التغييرات هذا.
إذا كانت لديك ملاحظات حول هذه المقاييس، يمكنك تقديمها في مجموعة web-vitals-feedback على Google.