Gryffin Forge
الواجهة الأماميةالأداءالحركة

أقسام فيديو مرتبطة بالتمرير دون تدمير الأداء

كيف تبني قسم فيديو ومعرضًا مثبّتًا ومرتبطًا بالتمرير يبدو سينمائيًا لكنه يبقى سريعًا على الهواتف: قيمة تقدّم واحدة، وفيديو واحد يعمل، وبلا مكتبات.

قراءة 3 دقيقةGryffin Forge

تحب المواقع الفاخرة قسمًا مثبّتًا ينفتح فيه الفيديو مع التمرير وتتغير التعليقات فصلًا بعد فصل. وهو أيضًا من أسهل الطرق لجعل الصفحة متقطعة وثقيلة ومستهلكة للبطارية. إليك كيف بُني قسم العرض المستخدم في مكتبة العروض ليبقى سريعًا.

قيمة تقدّم واحدة تقود كل شيء

القسم حاوية طويلة بداخلها منصة ثابتة. ومع التمرير يحسب النص البرمجي رقمًا واحدًا — كم قطع الزائر من الحاوية، من 0 إلى 1 — وكل ما عداه يُشتق منه:

  • إزاحة clip-path التي تفتح الفيديو المؤطر حتى عرض الشاشة،
  • تكبير خفيف للفيديو النشط،
  • أي فصل (مقطع وتعليق) نشط،
  • عرض شريط التقدم،
  • تلاشي العنوان وانجرافه.

تُكتب القيم كخصائص CSS مخصصة، ويتولى CSS الباقي. لا يوجد خط زمني للحركة لكل عنصر يجب مزامنته، ولا مكتبة حركة للتنزيل.

const p = clamp(-rect.top / (rect.height - innerHeight));
stage.style.setProperty('--p', p);

اجمع القراءات والكتابات في إطار واحد

أحداث التمرير تنطلق أسرع من تحديث الشاشة. يكتفي المعالج بجدولة العمل عبر requestAnimationFrame، وفي كل إطار يقرأ التخطيط أولًا ثم يكتب الأنماط. خلط القراءة والكتابة يفرض إعادة حساب التخطيط مرارًا، وهو أشيع سبب لتقطع التمرير.

فيديو واحد فقط يعمل

ثلاثة فيديوهات تعمل تلقائيًا معًا ستسخّن الهاتف وتستنزف البيانات. القواعد:

  • يُحمَّل المقطع الأول فورًا كي لا يكون القسم فارغًا أبدًا.
  • تبدأ المقاطع الأخرى بـpreload="none".
  • حين يصبح فصل نشطًا يعمل مقطعه، ويُرقّى المقطع التالي إلى التحميل المسبق.
  • تتوقف المقاطع غير النشطة بعد انتهاء تلاشيها.
  • حين يغادر القسم كله مجال الرؤية، يتوقف كل شيء.

كل المقاطع صامتة ومتكررة وplaysinline، وهذا مطلوب للتشغيل التلقائي في متصفحات الجوال.

حرّك الخصائص الرخيصة

يمكن لمعالج الرسوميات تركيب opacity وtransform وclip-path. أما تحريك top أو width أو background-position على عناصر كبيرة فيستدعي إعادة التخطيط أو إعادة الرسم. يتحرك المعرض الأفقي بـtranslate3d، ويزيح المنظور المتحرك لكل بطاقة صورة داخلية بتحويل بدلًا من تغيير موضعها.

قدّم الفيديو بحكمة

المقاطع بدقة 720p، بضعة ميغابايتات لكل منها، تُقدَّم عبر وكيل على الحافة يخزنها مؤقتًا ويدعم طلبات النطاقات في HTTP كي تستطيع المتصفحات التنقل والبث. وتأتي صور الغلاف من لقطات ثابتة ليظهر شيء ذو معنى قبل فك ترميز الإطار الأول.

احترم تقليل الحركة

حين يطلب الزائر من نظامه تقليل الحركة، يتوقف تثبيت القسم، ويصبح المعرض صفًا عاديًا قابلًا للتمرير، ويظهر النص دون حركة. المحتوى مطابق؛ وتُزال الحركات الاستعراضية فقط.

دافع عن أنماطك

يُحقن هذا القسم في قوالب مختلفة كثيرة، وكان في أحدها قاعدة grid عامة باسم .gal أطاحت مسار المعرض بصمت. الآن تحمل كل فئة في المكوّن بادئة. إن كنت تبني مكونات توضع في صفحات لا تتحكم بها، فمساحات الأسماء ليست اختيارية.

الخلاصة

  • اشتق كل شيء من قيمة تقدّم تمرير واحدة.
  • جدول بـrequestAnimationFrame؛ اقرأ ثم اكتب.
  • فيديو واحد يعمل؛ تحميل مسبق في الوقت المناسب؛ إيقاف خارج الشاشة.
  • حرّك فقط الخصائص الملائمة للمركِّب.
  • خزّن الفيديو مؤقتًا وقدّمه بالنطاقات على الحافة.
  • احترم prefers-reduced-motion.
  • أعطِ الأنماط المحقونة مساحة أسماء.