في السابق، كان من الصعب على مطوّري الويب قياس سرعة ظهور المحتوى الرئيسي لصفحة الويب للمستخدمين. لا تعمل المقاييس القديمة، مثل 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 في الاعتبار سوى أصغر مستطيل يمكن أن يحتوي على جميع عقد النص.
بالنسبة إلى جميع العناصر، لا يأخذ مقياس 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
لأنّ ذلك يتوافق مع وقت 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.