یکی از مباحث مهم در افزایش سرعت وب سایت LCP یا Largest Contentful Paint می باشد که ما در این مقاله سعی کردیم این مبحث را به ساده ترین شکل به شما توضیح دهیم ولی همچنان ممکن است فهم این مباحث دشوار باشد و نیاز به داشتن تخصص در این زمینه دارد. اگر تخصص کافی برای افزایش سرعت سایت خود را ندارید به شما پیشنهاد می کنیم که خدمات بهینه سازی سرعت سایت خود را به تیم حرفه ای ما بسپارید و با نازلترین قیمت در زمان خود صرفه جویی کرده و سرعت لود سایت خود را به زیر 2 ثانیه برسانید.
همیشه، اندازهگیری سرعت لود شدن محتوای اصلی یک صفحه وب و قابل مشاهده بودن آن برای کاربران، برای توسعهدهندگان وب چالشبرانگیز بوده است. معیارهای قدیمیتر مانند load یا DOMContentLoaded خیلی خوب عمل نمیکنند چون لزوماً با آنچه کاربر روی صفحه میبیند، همخوانی ندارند. همچنین، معیارهای جدیدتر و متمرکز بر کاربر مانند First Contentful Paint (FCP) فقط ابتدای لود صفحه را ثبت میکنند.
در گذشته، ما معیارهایی مانند First Meaningful Paint (FMP) و Speed Index (SI) را پیشنهاد میکردیم (هر دو در Lighthouse موجود هستند) تا سرعت لود بیشتری را پس از اولین نمایش محتوا ثبت کنند، اما این معیارهای پیچیده، سخت توضیح داده میشوند و اغلب نادرست هستند—یعنی هنوز نمیتوانند تشخیص دهند که محتوای اصلی صفحه چه زمانی لود شده است.
بر اساس بحثهای گروه کاری عملکرد وب W3C و تحقیقات انجام شده در گوگل، یک راه دقیقتر برای اندازهگیری زمانی که محتوای اصلی صفحه لود شده است، توجه به زمان نمایش بزرگترین المان صفحه است.
LCP چیست؟
LCP زمان نمایش بزرگترین تصویر یا بلوک متن قابل مشاهده در viewport را نسبت به زمانی که کاربر اولین بار به صفحه هدایت شده است گزارش میدهد.
نکته کلیدی: توجه داشته باشید که LCP شامل زمانی که صفحه قبلی ترک شده، زمان برقراری اتصال، زمان هدایت و Time To First Byte (TTFB) میشود که میتواند هنگام اندازهگیری مورد توجه باشد.
یک امتیاز LCP خوب چقدر است؟
برای ارائه تجربه کاربری خوب، سایتها باید تلاش کنند تا زمان Largest Contentful Paint زیر 2.5 ثانیه باشد. این آمار باید در حدود 75 درصد لودهای صفحه در گوشی موبایل و دسکتاپ باشد. امتیازهای خوب LCP زیر 2.5 ثانیه هستند، امتیازهای ضعیف بیشتر از 4.0 ثانیه هستند و هر چیزی بین این دو نیاز به بهبود دارد.
چه المانهایی در نظر گرفته میشوند؟
همانطور که در API Largest Contentful Paint مشخص شده است، انواع المانهایی که برای Largest Contentful Paint در نظر گرفته میشوند عبارتند از:
عناصر <img> (زمان نمایش اولین فریم برای محتوای متحرک مانند GIFها یا PNGهای متحرک استفاده میشود)
المان های <image> درون عنصر <svg>
عناصر <video> (زمان بارگذاری تصویر کاور ویدیو یا زمان نمایش اولین فریم برای ویدیوها—هر کدام زودتر باشد)
یک المان با تصویر بک گراند لود شده در حالی که از تابع url() استفاده می کند.
علاوه بر در نظر گرفتن این المانها، اندازهگیریهای LCP از روشهای تجربی برای حذف المانهایی که کاربران احتمالاً آنها را به عنوان “non-contentful” میبینند، استفاده میکنند. برای مرورگرهای مبتنی بر کرومیوم، این شامل موارد زیر میشود:
المانهایی با شفافیت 0، که برای کاربر نامرئی هستند.
المانهایی که کل viewport را پوشش میدهند، که احتمالاً به عنوان پسزمینه در نظر گرفته میشوند.
تصاویر جایگزین یا تصاویر دیگری با پیچیدگی کم، که احتمالاً محتوای واقعی صفحه را نشان نمیدهند.
مرورگرها احتمالاً به بهبود این روشها ادامه خواهند داد تا مطمئن شوند که با انتظارات کاربر از آنچه بزرگترین المان محتوایی است مطابقت داشته باشند.
این روشهای “Contentful” ممکن است با آنچه First Contentful Paint (FCP) استفاده میکند متفاوت باشد، که ممکن است برخی از این المانها را در نظر بگیرد، مانند تصاویر جایگزین یا تصاویر تمام صفحه، حتی اگر آنها به عنوان نامزدهای LCP واجد شرایط نباشند. با وجود اینکه هر دو از واژه “Contentful” در نام خود استفاده میکنند، هدف این پارامترها متفاوت است. FCP زمانی را اندازهگیری میکند که اولین المان در صفحه نمایش داده میشود و LCP زمانی را که محتوای اصلی نمایش داده میشود، بنابراین LCP قصد دارد گزینشیتر باشد.
اندازه یک المان چگونه تعیین میشود؟
اندازه المانی که برای LCP گزارش میشود، معمولاً اندازهای است که برای کاربر در viewport قابل مشاهده است. اگر المان از viewport خارج شود، یا اگر بخشی از المان بریده شده یا دارای overflow غیرقابل مشاهده باشد، آن بخشها در اندازه المان حساب نمیشوند.
برای المانهای تصویری که از اندازه اصلی خود تغییر اندازه داده شدهاند، اندازهای که گزارش میشود یا اندازه قابل مشاهده است یا اندازه اصلی تصویر، هر کدام که کوچکتر باشد.
برای المانهای متنی، LCP فقط کوچکترین مستطیلی را در نظر میگیرد که میتواند همه نودهای متنی را دربر بگیرد.
برای همه المانها LCP، حاشیهها، فاصلهها یا حاشیههای اعمال شده با استفاده از CSS را در نظر نمیگیرد.
توجه: تعیین اینکه کدام نودهای متنی به کدام المانها تعلق دارند، گاهی اوقات میتواند دشوار باشد، به خصوص برای المانهایی که فرزندان آنها شامل عناصر inline و نودهای متنی ساده اما همچنین المانهای بلوکی هستند. نکته کلیدی این است که هر نود متنی به و فقط به نزدیکترین المان بلوکی مادر خود تعلق دارد.
LCP چه زمانی گزارش میشود؟
صفحات وب اغلب در مراحل مختلف لود میشوند و در نتیجه، ممکن است بزرگترین المان در صفحه تغییر کند.
برای مدیریت این احتمال تغییر، مرورگر یک PerformanceEntry از نوع largest-contentful-paint را بلافاصله پس از نمایش اولین فریم ارسال میکند که بزرگترین المان محتوایی را شناسایی میکند. اما سپس، پس از نمایش فریمهای بعدی، هر زمان که بزرگترین المان محتوایی تغییر کند، یک PerformanceEntry دیگر ارسال میکند.
برای مثال، در یک صفحه با متن و یک تصویر بزرگ، مرورگر ممکن است ابتدا فقط متن را نمایش دهد—در این حالت مرورگر یک ورودی largest-contentful-paint ارسال میکند که احتمالاً خاصیت element آن به یک <p> یا <h1> اشاره میکند. بعداً، وقتی تصویر بزرگ تمام میشود، یک ورودی دوم largest-contentful-paint ارسال میشود و خاصیت element آن به <img> اشاره میکند.
یک المان تنها پس از نمایش و قابل مشاهده بودن برای کاربر میتواند به عنوان بزرگترین المان محتوایی در نظر گرفته شود. تصاویری که هنوز لود نشدهاند به عنوان “نمایش داده شده” در نظر گرفته نمیشوند. همچنین نودهای متنی که از فونتهای وب استفاده میکنند نیز به حساب نمیآیند. در چنین مواردی، ممکن است یک المان کوچکتر به عنوان بزرگترین المان محتوایی گزارش شود، اما به محض اینکه المان بزرگتر نمایش داده شود، یک PerformanceEntry دیگر ایجاد میشود.
علاوه بر تصاویر و فونتهای lazy load شده، ممکن است صفحه المانهای جدیدی به DOM اضافه کند که محتوای جدید در دسترس میشود. اگر هر یک از این المانهای جدید بزرگتر از المان محتوایی قبلی باشد، یک PerformanceEntry جدید نیز گزارش میشود.
اگر بزرگترین المان محتوایی از viewport، یا حتی از DOM حذف شود، همچنان به عنوان بزرگترین المان محتوایی باقی میماند مگر اینکه یک المان بزرگتر نمایش داده شود.
توجه: قبل از Chrome 88، المانهای حذف شده به عنوان بزرگترین المانهای محتوایی در نظر گرفته نمیشدند و حذف کاندید فعلی یک ورودی جدید largest-contentful-paint را ارسال میکرد. با این حال، به دلیل الگوهای محبوب UI مانند کاروسلهای تصویر که اغلب المانهای DOM را حذف میکردند، پارامتر به روز شد تا دقیقتر آنچه کاربران تجربه میکنند را بازتاب دهد.
مرورگر پس از اولین تعامل کاربر با صفحه (از طریق ضربه، اسکرول یا فشردن کلید)، گزارش ورودیهای جدید را متوقف میکند، زیرا تعامل کاربر اغلب چیزی که به کاربر قابل مشاهده است را تغییر میدهد (که مخصوصاً با اسکرول).
برای اهداف تحلیلی، شما باید فقط آخرین ورودی PerformanceEntry ارسال شده را به سرویس تحلیلی خود گزارش دهید.
هشدار: از آنجا که کاربران میتوانند صفحات را در یک تب پسزمینه باز کنند، ممکن است ورودیهای largest-contentful-paint تا زمانی که کاربر تب را کلیک نکند، ارسال نشوند که میتواند خیلی دیرتر از زمانی باشد که آنها اولین بار آن را لود کردند. ابزارهای گوگل که LCP را اندازهگیری میکنند این پارامتر را گزارش نمیکنند اگر صفحه در پسزمینه لود شده باشد، زیرا این زمان لود ادراک شده توسط کاربر را بازتاب نمیدهد.
این میتواند به وضعیتی منجر شود که به نظر میرسد LCP توسط APIهای وب زودتر از FCP گزارش شده است. اینطور نیست اما فقط به دلیل این محدودیت امنیتی به این شکل به نظر میرسد.
هر زمان ممکن باشد، همیشه توصیه میشود هدر Timing-Allow-Origin را تنظیم کنید، تا پارامترهای شما دقیقتر باشند.
تغییرات چیدمان و اندازه المان چگونه مدیریت میشوند؟
برای نگه داشتن سربار عملکرد محاسبه و ارسال ورودیهای جدید کم، تغییرات در اندازه یا موقعیت یک المان، نامزدهای جدید LCP تولید نمیکنند. تنها اندازه و موقعیت اولیه المان در viewport در نظر گرفته میشود.
این به این معنی است که تصاویری که ابتدا خارج از صفحه نمایش داده میشوند و سپس به روی صفحه انتقال مییابند ممکن است گزارش نشوند. همچنین به این معنی است که المانهایی که ابتدا در viewport نمایش داده میشوند و سپس به پایین، خارج از دید، منتقل میشوند، همچنان اندازه اولیه خود را در viewport گزارش میکنند.
مثالها در اینجا چند مثال از زمانی که Largest Contentful Paint در چند سایت محبوب رخ میدهد آورده شده است:
خط زمانی Largest Contentful Paint از cnn.com
خط زمانی Largest Contentful Paint از techcrunch.com
در هر دو خط زمانی بالا، بزرگترین المان با لود شدن محتوا تغییر میکند. در مثال اول، محتوای جدید به DOM اضافه میشود و آنچه که بزرگترین المان است را تغییر میدهد. در مثال دوم، چیدمان تغییر میکند و محتوایی که قبلاً بزرگترین بود از viewport حذف میشود.
در حالی که اغلب موارد، محتوای دیر لود شده بزرگتر از محتوای قبلاً روی صفحه است، همیشه اینطور نیست. دو مثال بعدی نشان میدهند که LCP قبل از لود کامل صفحه رخ میدهد.
خط زمانی Largest Contentful Paint از instagram.com
خط زمانی Largest Contentful Paint از google.com
در مثال اول، لوگوی اینستاگرام نسبتاً زود لود میشود و حتی با نمایش تدریجی محتوای دیگر، همچنان بزرگترین المان باقی میماند. در مثال صفحه نتایج جستجوی گوگل، بزرگترین المان یک پاراگراف متن است که قبل از هر یک از تصاویر یا لوگو به نمایش در میآید. از آنجا که همه تصاویر مجزا کوچکتر از این پاراگراف هستند، در طول فرآیند لود به عنوان بزرگترین المان باقی میماند.
توجه: در اولین فریم خط زمانی اینستاگرام، ممکن است متوجه شوید که لوگوی دوربین دارای یک جعبه سبز نیست. این به این دلیل است که یک المان <svg> است و المانهای <svg> در حال حاضر به عنوان نامزدهای LCP در نظر گرفته نمیشوند. اولین نامزد LCP متن در فریم دوم است.
چگونه LCP را اندازهگیری کنیم؟
LCP را میتوان دردر ابزارهای زیر اندازه گیری کرد:
Chrome User Experience Report PageSpeed Insights Search Console (گزارش Core Web Vitals) کتابخانه جاوا اسکریپت web-vitals
برای اندازهگیری LCP (Largest Contentful Paint) در JavaScript، میتوان از Largest Contentful Paint API استفاده کرد. در مثال زیر نشان داده شده است که چگونه میتوان با استفاده از یک PerformanceObserver، رویدادهای مرتبط با LCP را شنود کرده و در کنسول نمایش داد.
هشدار: این کد نشان میدهد که چگونه ورودیهای largest-contentful-paint را در کنسول لاگ کنید، اما اندازهگیری LCP در جاوا اسکریپت پیچیدهتر است.
در مثال بالا، هر ورودی مرتبط با LCP نشاندهنده کاندیدای فعلی LCP است. بهطور کلی، مقدار startTime آخرین ورودی، معمولاً مقدار واقعی LCP است، اما این همیشه صدق نمیکند. همه رویدادهای LCP معتبر نیستند و برای اندازهگیری LCP باید شرایط خاصی را در نظر گرفت.
تفاوتهای Metric و API:
تبهای پسزمینه (Background Tabs): API برای صفحاتی که در تبهای پسزمینه بارگذاری میشوند نیز رویداد LCP ارسال میکند، اما این صفحات نباید برای محاسبه LCP در نظر گرفته شوند.
فعالیت در پسزمینه: حتی پس از رفتن صفحه به پسزمینه، API همچنان رویدادهای LCP ارسال میکند، اما فقط رویدادهایی معتبر هستند که صفحه در تمام مدت در پیشزمینه بوده باشد.
Back/Forward Cache: هنگام بازگردانی صفحه از این نوع کش، API رویداد LCP ارسال نمیکند، اما باید LCP برای این موارد محاسبه شود چون کاربران آن را بهعنوان بازدیدی جداگانه تجربه میکنند.
Iframeها: API محتوای داخل iframeها را در نظر نمیگیرد، اما از آنجا که این عناصر بخشی از تجربه کاربری صفحه هستند، باید هنگام اندازهگیری LCP لحاظ شوند. برای صفحات دارای LCP در داخل iframe (مثل تصویر کاور یک ویدیو)، این مورد میتواند اختلافی بین دادههای CrUX و RUM ایجاد کند. برای اندازهگیری دقیق LCP، باید iframeها را به حساب آورد.
صفحات Prerendered: API LCP را از navigation start اندازهگیری میکند، اما برای صفحات prerendered باید از activationStart محاسبه شود که نشاندهنده زمان تجربهشده توسط کاربر است.
ابزارهای سادهتر برای توسعهدهندگان:
بهجای تلاش برای مدیریت این تفاوتها، میتوان از کتابخانه web-vitals استفاده کرد که این تفاوتها را تا حد ممکن مدیریت میکند (اگرچه مشکل iframeها را پوشش نمیدهد):
import {onLCP} from'web-vitals';
// اندازهگیری و نمایش LCP بهمحض در دسترس بودن onLCP(console.log);
برای مشاهده کد کامل onLCP و نحوه عملکرد آن، میتوانید به سورس کد مربوطه مراجعه کنید.
محدودیتها:
در برخی موارد، مثل iframeهای با منبع متفاوت (Cross-Origin Iframes)، اندازهگیری LCP با JavaScript ممکن نیست. برای جزئیات بیشتر، بخش محدودیتهای کتابخانه web-vitals را بررسی کنید.
وقتی بزرگترین عنصر مهمترین عنصر نیست:
در برخی مواقع، ممکن است مهمترین عنصر یا عناصر صفحه، بزرگترین عناصر نباشند. برای اندازهگیری زمان رندر این عناصر خاص، میتوان از Element Timing API استفاده کرد. این API به شما اجازه میدهد تا معیارهای سفارشی خود را تعریف کنید.
بهبود LCP:
برای بهبود LCP، میتوانید از یک راهنمای کامل استفاده کنید که شامل شناسایی زمانهای LCP در شرایط واقعی و بهینهسازی آنها با استفاده از دادههای آزمایشگاهی است.
دیدگاه شما