به تعویق انداختن CSS غیرضروری: راهنمای ساده برای بهبود سرعت بارگذاری وب

مهم: این راهنما یک تکنیک پیشرفته برای بهبود عملکرد است که اگر به‌درستی اجرا نشود، ممکن است به اشکالات منجر شود. اکثر وب‌سایت‌ها می‌توانند بدون این تکنیک به اهداف عملکردی توصیه‌شده دست یابند.

مقدمه

فایل‌های CSS منابع مسدودکننده رندر (Render-Blocking) هستند، به این معنا که مرورگر باید آن‌ها را بارگذاری و پردازش کند تا بتواند صفحه را رندر کند. صفحاتی که حاوی فایل‌های CSS بزرگ و غیرضروری هستند، زمان بیشتری برای رندر شدن نیاز دارند. این مقاله به شما نشان می‌دهد که چگونه با به تعویق انداختن CSS غیرضروری، مسیر رندر حیاتی (Critical Rendering Path) را بهینه کنید و First Contentful Paint (FCP) را بهبود دهید.

بارگذاری غیربهینه CSS چیست؟

هنگامی که یک صفحه وب بارگذاری می‌شود، مرورگر باید تمام فایل‌های CSS را قبل از نمایش محتوا پردازش کند. اگر این فایل‌ها شامل سبک‌هایی باشند که برای محتوای قابل‌مشاهده اولیه (Above-the-Fold) ضروری نیستند، زمان رندر صفحه افزایش می‌یابد. به عنوان مثال، فرض کنید یک صفحه شامل یک آکاردئون با سه پاراگراف مخفی است که هر کدام با یک کلاس CSS خاص سبک‌بندی شده‌اند:

[محل قرارگیری تصویر: نمونه آکاردئون در CodePen]
توضیح تصویر: نمونه‌ای از یک صفحه وب با آکاردئون که شامل سه پاراگراف مخفی است.

در این مثال، فایل CSS شامل هشت کلاس است، اما همه آن‌ها برای رندر محتوای قابل‌مشاهده اولیه ضروری نیستند. هدف این راهنما بهینه‌سازی صفحه است تا فقط سبک‌های حیاتی (Critical) به‌صورت هم‌زمان (Synchronous) بارگذاری شوند و سبک‌های غیرضروری به‌صورت غیرهمزمان (Asynchronous) بارگذاری شوند.

اندازه‌گیری عملکرد CSS

برای شناسایی فرصت‌های بهبود، می‌توانید از ابزار Lighthouse در DevTools مرورگر کروم استفاده کنید. مراحل زیر را دنبال کنید:

  1. دموی صفحه را در کروم باز کنید.
  2. DevTools کروم را باز کنید.
  3. به پنل Performance بروید.
  4. صفحه را دوباره بارگذاری کنید.

گزارش Lighthouse نشان می‌دهد که FCP در این صفحه حدود ۱ ثانیه است و فرصت بهبود حذف منابع مسدودکننده رندر (Eliminate Render-Blocking Resources) را برای فایل style.css پیشنهاد می‌کند.

[محل قرارگیری تصویر: گزارش Lighthouse]
توضیح تصویر: گزارش Lighthouse که FCP یک ثانیه و پیشنهاد حذف منابع مسدودکننده رندر را نشان می‌دهد.

توجه: در این دمو از یک فایل CSS کوچک استفاده شده است. در محیط‌های واقعی، فایل‌های CSS بزرگ‌تر هستند. اگر Lighthouse تشخیص دهد که حداقل ۲۰۴۸ بایت از قوانین CSS در رندر محتوای بالای صفحه استفاده نشده است، پیشنهاد حذف CSS استفاده‌نشده (Remove Unused CSS) را نیز نمایش می‌دهد.

در ردیابی عملکرد (Performance Trace)، نشانگر FCP بلافاصله پس از بارگذاری CSS ظاهر می‌شود، به این معنا که مرورگر باید منتظر تکمیل بارگذاری CSS بماند تا حتی یک پیکسل را روی صفحه رندر کند.

[محل قرارگیری تصویر: ردیابی عملکرد DevTools]
توضیح تصویر: ردیابی عملکرد که نشان می‌دهد FCP پس از بارگذاری CSS آغاز می‌شود.

بهینه‌سازی بارگذاری CSS

برای بهینه‌سازی، باید سبک‌های حیاتی را از سبک‌های غیرحیاتی جدا کرده و بارگذاری غیرحیاتی‌ها را به تعویق بیندازید. ابزار Coverage در DevTools به شما کمک می‌کند تا این سبک‌ها را شناسایی کنید:

  1. در DevTools، منوی دستورات (Command Menu) را با فشار دادن Ctrl+Shift+P (یا Cmd+Shift+P در مک) باز کنید.
  2. عبارت "Coverage" را تایپ کرده و Show Coverage را انتخاب کنید.
  3. روی Reload کلیک کنید تا صفحه دوباره بارگذاری شود و گزارش پوشش تولید شود.

[محل قرارگیری تصویر: گزارش Coverage]
توضیح تصویر: گزارش Coverage که نشان می‌دهد ۵۵.۹٪ از بایت‌های CSS استفاده نشده‌اند.

گزارش Coverage نشان می‌دهد:

  • سبک‌های حیاتی (سبز): برای رندر محتوای قابل‌مشاهده (مانند عنوان، زیرعنوان، و دکمه‌های آکاردئون) لازم هستند.
  • سبک‌های غیرحیاتی (قرمز): فقط برای محتوای غیرقابل‌مشاهده (مانند پاراگراف‌های مخفی) استفاده می‌شوند.

مراحل بهینه‌سازی

  1. استخراج سبک‌های حیاتی: سبک‌های سبز را از گزارش Coverage استخراج کرده و در یک بلاک <style> در بخش <head> صفحه قرار دهید:
<style type="text/css">
.accordion-btn {background-color: #ADD8E6;color: #444;cursor: pointer;padding: 18px;width: 100%;border: none;text-align: left;outline: none;font-size: 15px;transition: 0.4s;}
.container {padding: 0 18px;display: none;background-color: white;overflow: hidden;}
h1 {word-spacing: 5px;color: blue;font-weight: bold;text-align: center;}
</style>
  1. بارگذاری غیرهمزمان سبک‌های غیرحیاتی: برای بارگذاری باقی‌مانده کلاس‌ها به‌صورت غیرهمزمان، از الگوی زیر استفاده کنید:
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>

این کد چگونه کار می‌کند؟

  • <link rel="preload" as="style">: فایل CSS را به‌صورت غیرهمزمان بارگذاری می‌کند. برای اطلاعات بیشتر، به راهنمای پیش‌بارگذاری منابع حیاتی مراجعه کنید.
  • ویژگی onload: به مرورگر اجازه می‌دهد CSS را پس از بارگذاری پردازش کند.
  • حذف onload: تنظیم onload=null از فراخوانی مجدد کنترل‌کننده در برخی مرورگرها جلوگیری می‌کند.
  • فال‌بک <noscript>: برای مرورگرهایی که جاوااسکریپت را اجرا نمی‌کنند، یک لینک CSS معمولی ارائه می‌دهد.

در محیط واقعی (Production)

در محیط‌های واقعی، توصیه می‌شود از توابعی مانند loadCSS استفاده کنید که این رفتار را کپسوله کرده و با سیاست‌های امنیتی محتوا (Content Security Policy) سازگار است. همچنین می‌توانید لینک CSS را در انتهای صفحه قرار دهید، اما این روش همچنان ممکن است محتوای حیاتی را مسدود کند.

پایش (Monitoring)

برای بررسی تأثیر بهینه‌سازی، یک ردیابی Performance جدید در DevTools روی صفحه بهینه‌شده اجرا کنید. نشانگر FCP اکنون قبل از درخواست CSS ظاهر می‌شود، به این معنا که مرورگر دیگر منتظر بارگذاری CSS نمی‌ماند.

[محل قرارگیری تصویر: ردیابی عملکرد بهینه‌شده]
توضیح تصویر: ردیابی عملکرد که نشان می‌دهد FCP قبل از بارگذاری CSS آغاز می‌شود.

سپس، Lighthouse را روی صفحه بهینه‌شده اجرا کنید. گزارش نشان می‌دهد که FCP به ۰.۸ ثانیه کاهش یافته است (بهبود ۲۰٪). پیشنهاد حذف منابع مسدودکننده رندر دیگر در بخش Opportunities ظاهر نمی‌شود و در بخش Passed Audits قرار می‌گیرد.

[محل قرارگیری تصویر: گزارش Lighthouse بهینه‌شده]
توضیح تصویر: گزارش Lighthouse که FCP ۰.۸ ثانیه و موفقیت در حذف منابع مسدودکننده را نشان می‌دهد.

مراحل بعدی و منابع

برای محیط‌های پیچیده‌تر، راهنمای استخراج CSS حیاتی ابزارهای محبوب برای استخراج CSS حیاتی را معرفی می‌کند و شامل یک کادلاب برای تمرین عملی است.

نتیجه‌گیری

به تعویق انداختن CSS غیرضروری می‌تواند زمان رندر صفحه را کاهش دهد و تجربه کاربری بهتری ارائه کند. با استفاده از ابزارهایی مانند Coverage و Lighthouse، و با جداسازی سبک‌های حیاتی و بارگذاری غیرهمزمان سبک‌های غیرحیاتی، می‌توانید FCP را بهبود دهید. این تکنیک نیاز به دقت دارد تا از اشکالات احتمالی جلوگیری شود، اما در صورت اجرای صحیح، تأثیر قابل‌توجهی بر عملکرد وب‌سایت خواهد داشت.

تصویر اصلی از Unsplash.


توضیحات اضافی

  • نمودار پیشنهادی: اگر مایل به نمایش نموداری برای مقایسه FCP قبل (۱ ثانیه) و بعد (۰.۸ ثانیه) از بهینه‌سازی هستید، می‌توانم یک نمودار Chart.js ایجاد کنم. لطفاً تأیید کنید. به عنوان مثال:
{
  "type": "bar",
  "data": {
    "labels": ["قبل از بهینه‌سازی", "بعد از بهینه‌سازی"],
    "datasets": [{
      "label": "FCP (ثانیه)",
      "data": [1, 0.8],
      "backgroundColor": ["#FF6384", "#36A2EB"],
      "borderColor": ["#FF6384", "#36A2EB"],
      "borderWidth": 1
    }]
  },
  "options": {
    "scales": {
      "y": {
        "beginAtZero": true,
        "title": {
          "display": true,
          "text": "زمان FCP (ثانیه)"
        }
      },
      "x": {
        "title": {
          "display": true,
          "text": "وضعیت"
        }
      }
    },
    "plugins": {
      "legend": {
        "display": false
      },
      "title": {
        "display": true,
        "text": "مقایسه FCP قبل و بعد از بهینه‌سازی"
      }
    }
  }
}
  • تمرکز خاص: اگر نیاز به توضیحات عمیق‌تر در مورد بخش خاصی (مانند استفاده از loadCSS یا جزئیات Coverage) دارید، لطفاً مشخص کنید.
  • محتوای مرتبط: اگر مایل به مقاله‌ای درباره استخراج CSS حیاتی یا سایر معیارهای Web Vitals هستید، می‌توانم آن را تهیه کنم.

لطفاً بازخورد یا درخواست‌های اضافی خود را ارائه دهید!