في السابق، كان من الصعب على مطوّري الويب قياس سرعة ظهور المحتوى الرئيسي لصفحة الويب للمستخدمين. لا تعمل المقاييس القديمة، مثل load أو DOMContentLoaded، بشكلٍ جيد لأنّها لا تتوافق بالضرورة مع ما يراه المستخدم على شاشته. أمّا مقاييس الأداء الجديدة التي تركّز على المستخدم، مثل سرعة عرض المحتوى على الصفحة (FCP)، فلا ترصد سوى بداية تجربة التحميل. إذا كانت الصفحة تعرض شاشة البداية أو مؤشر التحميل، لن تكون هذه اللحظة ملائمة جدًا للمستخدم.
في السابق، كنا نقترح مقاييس الأداء، مثل سرعة عرض أول محتوى مرئي (FMP) ومؤشر السرعة (SI) (كلاهما متاح في Lighthouse) للمساعدة في رصد المزيد من تجربة التحميل بعد عرض الصفحة للمرة الأولى، ولكنّ هذه المقاييس معقّدة ويصعب شرحها وغالبًا ما تكون خاطئة، ما يعني أنّها لا تزال لا تحدّد وقت تحميل المحتوى الرئيسي للصفحة.
استنادًا إلى المناقشات التي جرت في مجموعة عمل الويب W3C والأبحاث التي تم إجراؤها في Google، تبيَّن لنا أنّ الطريقة الأكثر دقة لقياس وقت تحميل المحتوى الرئيسي للصفحة هي النظر في وقت عرض العنصر الأكبر.
ما هو مقياس LCP؟
يشير مقياس LCP إلى الوقت الذي تستغرقه أكبر صورة أو مقطع نصي أو فيديو للظهور ضمن إطار العرض مقارنةً بالوقت الذي انتقل فيه المستخدم إلى الصفحة لأول مرة.
ما هي نتيجة LCP الجيدة؟
لتقديم تجربة جيدة للمستخدم، يجب أن تسعى المواقع الإلكترونية إلى أن تكون سرعة عرض أكبر محتوى مرئي 2.5 ثانية أو أقل. لضمان تحقيق هذا المستهدف لمعظم المستخدمين، يمكنك قياس الشريحة المئوية الخامسة والسبعين من عمليات تحميل الصفحات، مقسّمة على الأجهزة الجوّالة وأجهزة الكمبيوتر المكتبي.
ما العناصر التي يتم اعتبارها؟
وفقًا لما هو محدّد حاليًا في واجهة برمجة تطبيقات "سرعة عرض أكبر محتوى مرئي"، إنّ أنواع العناصر التي يتم اعتبارها "سرعة عرض أكبر محتوى مرئي" هي:
<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 في المختبر أو في الميدان، وهو متاح في الأدوات التالية:
أدوات الحقل
- تقرير تجربة المستخدم على 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
عند استعادة الصفحة من ذاكرة التخزين المؤقت للرجوع/التقديم، ولكن يجب قياس LCP في هذه الحالات لأنّ المستخدمين يواجهونها كزيارات صفحة مختلفة. - لا تأخذ واجهة برمجة التطبيقات في الاعتبار العناصر ضمن إطارات iframe، لكنّ المقياس يأخذها في الاعتبار لأنّها جزء من تجربة المستخدم على الصفحة. في الصفحات التي تتضمّن عنصر LCP ضمن إطار iframe، مثل صورة ملصق على فيديو مضمّن، سيظهر ذلك كاختلاف بين CrUX وRUM. ويجب أخذها في الاعتبار لقياس LCP بشكل صحيح. يمكن للإطارات الفرعية استخدام واجهة برمجة التطبيقات للإبلاغ عن إدخالات
largest-contentful-paint
إلى الإطار الرئيسي للتجميع. - تقيس واجهة برمجة التطبيقات سرعة عرض أكبر محتوى مرئي (LCP) من بدء التنقّل، ولكن بالنسبة إلى الصفحات المعروضة مُسبقًا، يجب قياس LCP من
activationStart
بما يتوافق مع وقت سرعة عرض أكبر جزء من المحتوى على النحو الذي يراه المستخدم.
بدلاً من حفظ كل هذه الاختلافات الدقيقة، يمكن للمطوّرين استخدام 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)
سجلّ التغييرات
من حين لآخر، يتم اكتشاف أخطاء في واجهات برمجة التطبيقات المستخدمة لقياس المقاييس، وأحيانًا في تعريفات المقاييس نفسها. ونتيجةً لذلك، يجب إجراء تغييرات في بعض الأحيان، ويمكن أن تظهر هذه التغييرات كتحسينات أو تراجعات في التقارير ولوحات البيانات الداخلية.
لمساعدتك على إدارة هذه المقاييس، سيتم عرض جميع التغييرات التي تطرأ على تنفيذ هذه المقاييس أو تعريفها في سجلّ التغييرات هذا.
إذا كانت لديك ملاحظات بشأن هذه المقاييس، يمكنك تقديمها في مجموعة Google الخاصة بملاحظات مؤشرات أداء الويب.