بهینه‌سازی کارایی سایت سینمایی روی موبایل

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

⏱ زمان مطالعه: حدود ۷ دقیقه

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

این درس دربارهٔ همان فاصله است — فاصلهٔ بین «روی دستگاه من کار می‌کند» و «برای همه کار می‌کند». و خبر خوب اینکه بیشتر این فاصله با ده تصمیم ساده پر می‌شود.

بهینه‌سازی کارایی سایت سینمایی روی موبایل

اول بفهمیم گلوگاه واقعی کجاست

یک باور غلط رایج: «انیمیشن سایت را کند می‌کند». در عمل، در نود درصد پروژه‌ها متهم اصلی این‌هاست:

عامل سهم معمول از کندی سختی رفع
تصاویر بهینه‌نشده خیلی زیاد آسان
ویدئوی پس‌زمینهٔ سنگین زیاد آسان
فونت‌های متعدد متوسط آسان
انیمیشن روی ویژگی‌های اشتباه متوسط متوسط
حجم کتابخانه‌ها کم متوسط

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

تصاویر: بزرگ‌ترین برد با کمترین زحمت

۱. قالب مدرن استفاده کن

<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" width="1920" height="1080"
       alt="جادهٔ شبانه" fetchpriority="high" decoding="async">
</picture>

مرورگر اولین قالبی را که می‌شناسد برمی‌دارد. تبدیل یک تصویر جِی‌پِگ چهارمگابایتی به قالب مدرن، معمولاً حجم را به یک‌سوم تا یک‌پنجم می‌رساند — با تفاوت بصری تقریباً صفر.

۲. اندازهٔ درست بده، نه بزرگ‌ترین

<img src="hero-1280.jpg"
     srcset="hero-800.jpg 800w, hero-1280.jpg 1280w, hero-1920.jpg 1920w"
     sizes="100vw"
     width="1920" height="1080" alt="...">

فرستادن تصویر ۱۹۲۰ پیکسلی به گوشی‌ای که ۳۹۰ پیکسل عرض دارد، یعنی هدردادن هشتاد درصد داده.

۳. ابعاد را همیشه بنویس

صفت‌های width و height اختیاری نیستند. بدون آن‌ها، وقتی تصویر لود می‌شود، کل صفحه می‌پرد — همان چیزی که به آن «جابه‌جایی چیدمان» می‌گویند و هم آزاردهنده است هم در سنجه‌های کیفیت سایت جریمه دارد.

۴. ترتیب اولویت را مشخص کن

<!-- تصویر هیرو: بالاترین اولویت -->
<img src="hero.avif" fetchpriority="high">

<!-- بقیهٔ تصاویر: با تأخیر -->
<img src="panel-2.avif" loading="lazy" decoding="async">

یک اشتباه رایج: گذاشتن loading="lazy" روی تصویر هیرو. این کار دقیقاً برعکس عمل می‌کند و اولین چیزی را که کاربر باید ببیند، عقب می‌اندازد.

ویدئوی پس‌زمینه: قاتل خاموش

ویدئوی تمام‌صفحه زیباست و اغلب اشتباه. اگر واقعاً لازم است:

<video autoplay muted loop playsinline
       poster="hero-poster.avif"
       preload="none"
       width="1920" height="1080">
  <source src="hero-720.webm" type="video/webm">
  <source src="hero-720.mp4"  type="video/mp4">
</video>

و در جاوااسکریپت، فقط وقتی لود کن که ارزشش را داشته باشد:

const v = document.querySelector('video');
const slowNet = navigator.connection &&
  (navigator.connection.saveData ||
   /2g|slow-2g|3g/.test(navigator.connection.effectiveType));

if (!isTouch && !slowNet && !reduce){
  v.preload = 'auto';
  v.load();
} // در غیر این‌صورت فقط تصویر poster دیده می‌شود

قواعد عملی ویدئوی پس‌زمینه: حداکثر ۸ ثانیه، حداکثر ۱ مگابایت، بدون صدا، رزولوشن ۷۲۰ کافی است (چون پشت پردهٔ تیره است)، و روی موبایل اصلاً پخش نشود.

انیمیشن روی transform و opacity برای کارایی بهتر

انیمیشن: فقط دو ویژگی امن

این مهم‌ترین نکتهٔ فنی این درس است. مرورگر برای رسم هر فریم سه مرحله دارد: محاسبهٔ چیدمان، رنگ‌آمیزی، و ترکیب لایه‌ها. برخی ویژگی‌ها هر سه مرحله را دوباره اجرا می‌کنند و بعضی فقط آخری را:

ویژگی هزینه حکم
transform فقط ترکیب لایه ✅ امن
opacity فقط ترکیب لایه ✅ امن
filter رنگ‌آمیزی ⚠️ با احتیاط
width، height چیدمان کامل ❌ پرهیز
top، left، margin چیدمان کامل ❌ پرهیز

ترجمهٔ عملی:

/* ❌ غلط — هر فریم چیدمان را دوباره محاسبه می‌کند */
gsap.to('.card', { top: 100, width: 400 });

/* ✅ درست — فقط لایه جابه‌جا می‌شود */
gsap.to('.card', { y: 100, scaleX: 1.2 });

اگر فقط همین یک قاعده را رعایت کنی، بیشتر پرش‌های انیمیشن حل می‌شود.

دربارهٔ will-change محتاط باش

/* ❌ فاجعه — همه‌چیز روی کارت گرافیک */
*{ will-change: transform; }

/* ✅ فقط عناصری که واقعاً و مداوم حرکت می‌کنند */
.hero__media img, .pin__panels .panel { will-change: transform; }

هر عنصری که will-change دارد، یک لایهٔ مستقل در حافظهٔ گرافیکی می‌گیرد. چند ده عنصر یعنی پرشدن حافظه و کندی شدید — دقیقاً برعکس هدفی که داشتی.

موبایل: کمتر همیشه بهتر است

استراتژی درست، «کوچک‌کردن نسخهٔ دسکتاپ» نیست؛ ساختن یک نسخهٔ سبک‌تر است:

روی دسکتاپ روی موبایل
اسکرول نرم خاموش (فیزیک بومی بهتر است)
پین چندمرحله‌ای بخش‌های پشت‌سرهم عادی
پارالاکس چندلایه حذف یا فقط یک لایه
ویدئوی پس‌زمینه تصویر ثابت
تایپوگرافی کلمه‌به‌کلمه ظهور ساده
نوار افقی پین‌شده اسکرول افقی طبیعی با snap

آن آخری را با CSS خالص می‌شود ساخت و بسیار سبک‌تر از نسخهٔ پین‌شده است:

@media (max-width: 899px){
  .proof__track{
    overflow-x:auto;
    scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
  }
  .quote{ scroll-snap-align:center; }
}

مشکل ارتفاع روی موبایل

/* ❌ نوار آدرس که جمع شود، ارتفاع می‌پرد */
.scene--hero{ min-height:100vh; }

/* ✅ ارتفاع کوچک ثابت، بدون پرش */
.scene--hero{ min-height:100svh; }

فونت: نکته‌ای که همه فراموش می‌کنند

@font-face{
  font-family:'Vazirmatn';
  src:url('vazirmatn.woff2') format('woff2');
  font-weight:400 900;          /* فونت متغیر: یک فایل برای همهٔ ضخامت‌ها */
  font-display:swap;            /* متن بلافاصله با فونت جایگزین دیده شود */
}

سه قاعده: فقط قالب woff2، حداکثر دو خانوادهٔ فونت در کل سایت، و font-display:swap تا متن قبل از رسیدن فونت هم خوانا باشد. اگر فونت متغیر در دسترس است، از آن استفاده کن — یک فایل به‌جای پنج فایل.

بارگذاری شرطی کتابخانه های انیمیشن برای موبایل

بارگذاری هوشمند کتابخانه‌ها

چرا باید کاربر موبایل، کتابخانهٔ اسکرول نرم را دانلود کند وقتی قرار نیست استفاده شود؟

async function loadMotion(){
  const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
  const small  = innerWidth < 900;

  if (reduce) return;                       // اصلاً هیچ‌چیز

  await import('https://cdn.jsdelivr.net/npm/[email protected]/+esm');
  await import('https://cdn.jsdelivr.net/npm/[email protected]/ScrollTrigger/+esm');

  if (!small){
    await import('https://unpkg.com/[email protected]/+esm');  // فقط دسکتاپ
  }
  initAnimations({ small });
}
loadMotion();

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

چک‌لیست ده‌مرحله‌ای کارایی

  1. همهٔ تصاویر در قالب مدرن و با چند اندازه.
  2. صفت‌های width و height روی هر تصویر.
  3. تصویر هیرو با fetchpriority="high"، بقیه با loading="lazy".
  4. ویدئو: زیر یک مگابایت یا حذف؛ روی موبایل فقط تصویر.
  5. انیمیشن فقط روی transform و opacity.
  6. ویژگی will-change فقط روی چند عنصر مشخص.
  7. واحد svh به‌جای vh.
  8. فونت متغیر woff2 با font-display:swap.
  9. کتابخانه‌ها به‌صورت شرطی لود شوند.
  10. تست روی گوشی واقعی با حالت شبکهٔ کند.

پرامپت بازبینی کارایی

نقش: مهندس کارایی وب با تمرکز بر صفحات انیمیشن‌محور.

زمینه: [کل کد صفحه]

کار: فقط مشکلات کارایی را پیدا کن. فایل را بازنویسی نکن.

بررسی کن:
- هر انیمیشنی که ویژگی‌های چیدمانی (width/height/top/left/margin)
  را تغییر می‌دهد؛ معادل transform آن را پیشنهاد بده.
- will-change روی چند عنصر گذاشته شده؟ اگر بیش از پنج تاست هشدار بده.
- تصاویر: قالب، srcset، ابعاد، fetchpriority و loading.
- آیا کتابخانه‌ای هست که روی موبایل یا در حالت کاهش حرکت
  بی‌استفاده لود می‌شود؟
- آیا vh به‌جای svh استفاده شده؟
- آیا انیمیشنی روی عنصری بالای صفحه هست که رندر اولیه را عقب بیندازد؟

خروجی: جدول «مشکل | شدت (بالا/متوسط/کم) | اصلاح» و بعد
فقط قطعه‌کدهای اصلاحی به‌ترتیب اولویت.
ممنوع: بازنویسی کل فایل، افزودن کتابخانهٔ جدید.

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

پرسش‌های پرتکرار

آیا باید انیمیشن‌ها را کلاً حذف کنم تا سایت سریع شود؟
تقریباً هیچ‌وقت. انیمیشنِ درست‌پیاده‌شده روی transform و opacity، هزینهٔ ناچیزی دارد. مشکل معمولاً جای دیگری است.

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

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

چطور بفهمم کدام انیمیشن کند است؟
در ابزار توسعه‌دهندهٔ مرورگر، زبانهٔ عملکرد را در حین اسکرول ضبط کن. هر فریمی که بیش از حدود ۱۶ میلی‌ثانیه طول بکشد، مقصر است.

جمع‌بندی

کارایی در این نوع پروژه‌ها بیشتر از آنکه به انیمیشن ربط داشته باشد، به تصاویر و تصمیم‌های بارگذاری برمی‌گردد. قالب مدرن تصویر، ابعاد مشخص، انیمیشن فقط روی transform و opacity، نسخهٔ سبک‌تر برای موبایل و بارگذاری شرطی کتابخانه‌ها — همین پنج مورد معمولاً کار را تمام می‌کند.

در آخرین درس این نقشهٔ راه سراغ موضوعی می‌رویم که کمتر دربارهٔ آن صحبت می‌شود اما اهمیتش کمتر از بقیه نیست: دسترس‌پذیری و احترام به کاهش حرکت. مسیر کامل را در نقشهٔ راه طراحی سایت سینمایی ببین و در @MrChatGPT_IR همراه ما باش.

(0 رأی)

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *