تصویر نویسنده

۱۱ مهر ۱۳۹۹

0

Largest Contentful Paint یا LCP چیست؟

مقاله

Largest Contentful Paint یک معیار مهم و کاربر محور برای اندازه گیری سرعت بارگیری است زیرا وقتی محتوای اصلی صفحه بارگیری می شود، این نقطه را در جدول زمانی بارگیری صفحه نشان می دهد – یک LCP سریع به کاربر اطمینان می دهد که صفحه مفید است.

از نظر تاریخی، اندازه گیری سرعت بارگیری محتوای اصلی یک صفحه وب و قابل مشاهده شدنش برای کاربران برای توسعه دهندگان وب یک چالش بوده است.

معیارهای قدیمی مانند load یا DOMContentLoaded خوب نیستند زیرا لزوماً با آنچه کاربر در صفحه خود می بیند مطابقت ندارند و معیارهای جدیدتر و مبتنی بر عملکرد کاربر مانند First Contentful Paint (FCP) فقط ابتدای تجربه بارگیری را ضبط می کنند. لحظات نشان داده شدن یک اسپلش اسکرین یا یک نشانگر بارگیری در صفحه، چندان به کاربر مربوط نیست.

در گذشته ما معیارهای عملکردی مانند First Meaningful Paint (FMP) وSpeed Index (SI) (هر دو در Lighthouse موجودند) را برای کمک به گرفتن تجربه بارگیری بیشتر پس از رنگ شدن اولیه توصیه کرده ایم، اما توضیح این معیارها پیچیده و اغلب اشتباه است – به این معنی که آنها هنوز هم زمان بارگذاری محتوای اصلی صفحه را تشخیص نمی دهند.

بعضی اوقات ساده تر بودن بهتر است. بر اساس بحث در کارگروه عملکرد وب W3C و تحقیقاتی که در گوگل انجام شده است، متوجه شده ایم که یک روش دقیق تر برای اندازه گیری زمان بارگیری محتوای اصلی یک صفحه، بررسی زمان رندر شدن بزرگترین عنصر است.

Largest Contentful Paint چیست؟

معیار Largest Contentful Paint زمان رندر شدن بزرگترین تصویر یا بلوک متنی را که در ویوپورت قابل مشاهده است گزارش می کند.

بازه نمره های LCP

نمره خوب برای Largest Contentful Paint چند است؟

برای ایجاد یک تجربه کاربری خوب، سایت ها باید تلاش کنند که بزرگترین محتوا در ۲.۵ ثانیه ابتدایی بارگیری صفحه لود شود. یک آستانه مناسب اندازه گیری برای اطمینان از دستیابی به این هدف برای بیشتر کاربران، رسیدن به این زمان در ۷۵ لود از ۱۰۰ بار لود کردن صفحه در دستگاه های همراه و دسکتاپ است.

چه عناصری در نظر گرفته می شوند؟

انواع عناصر در نظر گرفته شده برای Largest Contentful Paint عبارتند از:

  • عناصر <img>
  • عناصر<image> داخل یک عنصر <svg>
  • عناصر <video> (از تصویر پوستر استفاده می شود)
  • عنصری با یک تصویر پس زمینه که از طریق تابع ()url بارگیری می شود (برخلاف گرادیان CSS)
  • عناصر سطح بلوک شامل گره های متنی یا سایر عناصر متن درون خطی.

توجه داشته باشید که محدود کردن عناصر به این مجموعه محدود به منظور تسهیل مسائل در ابتدای کار است. با انجام تحقیقات بیشتر ممکن است در آینده عناصر دیگری نیز (به عنوان مثال <svg> ، <video>) اضافه شوند.

اندازه یک عنصر چگونه تعیین می شود؟

اندازه عنصر گزارش شده برای بزرگترین محتوا معمولاً اندازه ای است که برای کاربر در داخل ویوپورت قابل مشاهده است. اگر عنصر خارج از ویوپورت گسترش یابد، یا اگر هر یک از عناصر قطع شده یا دارای سرریز غیرقابل مشاهده باشد، آن قسمتها به عنوان اندازه عنصر حساب نمی شوند.

برای عناصر تصویری که از اندازه ذاتی شان تغییر اندازه داده اند، اندازه ای که گزارش می شود یا اندازه قابل مشاهده است یا اندازه ذاتی، هر کدام که کوچکتر باشد. به عنوان مثال، تصاویری که به کوچکتر از اندازه ذاتی خود تبدیل می شوند، اندازه ای را که در آن نمایش داده می شوند گزارش می دهند، در حالی که تصاویر کشیده شده یا گسترش یافته به اندازه بزرگتر، اندازه ذاتی خود را گزارش می دهند.

برای عناصر متنی فقط اندازه گره های متنی آنها در نظر گرفته شده است (کوچکترین مستطیلی که همه گره های متنی را در بر می گیرد).

برای همه عناصر، هیچ حاشیه، padding یا مرز اعمال شده از طریق CSSای در نظر گرفته نشده است.


تعیین اینکه کدام گره های متنی به کدام عناصر تعلق دارند، گاهی اوقات ممکن است دشوار باشد، به ویژه برای عناصری که شامل عناصر درون خطی و گره های متنی ساده و همچنین عناصر سطح بلوک نیز هستند. نکته اصلی این است که هر گره متنی به نزدیکترین عنصر پدر خود در سطح بلوک تعلق دارد (و فقط به آن). از نظر مشخصات: هر گره متن متعلق به عنصری است که بلوک حاوی عنصر را تولید می کند.

بزرگترین محتوا چه زمانی گزارش می شود؟

صفحات وب معمولاً به صورت مرحله ای بارگیری می شوند و در نتیجه ممکن است بزرگترین عنصر صفحه تغییر کند.

برای کنترل این تغییر بالقوه، مرورگر به محض این که اولین قاب را رنگ آمیزی کرد، یک PerformanceEntry از بزرگترین محتوا را شروع می کند که بزرگترین عنصر محتوایی را مشخص می کند. اما سپس، پس از ارائه فریم های بعدی، هر زمان که بزرگترین عنصر محتوایی تغییر کرد، یک PerformanceEntry دیگر شروع می کند.

به عنوان مثال، در صفحه ای با متن و یک تصویر، مرورگر ممکن است در ابتدا متن را رندر کند – در این صورت مرورگر یک ورودی بزرگترین محتوا را ارسال می کند که ویژگی عنصر آن احتمالاً به یک <p> یا <h1> اشاره دارد. بعداً، وقتی بارگذاری تصویر به پایان رسید، دومین ورودی بزرگترین محتوا ارسال می شود و ویژگی عنصر آن به <img> اشاره می کند.

توجه به این نکته مهم است که فقط می توان یک عنصر را بزرگترین عنصر محتوایی در نظر گرفت و در معرض دید کاربر قرار داد. تصاویری که هنوز بارگیری نشده اند “ارائه” محسوب نمی شوند. همچنین گره های متنی در طول بلوک فونت از فونت های وب استفاده نمی کنند. در چنین مواردی ممکن است عنصر کوچکتر به عنوان بزرگترین عنصر محتوایی گزارش شود ، اما به محض اتمام رندر، عنصر بزرگتر از طریق یک PerformanceEntry دیگر گزارش می شود.

علاوه بر بارگیری دیرهنگام تصاویر و فونت ها، با دسترسی به محتوای جدید، یک صفحه می تواند عناصر جدیدی را به DOM اضافه کند. اگر هر یک از این عناصر جدید از بزرگترین عنصر محتوای قبلی بزرگتر باشد، یک PerformanceEntry جدید نیز گزارش می شود.

اگر یک صفحه عنصری را از DOM حذف کند، آن عنصر دیگر در نظر گرفته نمی شود. به طور مشابه، اگر منبع تصویر مرتبط با یک عنصر تغییر کند (به عنوان مثال تغییر img.src از طریق JavaScript)، تا زمان بارگیری تصویر جدید، این عنصر در نظر گرفته نمی شود.


در آینده، عناصر حذف شده از DOM همچنان ممکن است به عنوان کاندیداهای LCP در نظر گرفته شوند. در حال حاضر تحقیقاتی برای ارزیابی تأثیر این تغییر در حال انجام است.

به محض تعامل کاربر با صفحه (از طریق ضربه زدن، پیمایش یا فشار دادن کلید)، مرورگر گزارش ورودی های جدید را متوقف می کند، زیرا تعامل کاربر اغلب آنچه را که برای کاربر قابل مشاهده است تغییر می دهد (که مخصوصا در مورد پیمایش درست است).

به منظور تجزیه و تحلیل، شما فقط باید PerformanceEntry اخیراً ارسال شده را به سرویس تجزیه و تحلیل خود گزارش دهید.


احتیاط: از آنجا که کاربران می توانند صفحات را در یک تب پس زمینه باز کنند، ممکن است بزرگترین محتوا تا زمانی که کاربر برگه را متمرکز نکند، ارائه نشود، بنابرین ارائه مدتی بعد از زمانی خواهد بود که آن را بارگذاری کرده اند.

زمان بارگذاری در مقابل زمان ارائه (Load time vs. Render time)

به دلایل امنیتی، زمان ارئه تصاویر برای تصاویر cross-origin که فاقد هدر Timing-Allow-Origin هستند نشان داده نمی شود. درعوض، فقط زمان بارگذاری آنها در معرض دید قرار دارد (زیرا این مورد از قبل از طریق بسیاری از API های وب دیگر نشان داده شده است).

مثال زیر نحوه مدیریت عناصری که زمان ارائه آنها در دسترس نیست را نشان می دهد. اما، در صورت امکان، توصیه می شود که هدر Timing-Allow-Origin را استفاده کنید، تا معیارهایتان دقیق تر باشد.

نحوه طرح بندی و تغییر اندازه عناصر چگونه کنترل می شوند؟

برای پایین نگه داشتن عملکرد در محاسبه و ارسال عملکردهای جدید، تغییرات در اندازه یا موقعیت یک عنصر باعث ایجاد کاندیداهای جدید Largest Contentful Paint نمی شود. فقط اندازه و موقعیت اولیه عنصر در ویوپورت در نظر گرفته می شود.

این به این معنی است که تصاویری که در ابتدا خارج از صفحه ارائه می شوند و بعدا به ویوپورت منتقل می شوند، گزارش نمی شوند. این همچنین به معناست که عناصری که ابتدا در ویوپورت ارائه شده اند و سپس به پایین رانده می شوند و از ویوپورت خارج می شوند همچنان اندازه اولیه شان در ویوپورت گزارش می شود.

با این حال، (همانطور که در بالا ذکر شد) اگر یک عنصر از DOM حذف شود یا منبع تصویر مرتبط با آن تغییر کند، همچنان پیگیری خواهد شد.

مثال ها

در اینجا چند نمونه از زمان آماده شدن بزرگترین محتوا در چند وب سایت معروف آورده شده است:

مثال سایت CNN
حذف شدن مقداری که قبلا بیشترین مقدار را داشت

در هر دو جدول زمانی بالا، بزرگترین عنصر با بارگذاری محتوا تغییر می کند. در مثال اول، محتوای جدید به DOM اضافه می شود و این بزرگترین عنصر را تغییر می دهد. در مثال دوم، چیدمان تغییر می کند و محتوایی که قبلاً بیشترین مقدار را داشت، از ویوپورت حذف می شود.

گرچه غالباً چنین است که محتوای دیرتر بارگذاری شده نسبت به محتوای موجود در صفحه بزرگتر است، اما لزوماً اینگونه نیست. دو مثال بعدی بزرگترین محتوا را قبل از بارگیری کامل صفحه نشان می دهد.

مثال سایت اینستاگرام
مثال بخش جستجوی گوگل

در مثال اول، آرم اینستاگرام نسبتاً زود بارگیری می شود و حتی با نمایش تدریجی سایر مطالب، بزرگترین عنصر باقی می ماند. در مثال صفحه نتایج جستجوی گوگل، بزرگترین عنصر یک پاراگراف از متن است که قبل از پایان بارگیری هر یک از تصاویر یا آرم نمایش داده می شود. از آنجا که تمام تصاویر منفرد کوچکتر از این پاراگراف هستند، بزرگترین عنصر در طول فرآیند بارگذاری باقی می ماند.


در اولین قاب جدول زمانی اینستاگرام ممکن است متوجه شوید که آرم دوربین در اطراف خود جعبه ای سبز رنگ ندارد. به این دلیل که این یک عنصر <svg> است و عناصر <svg> در حال حاضر به عنوان کاندیداهای LCP در نظر گرفته نمی شوند. اولین نامزد LCP متن موجود در قاب دوم است.

نحوه اندازه گیری  LCP

LCP را می توان در آزمایش یا در شرایط میدانی اندازه گیری کرد و در ابزارهای زیر در دسترس است:

ابزار میدانی

ایزار های آزمایشگاهی

LCP را در JavaScript اندازه بگیرید

ساده ترین راه برای اندازه گیری LCP (و همچنین تمام معیارهای زمینه Web Vital ها) با استفاده از کتابخانه جاوا اسکریپت web-vitals است که تمام پیچیدگی های اندازه گیری دستی LCP را در یک عملکرد واحد قرار می دهد:

import {getLCP} from 'web-vitals';

// Measure and log the current LCP value,
// any time it's ready to be reported.
getLCP(console.log);

برای اندازه گیری دستی LCP، می توانید از API بزرگترین محتوا استفاده کنید. مثال زیر نحوه ایجاد PerformanceObserver را نشان می دهد که ورودی های بزرگترین محتوا را می پذیرد و مقدار LCP را در کنسول ثبت می کند:

// Keep track of whether (and when) the page was first hidden, see:
// https://github.com/w3c/page-visibility/issues/29
// NOTE: ideally this check would be performed in the document <head>
// to avoid cases where the visibility state changes before this code runs.
let firstHiddenTime = document.visibilityState === 'hidden' ? 0 : Infinity;
document.addEventListener('visibilitychange', (event) => {
  firstHiddenTime = Math.min(firstHiddenTime, event.timeStamp);
}, {once: true});

// Sends the passed data to an analytics endpoint. This code
// uses `/analytics`; you can replace it with your own URL.
function sendToAnalytics(data) {
  const body = JSON.stringify(data);
  // Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
  (navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) ||
      fetch('/analytics', {body, method: 'POST', keepalive: true});
}

// Use a try/catch instead of feature detecting `largest-contentful-paint`
// support, since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
  // Create a variable to hold the latest LCP value (since it can change).
  let lcp;

  function updateLCP(entry) {
    // Only include an LCP entry if the page wasn't hidden prior to
    // the entry being dispatched. This typically happens when a page is
    // loaded in a background tab.
    if (entry.startTime < firstHiddenTime) {
      // NOTE: the `startTime` value is a getter that returns the entry's
      // `renderTime` value, if available, or its `loadTime` value otherwise.
      // The `renderTime` value may not be available if the element is an image
      // that's loaded cross-origin without the `Timing-Allow-Origin` header.
      lcp = entry.startTime;
    }
  }

  // Create a PerformanceObserver that calls `updateLCP` for each entry.
  const po = new PerformanceObserver((entryList, po) => {
    entryList.getEntries().forEach((entry) => updateLCP(entry, po));
  });

  // Observe entries of type `largest-contentful-paint`, including buffered entries,
  // i.e. entries that occurred before calling `observe()` below.
  po.observe({
    type: 'largest-contentful-paint',
    buffered: true,
  });

  // Log the final LCP score once the
  // page's lifecycle state changes to hidden.
  addEventListener('visibilitychange', function fn(event) {
    if (document.visibilityState === 'hidden') {
      removeEventListener('visibilitychange', fn, true);

      // Force any pending records to be dispatched and disconnect the observer.
      po.takeRecords().forEach((entry) => updateLCP(entry, po));
      po.disconnect();

      // If LCP is set, report it to an analytics endpoint.
      if (lcp) {
        sendToAnalytics({lcp});
      }
    }
  }, true);
} catch (e) {
  // Do nothing if the browser doesn't support this API.
}

اگر بزرگترین عنصر مهمترین نباشد چه می شود؟

در برخی موارد مهمترین عنصر (یا عناصر) موجود در صفحه با بزرگترین عنصر یکی نیست و توسعه دهندگان ممکن است بیشتر علاقه مند به اندازه گیری زمان رندر این عناصر باشند. همانطور که در مقاله معیارهای سفارشی شرح داده شده است، این کار با استفاده از Element Timing API امکان پذیر است.

چگونه می توان LCP را بهبود بخشید

LCP در درجه اول تحت تأثیر چهار عامل قرار دارد:

  • پاسخ سرور کند
  • جاوا اسکریپت و CSS ارائه را مسدود کنند
  • زمان بارگذاری منابع
  • ارائه در سمت مشتری

برای اطلاعات بیشتر در این مورد می توانید به مطلب “بهینه سازیLargest Contentful Paint” مراجعه کنید.

تغییرات

گاهی اوقات، در API های مورد استفاده برای اندازه گیری معیارها و گاهی اوقات در تعاریف خود معیارها اشکالاتی یافته می شود. در نتیجه، گاهی اوقات باید تغییراتی ایجاد شوند و این تغییرات می تواند به عنوان بهبود یا عقبگرد در گزارشات داخلی و داشبورد شما نشان داده شود.

برای کمک به شما در مدیریت این امر، تمام تغییرات موجود در پیاده سازی یا تعریف این معیارها در این CHANGELOG نشان داده می شود.

منبع : web.dev

۰ ۰ vote
Article Rating