از لحاظ تاریخی، اندازهگیری سرعت بارگیری محتوای اصلی یک صفحه وب و مشاهده آن برای کاربران، برای توسعهدهندگان وب یک چالش بوده است. معیارهای قدیمی تر مانند بار یا DOMContentLoaded به خوبی کار نمی کنند زیرا لزوماً با آنچه کاربر در صفحه خود می بیند مطابقت ندارند. و معیارهای عملکرد کاربر محور جدیدتر مانند First Contentful Paint (FCP) تنها شروع تجربه بارگیری را نشان می دهد. اگر صفحه ای یک صفحه نمایش اسپلش نشان می دهد یا نشانگر بارگذاری را نشان می دهد، این لحظه چندان به کاربر مربوط نمی شود.
در گذشته، ما معیارهای عملکردی مانند First Meaningful Paint (FMP) و Speed Index (SI) (هر دو در Lighthouse موجود هستند) را برای کمک به ثبت بیشتر تجربه بارگیری پس از رنگآمیزی اولیه توصیه میکردیم، اما این معیارها پیچیده هستند و به سختی قابل مشاهده هستند. توضیح دهید، و اغلب اشتباه است - به این معنی که آنها هنوز تشخیص نمی دهند که محتوای اصلی صفحه چه زمانی بارگذاری شده است.
بر اساس بحثهای گروه کاری W3C Web Performance و تحقیقات انجامشده در Google، ما دریافتیم که روش دقیقتری برای اندازهگیری زمانی که محتوای اصلی یک صفحه بارگذاری میشود این است که ببینیم چه زمانی بزرگترین عنصر ارائه شده است.
LCP چیست؟
LCP زمان رندر بزرگترین تصویر یا بلوک متن قابل مشاهده در ویوپورت را نسبت به زمانی که کاربر برای اولین بار به صفحه پیمایش کرده است، گزارش می دهد.
نمره LCP خوب چیست؟
برای ارائه یک تجربه کاربری خوب، سایت ها باید تلاش کنند تا بزرگترین رنگ محتوای 2.5 ثانیه یا کمتر را داشته باشند. برای اطمینان از رسیدن به این هدف برای اکثر کاربران خود، یک آستانه خوب برای اندازه گیری صدک 75 بارگذاری صفحه است که در دستگاه های تلفن همراه و دسکتاپ تقسیم بندی شده است.
چه عناصری در نظر گرفته می شود؟
همانطور که در حال حاضر در Largest Contentful Paint API مشخص شده است، انواع عناصر در نظر گرفته شده برای Largest Contentful Paint عبارتند از:
- عناصر
<img>
( زمان ارائه فریم اول برای محتوای متحرک مانند GIF یا PNG متحرک استفاده می شود) - عناصر
<image>
درون یک عنصر<svg>
- عناصر
<video>
(زمان بارگذاری تصویر پوستر یا زمان ارائه اولین فریم برای ویدیوها استفاده می شود - هر کدام زودتر باشد) - یک عنصر با یک تصویر پسزمینه که با استفاده از تابع
url()
بارگذاری شده است، (برخلاف یک گرادیان CSS ) - عناصر سطح بلوک حاوی گره های متنی یا دیگر عناصر متنی در سطح درون خطی.
توجه داشته باشید که محدود کردن عناصر به این مجموعه محدود به منظور ساده نگه داشتن کارها در ابتدا عمدی بود. عناصر اضافی (مانند پشتیبانی کامل <svg>
) ممکن است در آینده با تحقیقات بیشتر اضافه شوند.
اندازهگیریهای LCP علاوه بر در نظر گرفتن تنها برخی از عناصر، از اکتشافی برای حذف عناصر خاصی استفاده میکنند که کاربران احتمالاً آنها را «غیر محتوا» میدانند. برای مرورگرهای مبتنی بر Chromium، این موارد عبارتند از:
- عناصری با کدورت 0 که برای کاربر نامرئی هستند
- عناصری که نمای کامل را پوشش می دهند و احتمالاً به جای محتوا به عنوان پس زمینه در نظر گرفته می شوند
- تصاویر مکاننما یا سایر تصاویر با آنتروپی کم، که احتمالاً محتوای واقعی صفحه را منعکس نمیکنند.
مرورگرها احتمالاً به بهبود این اکتشافیها ادامه میدهند تا اطمینان حاصل کنند که انتظارات کاربر را از بزرگترین عنصر محتوایی مطابقت میدهیم.
این اکتشافیهای «محتوا» ممکن است با موارد استفاده شده توسط First Contentful Paint (FCP) متفاوت باشد، که ممکن است برخی از این عناصر، مانند تصاویر مکاننما یا تصاویر نمای کامل را در نظر بگیرد، حتی اگر برای کاندید LCP واجد شرایط نباشند. علیرغم اینکه هر دو از "محتوا" در نام خود استفاده می کنند، هدف این معیارها متفاوت است. FCP زمانی که هر محتوایی روی صفحه نمایش داده می شود و LCP زمانی که محتوای اصلی رنگ می شود اندازه گیری می کند، بنابراین 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
هستند، نمایش داده نمی شود. درعوض، فقط زمان بارگذاری آنها در معرض دید قرار میگیرد (زیرا این از قبل از طریق بسیاری از APIهای وب دیگر در معرض دید قرار گرفته است).
این می تواند منجر به وضعیت به ظاهر غیرممکن شود که در آن LCP توسط API های وب زودتر از FCP گزارش می شود. این مورد نیست، بلکه فقط به دلیل این محدودیت امنیتی ظاهر می شود.
در صورت امکان، همیشه توصیه میشود هدر Timing-Allow-Origin
را تنظیم کنید تا معیارهای شما دقیقتر باشد.
چیدمان عناصر و تغییرات اندازه چگونه مدیریت می شوند؟
برای پایین نگه داشتن سربار عملکرد محاسبه و ارسال ورودی های عملکرد جدید، تغییرات در اندازه یا موقعیت یک عنصر، نامزدهای LCP جدیدی ایجاد نمی کند. فقط اندازه و موقعیت اولیه عنصر در نمای در نظر گرفته می شود.
این بدان معنی است که تصاویری که ابتدا خارج از صفحه نمایش داده می شوند و سپس انتقال روی صفحه نمایش داده می شوند، ممکن است گزارش نشوند. همچنین به این معنی است که عناصری که ابتدا در viewport رندر شدهاند و سپس به پایین فشار داده میشوند، خارج از دید همچنان اندازه اولیه خود را گزارش میکنند.
مثال ها
در اینجا چند نمونه از زمانی که بزرگترین رنگ محتوایی در چند وب سایت محبوب رخ می دهد آورده شده است:
در هر دو جدول زمانی بالا، بزرگترین عنصر با بارگیری محتوا تغییر می کند. در مثال اول، محتوای جدیدی به DOM اضافه میشود و عنصری که بزرگترین است را تغییر میدهد. در مثال دوم، طرحبندی تغییر میکند و محتوایی که قبلاً بزرگترین بود از viewport حذف میشود.
در حالی که غالباً محتوایی که دیر بارگذاری می شود بزرگتر از محتوای موجود در صفحه است، لزوماً اینطور نیست. دو مثال بعدی LCP را قبل از بارگیری کامل صفحه نشان می دهد.
در مثال اول، لوگوی اینستاگرام نسبتاً زود بارگذاری می شود و حتی با نمایش تدریجی سایر محتواها، بزرگترین عنصر باقی می ماند. در مثال صفحه نتایج جستجوی گوگل، بزرگترین عنصر پاراگراف متنی است که قبل از بارگیری هر یک از تصاویر یا لوگو نمایش داده می شود. از آنجایی که همه تصاویر منفرد کوچکتر از این پاراگراف هستند، بزرگترین عنصر در طول فرآیند بارگذاری باقی می ماند.
نحوه اندازه گیری LCP
LCP را می توان در آزمایشگاه یا میدان اندازه گیری کرد و در ابزارهای زیر موجود است:
ابزارهای میدانی
- گزارش تجربه کاربر Chrome
- PageSpeed Insights
- کنسول جستجو (گزارش Core Web Vitals)
- کتابخانه جاوا اسکریپت
web-vitals
ابزار آزمایشگاهی
اندازه گیری LCP در جاوا اسکریپت
برای اندازهگیری LCP در جاوا اسکریپت، میتوانید از 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 معتبر نیستند.
بخش زیر تفاوتهای بین آنچه API گزارش میکند و نحوه محاسبه متریک را فهرست میکند.
تفاوت بین متریک و API
- API
largest-contentful-paint
برای صفحات بارگیری شده در یک برگه پسزمینه ارسال میکند، اما این صفحات باید هنگام محاسبه LCP نادیده گرفته شوند. - API پس از پسزمینهسازی صفحه، به ارسال ورودیهای
largest-contentful-paint
ادامه میدهد، اما این ورودیها باید هنگام محاسبه LCP نادیده گرفته شوند (ممکن است عناصر فقط در صورتی در نظر گرفته شوند که صفحه تمام مدت در پیشزمینه باشد). - وقتی صفحه از حافظه پنهان عقب/ جلو بازیابی میشود، API ورودیهای
largest-contentful-paint
گزارش نمیکند، اما LCP باید در این موارد اندازهگیری شود، زیرا کاربران آنها را بهعنوان بازدید از صفحه مجزا تجربه میکنند. - API عناصر داخل iframe را در نظر نمی گیرد، اما معیارها به عنوان بخشی از تجربه کاربر از صفحه هستند. در صفحات دارای LCP در iframe - برای مثال یک تصویر پوستر در یک ویدیوی جاسازی شده - این به عنوان تفاوت بین CrUX و RUM نشان داده می شود. برای اندازه گیری صحیح LCP باید آنها را در نظر بگیرید. فریمهای فرعی میتوانند از API استفاده کنند تا
largest-contentful-paint
خود را برای جمعآوری به فریم اصلی گزارش دهند. - API LCP را از شروع ناوبری اندازه گیری می کند، اما برای صفحات از قبل اجرا شده LCP باید از
activationStart
اندازه گیری شود زیرا با زمان LCP مطابق با تجربه کاربر مطابقت دارد.
توسعهدهندگان میتوانند بهجای حفظ کردن همه این تفاوتهای ظریف، از کتابخانه JavaScript web-vitals
برای اندازهگیری LCP استفاده کنند، که این تفاوتها را برای شما مدیریت میکند (در صورت امکان، توجه داشته باشید که مشکل iframe پوشش داده نشده است):
import {onLCP} from 'web-vitals';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
برای مثال کاملی از نحوه اندازه گیری LCP در جاوا اسکریپت به کد منبع onLCP()
مراجعه کنید.
اگر بزرگترین عنصر مهم ترین نباشد چه؟
در برخی موارد مهم ترین عنصر (یا عناصر) در صفحه با بزرگترین عنصر یکسان نیست و توسعه دهندگان ممکن است به جای آن بیشتر به اندازه گیری زمان رندر این عناصر دیگر علاقه مند باشند. همانطور که در مقاله معیارهای سفارشی توضیح داده شده است، با استفاده از Element Timing API امکان پذیر است.
نحوه بهبود LCP
یک راهنمای کامل در مورد بهینهسازی LCP در دسترس است تا شما را در فرآیند شناسایی زمانبندی LCP در میدان و استفاده از دادههای آزمایشگاهی برای بررسی و بهینهسازی آنها راهنمایی کند.
منابع اضافی
تغییرات
گاهی اوقات، اشکالاتی در APIهای مورد استفاده برای اندازه گیری معیارها و گاهی اوقات در تعاریف خود معیارها کشف می شود. در نتیجه، گاهی اوقات باید تغییراتی ایجاد شود، و این تغییرات میتواند به صورت بهبود یا پسرفت در گزارشهای داخلی و داشبورد شما نشان داده شود.
برای کمک به شما در مدیریت این موضوع، همه تغییرات در اجرا یا تعریف این معیارها در این Changelog ظاهر میشود.
اگر بازخوردی برای این معیارها دارید، میتوانید آن را در گروه web-vitals-feedback Google ارائه کنید.