آیا تا به حال در حال خواندن مقاله ای آنلاین بوده اید که ناگهان چیزی در صفحه تغییر کند؟ بدون هشدار، متن حرکت می کند و شما جای خود را گم کرده اید. یا حتی بدتر: میخواهید روی یک پیوند یا دکمه ضربه بزنید، اما بلافاصله قبل از اینکه انگشتتان فرود بیاید لینک حرکت میکند و در نهایت روی چیز دیگری کلیک میکنید.
اغلب اوقات این نوع تجربیات فقط آزاردهنده هستند، اما در برخی موارد می توانند آسیب واقعی ایجاد کنند. که در تجربه کاربری بد و کاهش رتبه در نتایج و مبحث سئو به شما ضربه خواهد زد
حرکت غیرمنتظره محتوای صفحه معمولاً به این دلیل اتفاق می افتد که منابع به صورت ناهمزمان بارگیری می شوند یا عناصر DOM به صورت پویا به صفحه بالای محتوای موجود اضافه می شوند. مقصر ممکن است تصویر یا ویدیویی با ابعاد ناشناخته، فونتی باشد که بزرگتر یا کوچکتر از نسخه قبلی خود می شود، یا یک تبلیغ شخص ثالث یا ویجت که به صورت پویا خود را تغییر اندازه می دهد.
چیزی که این موضوع را حتی مشکلسازتر میکند این است که نحوه عملکرد یک سایت در توسعه اغلب با نحوه تجربه کاربران (ux) کاملاً متفاوت است. محتوای شخصی یا شخص ثالث اغلب در توسعه مانند تولید عمل نمی کند، تصاویر آزمایشی اغلب در cache مرورگر توسعه دهنده هستند و درخواست های API که به صورت محلی اجرا می شوند اغلب آنقدر سریع هستند که تاخیر قابل توجه نیست.
متریک Cumulative Layout Shift (CLS) به شما کمک می کند این مشکل را با اندازه گیری تعداد دفعات وقوع آن برای کاربران واقعی برطرف کنید.
CLS چیست؟
CLS اندازهگیری بزرگترین پیاپی امتیازات تغییر طرحبندی برای هر تغییر غیرمنتظرهای که در طول عمر یک صفحه رخ میدهد است.
هر زمانی که یک عنصر قابل مشاهده موقعیت خود را از یک فریم رندر شده به فریم بعدی تغییر می دهد، تغییر طرح رخ می دهد.
انبوهی از تغییرات طرحبندی، که به عنوان Session Window شناخته میشود، زمانی است که یک یا چند تغییر چیدمان به صورت متوالی و با کمتر از 1 ثانیه بین هر تغییر و حداکثر 5 ثانیه برای کل مدت زمان پنجره اتفاق میافتد.
بزرگترین انفجار Session Window با حداکثر امتیاز تجمعی از تمام تغییرات طرح در آن پنجره است.
امتیاز CLS خوب چقدر است؟
برای ارائه یک تجربه کاربری خوب، سایت ها باید تلاش کنند تا امتیاز CLS 0.1 یا کمتر داشته باشند. برای اطمینان از رسیدن به این هدف برای اکثر کاربران خود، یک آستانه خوب برای اندازه گیری صدک 75 بارگذاری صفحه است که در دستگاه های تلفن همراه و دسکتاپ تقسیم بندی شده است.
جزئیات Layout Shift در cls
تغییر چیدمان توسط Layout Instability API تعریف میشود، که هر زمانی که عنصری که در لود اولیه قابل مشاهده است، موقعیت شروع خود را (مثلاً موقعیت بالا و چپ در حالت نوشتن پیشفرض) بین دو فریم تغییر دهد، ورودیهای تغییر طرح را گزارش میکند. چنین عناصری عناصر ناپایدار در نظر گرفته می شوند.
توجه داشته باشید که تغییرات چیدمان تنها زمانی رخ می دهد که عناصر موجود موقعیت شروع خود را تغییر دهند. اگر یک عنصر جدید به DOM اضافه شود یا یک عنصر موجود اندازه آن را تغییر دهد، به عنوان یک تغییر چیدمان به حساب نمی آید - تا زمانی که این تغییر باعث نشود که سایر عناصر قابل مشاهده موقعیت شروع خود را تغییر دهند.
Layout shift score در cls
برای محاسبه امتیاز تغییر طرح، مرورگر به اندازه ویوپورت و حرکت عناصر ناپایدار در view port بین دو فریم رندر شده نگاه می کند. امتیاز تغییر طرح محصول دو معیار آن حرکت است: impact fraction و distance fraction (هر دو در زیر تعریف شده اند).
layout shift score = impact fraction * distance fraction
-
معیار impact fraction در cls
impact fraction نحوه تاثیر عناصر ناپایدار بر ناحیه دید بین دو فریم را اندازه گیری می کند.
اتحاد نواحی قابل مشاهده همه عناصر ناپایدار برای قاب قبلی و قاب فعلی - به عنوان کسری از مساحت کل نما - impact fraction برای قاب فعلی است.
در تصویر بالا عنصری وجود دارد که نیمی از نمای در یک فریم را اشغال می کند. سپس، در فریم بعدی، عنصر به میزان 25 درصد از ارتفاع درگاه دید به پایین جابهجا میشود. مستطیل نقطهدار قرمز نشاندهنده اتحاد ناحیه قابل مشاهده عنصر در هر دو فریم است که در این حالت 75٪ از کل دید است، بنابراین کسر ضربه آن 0.75 است.
-
معیار distance fraction در cls
بخش دیگر معادله امتیاز تغییر چیدمان، فاصله ای را که عناصر ناپایدار حرکت کرده اند، نسبت به درگاه دید اندازه گیری می کند. distance fraction بزرگترین فاصله ای است که هر عنصر ناپایدار در قاب حرکت کرده است (افقی یا عمودی) تقسیم بر بزرگترین بعد درگاه دید (عرض یا ارتفاع، هر کدام که بیشتر باشد).
در مثال بالا، بزرگترین بعد درگاه دید، ارتفاع است و عنصر ناپایدار 25 درصد از ارتفاع درگاه دید جابجا شده است، که distance fraction را 0.25 می کند.
بنابراین، در این مثال impact fraction 0.75 و distance fraction 0.25 است، بنابراین نمره تغییر طرح 0.75 * 0.25 = 0.1875 است.
نکته: در ابتدا، امتیاز تغییر طرح تنها بر اساس impact fraction محاسبه شد. distance fraction برای جلوگیری از جریمه کردن بیش از حد مواردی که عناصر بزرگ با مقدار کمی جابجا می شوند، معرفی شد.
مثال بعدی نشان میدهد که چگونه افزودن محتوا به یک عنصر موجود بر امتیاز تغییر طرحبندی تأثیر میگذارد:
"Click Me!" دکمه به پایین کادر خاکستری با متن سیاه اضافه شده است، که کادر سبز با متن سفید را به پایین (و تا حدی خارج از نمای دید) فشار می دهد.
در این مثال، جعبه خاکستری تغییر اندازه می دهد، اما موقعیت شروع آن تغییر نمی کند، بنابراین یک عنصر ناپایدار نیست.
دکمه "Click Me!" قبلاً در DOM نبود، بنابراین موقعیت شروع آن نیز تغییر نمی کند.
با این حال، موقعیت شروع کادر سبز تغییر میکند، اما از آنجایی که تا حدی به خارج از نما منتقل شده است، هنگام محاسبه impact fraction ، ناحیه نامرئی در نظر گرفته نمیشود. اتحاد نواحی قابل مشاهده برای کادر سبز در هر دو فریم (که با مستطیل نقطهدار قرمز نشان داده شده است) با مساحت کادر سبز در اولین فریم برابر است - 50٪ از نمای دید. impact fraction 0.5 است.
distance fraction با فلش بنفش نشان داده شده است. کادر سبز حدود 14 درصد از نمای دید به سمت پایین حرکت کرده است، بنابراین کسر فاصله 0.14 است.
layout shift score برابر با 0.5 * 0.14 = 0.07 است.
این مثال آخر چندین عنصر ناپایدار را نشان می دهد:
در فریم اول بالا چهار نتیجه از یک درخواست API برای حیوانات وجود دارد که به ترتیب حروف الفبا مرتب شده اند. در فریم دوم، نتایج بیشتری به لیست مرتب شده اضافه می شود.
اولین مورد در لیست ("Cat") موقعیت شروع خود را بین فریم ها تغییر نمی دهد، بنابراین پایدار است. به طور مشابه، موارد جدید اضافه شده به لیست قبلاً در DOM نبودند، بنابراین موقعیت شروع آنها نیز تغییر نمی کند. اما اقلام با برچسب "Dog"، "Horse" و "Zebra" همگی موقعیت شروع خود را تغییر می دهند و آنها را به عناصر ناپایدار تبدیل می کنند.
مجدداً، مستطیلهای نقطه چین قرمز، اتحاد این سه عنصر ناپایدار قبل و بعد را نشان میدهند، که در این مورد حدود 60% مساحت نمای درگاه است (impact fraction 0.60).
فلش ها نشان دهنده فواصلی هستند که عناصر ناپایدار از موقعیت شروع خود جابجا شده اند. عنصر "Zebra" که با فلش آبی نشان داده می شود، بیشترین جابجایی را داشته است، در حدود 30٪ از ارتفاع دید. این باعث می شود distance fraction در این مثال 0.3 باشد.
layout shift score برابر با 0.60 * 0.3 = 0.18 است.
layout shift مورد انتظار در مقابل layout shift غیرمنتظره در معیار cls
همه layout shift ها بد نیستند. در واقع، بسیاری از برنامه های کاربردی وب پویا مرتباً موقعیت شروع عناصر را در صفحه را تغییر می دهند.
User-initiated layout shifts - layout shift تنها زمانی بد است که کاربر انتظار آن را نداشته باشد. از سوی دیگر، تغییرات طرحبندی که در پاسخ به تعاملات کاربر رخ میدهد (کلیک کردن روی پیوند، فشار دادن یک دکمه، تایپ کردن در کادر جستجو و موارد مشابه) معمولاً خوب است، تا زمانی که این تغییر به اندازه کافی نزدیک به تعاملی باشد که رابطه برقرار میشود. برای کاربر روشن است.
به عنوان مثال، اگر یک تعامل کاربر یک درخواست شبکه را راه اندازی می کند که ممکن است تکمیل آن مدتی طول بکشد، بهتر است فوراً مقداری فضا ایجاد کنید و یک نشانگر بارگذاری نشان دهید تا از layout shift ناخوشایند هنگام تکمیل درخواست جلوگیری کنید. اگر کاربر متوجه نشود که چیزی در حال بارگیری است، یا احساسی از زمان آماده شدن منبع نداشته باشد، ممکن است سعی کند در حین انتظار روی چیز دیگری کلیک کند - چیزی که می تواند از زیر آنها خارج شود.
layout shift که در عرض 500 میلیثانیه از ورودی کاربر رخ میدهند دارای پرچم RecentInput هستند، بنابراین میتوان آنها را از محاسبات حذف کرد.
Animations و transitions- انیمیشن ها و انتقال ها، زمانی که به خوبی انجام شوند، راهی عالی برای به روز رسانی محتوای صفحه بدون تعجب کاربر هستند. محتوایی که بهطور ناگهانی و غیرمنتظره در صفحه جابهجا میشود تقریباً همیشه یک تجربه کاربری بد ایجاد میکند. اما محتوایی که بهتدریج و بهطور طبیعی از یک موقعیت به موقعیت دیگر حرکت میکند، اغلب میتواند به کاربر کمک کند تا بهتر بفهمد چه اتفاقی میافتد و او را بین تغییرات حالت راهنمایی کند.
مطمئن شوید که به تنظیمات مرورگر prefers-reduced-motion احترام بگذارید، زیرا برخی از بازدیدکنندگان سایت ممکن است اثرات نامطلوب یا مشکلاتی از انیمیشنها را تجربه کنند.
ویژگی CSS transform به شما امکان می دهد عناصر را بدون ایجاد تغییرات طرح بندی متحرک کنید:
- به جای تغییر خصوصیات ارتفاع و عرض، از transform: scale() استفاده کنید.
- برای جابجایی عناصر به اطراف، از تغییر ویژگی های بالا، راست، پایین یا چپ خودداری کنید و به جای آن از transform: translate() استفاده کنید.
نحوه اندازه گیری CLS
CLS را می توان در آزمایشگاه یا میدان اندازه گیری کرد که در ابزارهای زیر موجود است:
نکته: ابزارهای آزمایشگاهی معمولاً صفحات را در یک محیط مصنوعی بارگیری میکنند و بنابراین فقط میتوانند تغییرات طرحبندی را که در حین بارگذاری صفحه رخ میدهد اندازهگیری کنند. در نتیجه، مقادیر CLS گزارش شده توسط ابزارهای آزمایشگاهی برای یک صفحه معین ممکن است کمتر از آن چیزی باشد که کاربران واقعی در این زمینه تجربه می کنند.
ابزارهای میدانی:
- Chrome User Experience Report
- PageSpeed Insights
- Search Console (Core Web Vitals report)
- کتابخانه جاوا اسکریپت web-vitals
ابزارهای آزمایشگاهی:
- Chrome DevTools
- Lighthouse
- PageSpeed Insights
- WebPageTest
layout shift برای clsرا در جاوا اسکریپت چگونه اندازهگیری کنیم؟
برای اندازهگیری layout shift در جاوا اسکریپت، از Layout Instability API استفاده میکنید.
مثال زیر نحوه ایجاد یک PerformanceObserver برای ثبت ورودی های layout-shift به کنسول را نشان می دهد:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('Layout shift:', entry);
}
}).observe({type: 'layout-shift', buffered: true});
برای اندازهگیری CLS در جاوا اسکریپت، باید این ورودیهای layout shift غیرمنتظره را در جلسات گروهبندی کنید و حداکثر مقدار جلسه را محاسبه کنید. می توانید به کد منبع کتابخانه جاوا اسکریپت web vitals مراجعه کنید که حاوی یک پیاده سازی مرجع در مورد نحوه محاسبه آن است.
در بیشتر موارد، مقدار CLS فعلی در زمانی که صفحه در حال بارگیری است، مقدار نهایی برای آن صفحه است، اما چند استثنا مهم وجود دارد. کتابخانه جاوا اسکریپت web vitals این موارد را تا آنجا که ممکن است، در محدوده محدودیت های API های وب، حساب می کند.
تفاوت بین متریک و API:
اگر صفحهای در پسزمینه بارگذاری میشود، یا اگر قبل از اینکه مرورگر محتوایی را در پس زمینه بارگیری کند، نباید هیچ مقدار CLS را گزارش کند.
اگر صفحه ای از Back/Forward cache بازیابی شود، مقدار CLS آن باید به صفر بازنشانی شود زیرا کاربران این را به عنوان یک بازدید از صفحه مجزا تجربه می کنند.
API ورودیهای layout shift را برای تغییراتی که در iframe اتفاق میافتد گزارش نمیکند، اما معیار اندازهگیری را بهعنوان بخشی از تجربه کاربر صفحه انجام میدهد. این می تواند به عنوان تفاوت بین CrUX و RUM نشان داده شود. برای اندازه گیری صحیح CLS باید آنها را در نظر بگیرید. فریمهای فرعی میتوانند از API برای گزارش ورودیهای layout shift خود به قاب والد برای aggregation استفاده کنند.
علاوه بر این استثناها، CLS به دلیل این واقعیت که کل طول عمر یک صفحه را اندازه گیری می کند، پیچیدگی بیشتری نیز دارد:
- کاربران ممکن است یک برگه را برای مدت بسیار طولانی باز نگه دارند - روزها، هفته ها، ماه ها. در واقع، یک کاربر ممکن است هرگز یک برگه را نبندد.
- در سیستمعاملهای تلفن همراه، مرورگرها معمولاً برای برگههای پسزمینه، بازخوانی بارگیری صفحه را اجرا نمیکنند و گزارش مقدار «final» را دشوار میکند.
برای رسیدگی به چنین مواردی، CLS باید هر زمان که یک صفحه پسزمینه است گزارش شود - علاوه بر هر زمانی که بارگیری میشود (رویداد visibilitychange هر دوی این سناریوها را پوشش میدهد). و سیستم های تحلیلی که این داده ها را دریافت می کنند، باید مقدار نهایی آن را در بکاند محاسبه کنند.
توسعه دهندگان می توانند به جای حفظ کردن و دست و پنجه نرم کردن با همه این موارد، از کتابخانه جاوا اسکریپت web-vitals برای اندازه گیری CLS استفاده کنند، که تمام موارد ذکر شده در بالا را به حساب می آورد:
import {onCLS} from 'web-vitals';
// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);
نکته: در برخی موارد (مانند iframe های متقاطع) اندازه گیری CLS در جاوا اسکریپت ممکن نیست.