بدترین شکایت مشتری‌ای که یادم می‌آید، از کندی نبود و از هک هم نبود. کارفرمای یک فروشگاه اینترنتی با لحن عصبانی گفت: کاربرانمان به ما پیام می‌دهند که روی دکمه پرداخت که می‌زنند، ناگهان صفحه می‌پرد و روی بنر تبلیغاتی کلیک می‌شود. آن روز کل آمار را نگاه کردیم و متوجه شدیم در موبایل، نرخ پرش صفحه تسویه سه برابر بقیه صفحه‌هاست. مشکل نه سرعت بود و نه امنیت؛ مشکل CLS (Cumulative Layout Shift) بود که هیچ‌کس تا آن روز جدی نگرفته بود.

CLS یکی از سه معیار Core Web Vitals (شاخص‌های اصلی وب) است که گوگل برای سنجش تجربه کاربری تعیین کرده و در رتبه‌بندی لحاظ می‌کند. اما برخلاف LCP (Largest Contentful Paint) که از جنس سرعت است و INP (Interaction to Next Paint) که از جنس پاسخ‌گویی، CLS از جنس ثبات است — یعنی چقدر چیدمان صفحه در حین بارگذاری ثابت می‌ماند. همین ویژگی، آن را به معیاری مستقل تبدیل می‌کند که نه با بهبود سرور حل می‌شود و نه با کش. این مقاله، تجربهٔ کاری من روی بیش از بیست سایت را در کاهش CLS جمع می‌کند.

CLS چیست و گوگل با آن چه می‌سنجد؟

CLS (Cumulative Layout Shift) معیاری است که مجموع جابه‌جایی‌های ناخواستهٔ عناصر صفحه در طول فرایند بارگذاری را اندازه می‌گیرد. تصور کنید کاربر در حال خواندن پاراگراف اول صفحه است و ناگهان یک بنر تبلیغاتی بالای متن ظاهر می‌شود و کل متن را پایین می‌برد. یا کاربر می‌خواهد روی دکمه خرید بزند و در همان لحظه، یک تصویر سنگین بالاتر از دکمه بار می‌شود و دکمه را به سمت پایین هل می‌دهد. این تجربه، همان چیزی است که CLS می‌سنجد.

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

عدد آستانه‌ها را گوگل این‌طور تعیین کرده است:

وضعیتعدد CLSتفسیر تجربه کاربر
خوبزیر ۰/۱کاربر جابه‌جایی محسوسی تجربه نمی‌کند
نیازمند بهبودبین ۰/۱ تا ۰/۲۵کاربر جابه‌جایی‌های آزاردهنده حس می‌کند
ضعیفبالای ۰/۲۵تجربه کاربر مخدوش و نرخ پرش بالا

تفاوت این معیار با دو معیار دیگر Core Web Vitals را در Core Web Vitals چیست و چرا گوگل بر آن تأکید دارد؟ باز کرده‌ام. نکتهٔ کلیدی اینجاست: CLS تنها معیاری است که مستقل از سرعت اندازه‌گیری می‌شود. یعنی ممکن است سایت شما با سرعت بالا باز شود، اما چون تصاویر بدون ابعاد بارگذاری می‌شوند یا فونت دیر می‌رسد، CLS بدی داشته باشید.

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

چرا CLS مهم است؟ از تجربه کاربر تا رتبه گوگل

سه دلیل که CLS را از یک معیار تزئینی به یک ضرورت تبدیل می‌کند:

دلیل اول: تجربهٔ کاربر و نرخ تبدیل

در پروژهٔ فروشگاهی که در ابتدای این مقاله گفتم، کاهش CLS از ۰/۳۸ به ۰/۰۶ منجر به افزایش ۱۹ درصدی تکمیل خرید در صفحهٔ تسویه شد. کاربری که نگران است دکمهٔ پرداخت زیر انگشتش جابه‌جا شود، خریدی هم انجام نمی‌دهد. CLS مستقیماً روی احساس اعتماد کاربر اثر می‌گذارد؛ به‌خصوص در صفحات حساس مثل فرم‌ها و صفحات پرداخت. رابطهٔ CLS با نرخ تبدیل را در رابطه Core Web Vitals و نرخ تبدیل چیست؟ با اعداد پروژه‌های واقعی توضیح داده‌ام.

دلیل دوم: رتبه‌بندی گوگل

از سال ۲۰۲۱، Core Web Vitals بخشی از سیگنال‌های تجربهٔ صفحه در رتبه‌بندی گوگل شد. یعنی CLS بد نه‌فقط روی رفتار کاربر اثر می‌گذارد، بلکه مستقیماً روی جایگاه شما در نتایج جستجو. این اثر تعدیل‌گر است، نه قاطع؛ اما در رقابت بین دو سایت هم‌سطح محتوایی، همان تفاوت ۰/۲ در CLS می‌تواند جابه‌جایی رتبه را تعیین کند.

دلیل سوم: ترافیک موبایل

روی نمایشگر کوچک، هر جابه‌جایی چیدمان چند برابر آزاردهنده‌تر است. اندازه‌گیری‌های گوگل نشان داده که CLS در موبایل معمولاً دو تا سه برابر دسکتاپ است، چون عرض محدودتر، جابه‌جایی‌ها را محسوس‌تر می‌کند. در چگونه Core Web Vitals را در موبایل بهبود دهیم؟ این تفاوت‌ها را باز کرده‌ام.

پنج عامل رایج ایجاد پرش چیدمان

در بازبینی‌های خودم روی سایت‌های مختلف، پنج عامل بیشترین سهم را در تولید CLS دارند:

عامل اول: تصاویر بدون ابعاد مشخص

رایج‌ترین عامل. اگر به مرورگر نگویید تصویر چه ارتفاع و عرضی دارد، آن را با ابعاد صفر رزرو می‌کند و وقتی فایل تصویر لود شد، فضای واقعی را اشغال می‌کند و همه‌چیز پایین‌تر را جابه‌جا می‌کند. راه‌حل ساده است: همیشه در تگ <img> مقادیر width و height را مشخص کنید یا از CSS نسبت ابعاد (aspect-ratio) استفاده کنید. خوشبختانه وردپرس از نسخه ۵.۵ این کار را خودکار انجام می‌دهد، اما بعضی قالب‌های قدیمی هنوز این ابعاد را حذف می‌کنند.

عامل دوم: تبلیغات، بنرها و آی‌فریم‌های بی‌رزرو

هر محتوایی که از منبع بیرونی لود می‌شود و ابعادش از قبل رزرو نشده، عامل مستقیم CLS است. بنرهای تبلیغاتی، آی‌فریم شبکه‌های اجتماعی، ویجت‌های چت و نقشه‌های گوگل، همه پتانسیل این مشکل را دارند. راه‌حل: یک ارتفاع حداقلی با min-height برای ظرف آن‌ها رزرو کنید.

عامل سوم: فونت‌های وب بدون جایگزین

وقتی فونت سفارشی لود می‌شود، اگر مرورگر با فونت پیش‌فرض صفحه را رندر کرده باشد و سپس فونت جدید را جایگزین کند، متن جابه‌جا می‌شود. به این اتفاق FOUT (Flash of Unstyled Text) یا FOIT (Flash of Invisible Text) می‌گویند. راه‌حل: استفاده از font-display: swap به‌همراه تعریف یک فونت جایگزین هم‌اندازه.

عامل چهارم: محتوای تزریق‌شده در بالای صفحه

اگر افزونه‌ای یا کدی، محتوایی مثل نوار اطلاع‌رسانی، بنر کوکی یا هدر چسبان را بالای محتوای موجود تزریق کند، بقیهٔ صفحه به پایین هُل داده می‌شود. این الگو در پروژه‌های وردپرسی زیاد دیده می‌شود، به‌خصوص با افزونه‌های کوکی و تبلیغاتی.

عامل پنجم: دکمه‌ها و اجزای تعاملی بی‌محل

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

فهرست کامل‌تر این عوامل را در اشتباهات رایج در بهینه‌سازی Core Web Vitals آورده‌ام.

چطور CLS را اندازه بگیریم؟

دو منبع اندازه‌گیری CLS وجود دارد که هر دو را باید جدی گرفت:

داده میدانی (Field Data)

این داده از کاربران واقعی می‌آید و در گزارش CrUX (Chrome User Experience Report) گوگل جمع می‌شود. در Search Console، بخش Core Web Vitals این داده را نشان می‌دهد. مزیت این داده، واقعی بودن آن است؛ عیبش این است که برای سایت‌های کم‌ترافیک، داده‌ای نشان نمی‌دهد.

داده آزمایشگاهی (Lab Data)

این داده از ابزارهایی مثل PageSpeed Insights (قسمت Lighthouse)، Chrome DevTools و WebPageTest می‌آید. مزیتش سرعت و تکرارپذیری است؛ عیبش این است که شرایط آزمایشگاه همیشه با تجربهٔ واقعی کاربر یکی نیست.

روش من در پروژه‌ها: اول با PageSpeed Insights و DevTools روی نسخهٔ موبایل، CLS را در سه صفحهٔ پرترافیک بسنجم. بعد در Search Console داده میدانی را ببینم تا بفهمم کاربران واقعی چه تجربه‌ای دارند. ابزارهای دقیق‌تر را در ابزارهای سنجش Core Web Vitals کدامند؟ و بهترین ابزارهای تست سرعت سایت آورده‌ام.

کاهش CLS: هفت تکنیک عملی که واقعاً جواب می‌دهد

تکنیک یکم: ابعاد صریح روی همه تصاویر و ویدیوها

برای هر <img>، مقدار width و height را مشخص کنید. برای ویدیوها هم نسبت ابعاد را با CSS تعیین کنید. این ساده‌ترین و مؤثرترین کار است. اگر با وردپرس کار می‌کنید، در فایل قالب یا با افزونه‌ای مثل Code Snippets می‌توانید به‌صورت سراسری اعمالش کنید. توضیحات بیشتر در چگونه تصاویر را برای موبایل بهینه کنیم؟ آمده است.

تکنیک دوم: رزرو فضا برای تبلیغات و محتوای پویا

هر ظرفی که محتوایش بعداً بار می‌شود، باید ارتفاعش از پیش رزرو شده باشد. یک min-height روی کلاس CSS آن ظرف اضافه کنید. اگر ارتفاع دقیق را نمی‌دانید، میانگین ارتفاع ممکن را رزرو کنید.

تکنیک سوم: فونت‌ها با font-display درست

در @font-face، مقدار font-display: swap را تعیین کنید. این تنظیم باعث می‌شود مرورگر ابتدا با فونت جایگزین صفحه را رندر کند و بعد با فونت اصلی جایگزین کند، بدون اینکه چیدمان از هم بپاشد. برای فونت فارسی، این مسئله حساس‌تر است چون فونت‌های فارسی حجیم‌ترند و دیرتر می‌رسند.

تکنیک چهارم: ترتیب بارگذاری CSS بحرانی

CSS بحرانی (Critical CSS) همان استایل‌هایی است که برای رندر اولیهٔ صفحه لازماند. اگر آن‌ها را در head صفحه به‌صورت inline قرار دهید و بقیه را با rel="preload" یا تأخیری بار کنید، چیدمان صفحه سریع‌تر ثابت می‌شود. این تکنیک در پروژه‌های وردپرسی با افزونه‌های کش قابل اجرا است؛ مقایسه‌شان در بهترین افزونه‌های کش وردپرس.

تکنیک پنجم: پرهیز از تزریق محتوا بالای صفحه

هر محتوایی که توسط جاوااسکریپت اضافه می‌شود و بالای محتوای موجود قرار می‌گیرد، باید از ابتدا در HTML باشد یا از جریان عادی خارج شود (مثلاً با position: fixed). افزونه‌های کوکی و بنرهای تبلیغاتی معمولاً این مشکل را می‌سازند.

تکنیک ششم: انیمیشن‌ها با transform به‌جای top/left

انیمیشن‌هایی که با top، left، margin یا width اجرا می‌شوند، layout را دوباره محاسبه می‌کنند و CLS تولید می‌کنند. اما انیمیشن‌هایی که با transform و opacity کار می‌کنند، در لایهٔ رندر جدا اجرا می‌شوند و CLS تولید نمی‌کنند.

تکنیک هفتم: قالب سبک و استاندارد

بعضی قالب‌ها به‌خاطر ساختار نادرست CSS، ذاتاً پرش چیدمان تولید می‌کنند. اگر بعد از اجرای شش تکنیک بالا همچنان CLS بالاست، باید به قالب شک کنید. در قالب سبک وردپرس چیست؟ معیارهای قالب کم‌CLS را آورده‌ام و در چرا بعضی قالب‌های وردپرس سایت را کند می‌کنند؟ دلایل ساختاری را باز کرده‌ام.

جدول جمع‌بندی: عامل پرش و راه‌حل

عامل پرشنشانه در DevToolsراه‌حل
تصویر بدون ابعادجهش شدید بعد از لود تصویرافزودن width/height یا aspect-ratio
تبلیغ و آی‌فریمپرش بعد از اجرای اسکریپت خارجیرزرو فضا با min-height
فونت وبجهش متن هنگام تغییر فونتfont-display: swap
بنر و نوتیفیکیشنپرش بالای صفحه در ثانیه اولبار کردن در HTML اولیه
دکمه‌های پویاپرش در فرم یا صفحه پرداختاستایل اولیه کامل، بدون بازنویسی

اشتباهات رایج در کاهش CLS

چهار اشتباهی که در پروژه‌ها زیاد دیده‌ام و هر بار یادآوری می‌کنم:

  • خاموش کردن جاوااسکریپت برای حذف CLS: این کار شبیه قطع کردن دست برای درمان درد انگشت است. باید منبع پرش را برطرف کنید، نه همهٔ رفتارهای سایت را.
  • استفاده سراسری از skeleton screen: در بعضی موارد skeleton (اسکلت بارگذاری) کمک می‌کند، اما اگر ابعاد skeleton با محتوای نهایی یکی نباشد، خودش عامل CLS می‌شود.
  • توجه نکردن به موبایل: CLS روی موبایل همیشه بدتر از دسکتاپ است. باید هر تست را از منظر موبایل انجام دهید.
  • قناعت به نمره آزمایشگاهی: نمرهٔ PageSpeed لابراتوار مهم است، اما نمرهٔ واقعی CLS همان است که کاربران تجربه می‌کنند. باید در Search Console نگاه کنید.

نکات پیشرفته برای توسعه‌دهندگان

برای توسعه‌دهندگان و کسانی که با کد سر و کار دارند، چند نکته‌ که در پروژه‌های تخصصی به کارم آمده:

  • Content-Visibility: استفاده از content-visibility: auto برای بخش‌های پایین صفحه، باعث می‌شود مرورگر محتوای دور از دید را با ابعاد تخمینی رزرو کند. این تکنیک هم سرعت و هم CLS را بهبود می‌دهد.
  • contain-intrinsic-size: همراه با content-visibility استفاده می‌شود تا ارتفاع تخمینی را تعیین کند و پرش را کامل از بین ببرد.
  • resizeObserver: اگر محتوایی توسط جاوااسکریپت اضافه می‌کنید، با این API می‌توانید قبل از اضافه کردن، ارتفاع دقیق را حساب و رزرو کنید.
  • preconnect برای CDN و فونت: کاهش زمان دریافت منابع خارجی، پنجرهٔ زمانی ممکن برای پرش را کوچک‌تر می‌کند.

همان‌طور که در Core Web Vitals در وردپرس چگونه بهبود می‌یابد؟ توضیح داده‌ام، در وردپرس این تکنیک‌ها را می‌توانید از طریق چایلد تم و افزونه‌های تخصصی اجرا کنید. چایلد تم راهی است که در چرا از چایلد تم استفاده کنیم؟ باز کرده‌ام.

پرسش‌های پرتکرار درباره CLS

CLS چیست به زبان ساده؟

CLS یا Cumulative Layout Shift معیاری است که اندازه می‌گیرد چیدمان صفحه در طول بارگذاری چقدر جابه‌جا می‌شود. اگر کاربر در حال خواندن یا کلیک باشد و عناصر صفحه ناگهان جابه‌جا شوند، امتیاز CLS بد می‌شود. عدد خوب زیر ۰/۱ است.

آیا CLS روی رتبه گوگل اثر دارد؟

بله، اما اثر آن تعدیل‌گر است. گوگل Core Web Vitals را به‌عنوان بخشی از سیگنال‌های تجربه صفحه در رتبه‌بندی لحاظ می‌کند. اثرش به‌تنهایی بزرگ نیست، اما در رقابت نزدیک بین دو سایت مشابه، می‌تواند تعیین‌کننده باشد. رابطهٔ دقیق را در Core Web Vitals چیست؟ باز کرده‌ام.

چطور CLS را سریع بفهمم کجا مشکل دارد؟

در Chrome DevTools، پنل Performance را باز کنید و ضبط را شروع کنید. بعد از بارگذاری صفحه، بخش Experience را ببینید. پرش‌ها با علامت‌های قرمز مشخص می‌شوند و با کلیک روی هرکدام، دقیقاً می‌بینید کدام عنصر جابه‌جا شده. این سریع‌ترین راه تشخیص است.

آیا استفاده از skeleton screen CLS را کم می‌کند؟

اگر skeleton از ابتدا رزرو شده باشد و ابعاد نهایی محتوا با ابعاد skeleton یکی باشد، بله. اما اگر skeleton ابعاد اشتباهی داشته باشد یا دیرتر نمایش داده شود، خودش منبع CLS می‌شود. قاعدهٔ ساده: skeleton باید دقیقاً جایگزین محتوای نهایی را از ابتدا رزرو کند.

آیا افزونه‌ای برای کاهش CLS در وردپرس وجود دارد؟

به‌طور مستقیم نه، چون CLS یک مشکل ساختاری است که باید از ریشه حل شود. اما بعضی افزونه‌های کش و بهینه‌سازی مثل WP Rocket و Perfmatters گزینه‌هایی برای بهبود بارگذاری فونت و CSS بحرانی دارند که به کاهش CLS کمک می‌کند. توصیهٔ من: اول مشکل ساختاری را در قالب حل کنید، بعد افزونه.

اگر CLS سایت من بالای ۰/۲۵ باشد، چه اقدامی فوری کنم؟

اول در Chrome DevTools مشکل را دقیقاً شناسایی کنید. در ۸۰ درصد مواقع، منبع اصلی یکی از این سه است: تصاویر بدون ابعاد، تبلیغات بدون رزرو فضا، یا فونت با font-display اشتباه. با اعمال سه تکنیک اول این مقاله، معمولاً در یک روز CLS زیر ۰/۱ می‌رسد. اگر بعد از این سه تکنیک هنوز بالا بود، به قالب و افزونه‌های تزریق‌کننده شک کنید.

تصویر نهایی: ثبات چیدمان به‌عنوان یک عادت

کاهش CLS شبیه هیچ‌کدام از بهینه‌سازی‌های دیگر نیست. با سرعت، می‌توانید سرور و کش و تصاویر را یک‌جا بهبود دهید. با CLS، باید تک‌تک اجزای صفحه را از نظر ثبات رفتاری بازبینی کنید. اما خبر خوب این است که برخلاف سرعت که سقفش را هاست و قالب تعیین می‌کنند، CLS سقفش را خودتان تعیین می‌کنید. هر تصویر، هر آی‌فریم، هر فونت و هر دکمه‌ای که با دقت رزرو شود، یک قدم به سمت تجربهٔ بی‌پرش است.

پیشنهاد عملی من سه گام است. اول، همین امروز از صفحهٔ تسویه یا فرم اصلی سایتتان در Chrome DevTools فیلم‌برداری کنید و پرش‌ها را بشمارید. دوم، سه تکنیک اول این مقاله را روی صفحه اعمال کنید. سوم، یک هفته بعد دوباره از Search Console عدد CLS را نگاه کنید. این سه گام، در تجربهٔ من بیشترین اثر را در کوتاه‌ترین زمان دارد.

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