Next.js

Next.js View Transitions: رسوم متحركة أصلية بدون JS

استبدل مكتبات الرسوم المتحركة الثقيلة بـ Next.js view transitions لبناء انتقالات سلسة تماما وبدون JavaScript مباشرة داخل App Router الخاص بك.

By Mohamed DjoudirMay 18, 202610 min read
مشاركة:
Next.js View Transitions: رسوم متحركة أصلية بدون JS
#next.js-view-transitions#react-19#app-router#zero-js-animations#tailwind-v4

إن توفير رسوم متحركة سلسة للصفحات كان يعني سابقًا تثبيت مكتبات JavaScript ضخمة والتعامل مع دورات حياة المكونات المعقدة. بالنسبة للوحات تحكم SaaS والصفحات المقصودة، كان هذا يعني التضحية بحجم الحزمة والأداء من أجل الحصول على مظهر مرئي مصقول. يعمل React 19 و Next.js 16 على تغيير هذه المعادلة تمامًا من خلال كشف قدرات المتصفح الأصلية مباشرة لمكوناتك. يمكنك الآن استبدال التبعيات الثقيلة لجهات خارجية وبناء تأثيرات انتقال سلسة أصلية باستخدام Next.js view transitions.

ما هي Next.js view transitions؟

تعتبر Next.js view transitions رسومًا متحركة أصلية للمتصفح يتم تشغيلها بواسطة مكون React 19 <ViewTransition> أثناء تنقلات App Router، مما يخلق تحولًا مرئيًا سلسًا بين الصفحات دون حمولات JavaScript ثقيلة.

تاريخياً، كان تحريك تغييرات المسارات على الويب صعباً للغاية. اعتمد المطورون على أدوات معقدة لمراقبة حالات المسار وتحريك عقد DOM يدوياً. تقوم واجهة برمجة التطبيقات الأصلية View Transitions API بتفويض هذا العمل الثقيل بالكامل إلى محرك العرض في المتصفح. عند حدوث التنقل، يلتقط المتصفح لقطة مرئية محسنة للغاية للصفحة الصادرة. ثم يوقف العرض مؤقتًا لجزء من الثانية، ويلتقط لقطة جديدة للصفحة الواردة، ويقوم بالاستيفاء بسلاسة بين اللقطتين باستخدام خصائص CSS الأصلية.

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

تأثير الأداء للرسوم المتحركة بدون JS

لطالما حمل الاعتماد على مكتبات الرسوم المتحركة المعتمدة على JavaScript ضريبة أداء كبيرة. فالمكتبات التي تتعامل مع تحولات التخطيط المعقدة غالبًا ما تضيف 30 كيلوبايت إلى 50 كيلوبايت من JavaScript المصغر إلى التحميل الأولي للصفحة. بالنسبة للصفحات المقصودة التي تركز على التحويل، فإن هذا التضخم يقلل بشكل مباشر من مقاييس أداء الويب الأساسية الخاصة بك.

عندما تنتقل إلى Next.js view transitions، يكون تأثير الأداء فوريًا. أنت تقلل بشكل كبير من Total Blocking Time (TBT) و Interaction to Next Paint (INP) لأن السلسلة الرئيسية لم تعد مثقلة بحساب مواضع العناصر إطارًا بإطار أثناء تغييرات المسار. لا تعتمد واجهات برمجة تطبيقات المتصفح الأصلية على تحديثات حالة React لاستيفاء البكسلات.

تظل الرسوم المتحركة سلسة تمامًا حتى لو تم حظر السلسلة الرئيسية لفترة وجيزة بسبب جلب أو تحليل أصول أخرى. تبدو لوحات تحكم SaaS على الفور أسرع وأكثر استجابة. من خلال التخلص من التبعيات الضخمة واعتماد رسوم المسارات الأصلية، فإنك تقدم نفس الجودة المرئية تمامًا بجزء بسيط من العبء الحسابي.

تفعيل View Transitions في Next.js 16 App Router

قبل نشر view transitions الأصلية، يجب عليك تكوين بيئة إطار العمل الخاص بك. بينما يتضمن Next.js 16.2 دعمًا مدمجًا لواجهات برمجة تطبيقات React الأساسية، لا يزال التكامل حاليًا خلف علامة تجريبية محددة.

يجب عليك تفعيل هذه الميزة داخل ملف next.config.ts في جذر مشروعك.

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    // تفعيل انتقالات العرض الأصلية من React 19 لـ App Router
    viewTransition: true,
  },
};

export default nextConfig;

بمجرد تفعيله، يقوم Next.js تلقائيًا بتوجيه دورة حياة التنقل الداخلية لـ App Router. لست بحاجة إلى إعادة كتابة منطق تطبيقك. يتكامل كل تنقل قياسي باستخدام المكون <Link> والاستدعاء البرمجي useRouter().push() أصليًا مع سياق الانتقال.

ينسق مكون React 19 <ViewTransition> بسلاسة توقيت اللقطة مع ذاكرة التخزين المؤقت لجهاز التوجيه في Next.js ومراحل العرض، مما يمنع أخطاء المزامنة الهشة التي ابتليت بها التطبيقات اليدوية السابقة.

النمط الأول: انتقالات التلاشي المتقاطع السلسة للصفحات

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

لتنفيذ انتقال عام، قم بتغليف محتويات التخطيط الرئيسي الخاص بك بمكون React الأصلي <ViewTransition> داخل ملف التخطيط الجذري.

// app/layout.tsx
import { ViewTransition } from 'react';
import './globals.css';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {/* يلتقط تلقائيًا لقطات DOM الهيكلية أثناء تغييرات المسار */}
        <ViewTransition>
          <main className="min-h-screen bg-slate-50">
            {children}
          </main>
        </ViewTransition>
      </body>
    </html>
  );
}

في هذا التكوين، يقوم المتصفح تلقائيًا بتنفيذ تلاشي متقاطع موجز وأنيق عندما يتنقل المستخدمون بين الصفحات. نحن نحذف عمدًا خاصية name في هذا الغلاف العام. عند حذف name، تقوم React بذكاء بإنشاء معرف داخلي معزول لنطاق الانتقال، مما يمنع تصادمات الرسوم المتحركة العرضية.

النمط الثاني: انتقالات العناصر المشتركة (من صورة مصغرة إلى صورة رئيسية)

تكمن القوة الحقيقية لـ <ViewTransition> في انتقالات العناصر المشتركة. يقوم هذا النمط بتحويل مكون واجهة مستخدم معين من مسار واحد مباشرة إلى مكون مختلف هيكليًا في المسار التالي. فكر في صورة مصغرة تتوسع إلى صورة بارزة تمتد بكامل الشاشة.

لتحقيق هذا التأثير، يجب عليك تغليف العناصر المرئية المستهدفة في كل من الصفحتين الصادرة والواردة بـ <ViewTransition>، وبشكل حاسم، تعيين نفس خاصية name الدقيقة لهما.

بناء المسار الصادر

إليك صفحة شبكة المنتجات الصادرة:

// app/products/page.tsx
import { ViewTransition } from 'react';
import Link from 'next/link';

export default function ProductGrid() {
  return (
    <div className="grid grid-cols-3 gap-4 p-8">
      <Link href="/products/sneakers">
        {/* يجب أن يتطابق name بدقة مع صفحة الوجهة */}
        <ViewTransition name="product-hero-sneakers">
          <img 
            src="/images/sneakers-thumb.jpg" 
            alt="Sneakers" 
            className="w-48 h-48 rounded-md shadow-sm" 
          />
        </ViewTransition>
      </Link>
    </div>
  );
}

ربط المسار الوارد

في مسار الوجهة، قم بتعيين المعرف الدقيق نفسه للعنصر الأكبر. يتعامل المتصفح مع تحول التخطيط الموضعي والتحجيم البعدي تلقائيًا.

// app/products/sneakers/page.tsx
import { ViewTransition } from 'react';

export default function ProductDetail() {
  return (
    <section className="p-8 max-w-4xl mx-auto">
      {/* يتطابق مع معرف المسار الوارد لتشغيل التحول */}
      <ViewTransition name="product-hero-sneakers">
        <img 
          src="/images/sneakers-hero.jpg" 
          alt="Sneakers" 
          className="w-full h-96 rounded-xl object-cover shadow-lg" 
        />
      </ViewTransition>
      
      <h1 className="text-3xl font-bold mt-6">Premium Sneakers</h1>
    </section>
  );
}

يقوم المتصفح أصليًا باستيفاء الإحداثيات الدقيقة، العرض، الارتفاع، واختلافات نصف قطر الحدود بين اللقطتين، مما يولد تحولًا مرئيًا معقدًا بدون حساب JavaScript واحد.

تنسيق View Transitions باستخدام Tailwind CSS v4

بينما تقوم React بتجريد إدارة دورة حياة DOM، يتعامل محرك المتصفح في النهاية مع الاستيفاء المرئي. افتراضيًا، يطبق المتصفح تلاشيًا متقاطعًا بسيطًا لمدة 250 مللي ثانية. يمكنك تجاوز هذه الإعدادات الافتراضية باستخدام Tailwind v4 في CSS العام الخاص بك.

يعرض المتصفح بشكل أصلي عنصرين زائفين أساسيين أثناء دورة حياة اللقطة: ::view-transition-old() للقطة الثابتة الصادرة، و ::view-transition-new() للقطة المعروضة الواردة. باستهداف هذه العناصر الزائفة، يمكنك تخصيص السلوك تمامًا.

/* app/globals.css */
@import "tailwindcss";

/* استهداف الانتقال المحدد عن طريق خاصية name الدقيقة */
::view-transition-old(product-hero-sneakers),
::view-transition-new(product-hero-sneakers) {
  animation-duration: 600ms;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* إنشاء رسوم متحركة مخصصة للانزلاق لأعلى للجذر العام */
::view-transition-new(root) {
  animation: fade-in 300ms ease-out, slide-up 400ms cubic-bezier(0.16, 1, 0.3, 1);
}

::view-transition-old(root) {
  animation: fade-out 300ms ease-in;
}

@keyframes slide-up {
  from { 
    transform: translateY(20px) scale(0.98); 
  }
  to { 
    transform: translateY(0) scale(1); 
  }
}

نظرًا لأن Tailwind CSS v4 يستخدم محرك CSS فقط فائق السرعة، فإن دمج الإطارات الرئيسية المباشرة إلى جانب فئات الأدوات المساعدة يوفر التوازن المثالي بين التنسيق المحدد والتحكم الشامل في الانتقال.

هل لا تزال بحاجة إلى Framer Motion؟

مع دمج رسوم متحركة صفرية JS الأصلية بعمق في React 19، يواجه المطورون قرارًا معماريًا: هل ما زلت بحاجة إلى مكتبات خارجية ثقيلة؟ إليك كيف تقارن التنفيذ الأصلي مع الأدوات القياسية للصناعة.

الميزة React ViewTransition Framer Motion
تكلفة حزمة العميل 0 كيلوبايت (واجهة متصفح أصلية) ~30 كيلوبايت (مصغر ومضغوط)
تغيير المسار أصلي عبر خاصية name يتطلب غلاف AnimatePresence
محرك الفيزياء تسهيلات CSS cubic-bezier رياضيات زنبرك وقصور ذاتي معقدة
إيماءات معقدة غير مدعوم أصلياً مدعوم بالكامل (سحب، تمرير)
حالة الاستخدام الرئيسية تغييرات التخطيط، المسارات تفاعلات دقيقة، تحولات SVG معقدة

بالنسبة لتطبيقات SaaS الحديثة ومواقع التسويق، تتعامل رسوم المسارات الأصلية بسلاسة مع الغالبية العظمى من انتقالات التخطيط. يجب عليك الاحتفاظ بـ Framer Motion فقط إذا كان منتجك يتطلب بشكل خاص آليات سحب وإفلات معقدة أو تفاعلات دقيقة ثقيلة قائمة على الفيزياء.

الأخطاء الشائعة

  • إعادة استخدام خاصية name داخل حلقة: استخدام قيمة ثابتة مثل name="product-card" داخل حلقة .map() يكسر منطق لقطة التخطيط بالكامل. الحل: قم بإنشاء معرفات فريدة ديناميكيًا باستخدام البيانات، مثل name={"product-card-" + item.id}.
  • تطبيق خاصية name على التخطيطات العامة: ستؤدي إضافة name ثابت إلى التخطيط الجذري <ViewTransition> إلى حدوث التقطيع في الأبعاد عند التنقل بين صفحات ذات ارتفاعات مختلفة. الحل: احذف خاصية name تمامًا لتأثيرات التلاشي المتقاطع العامة القياسية للدخول والخروج.
  • نسيان العلامة التجريبية لـ Next.js: سيتم عرض مكون React، ولكن التنقلات ستحدث على الفور دون رسوم متحركة. الحل: تأكد بوضوح من تكوين experimental: { viewTransition: true } بشكل صحيح داخل next.config.ts الخاص بك.
  • تجاهل دعم المتصفح: لا تعمل view transitions حاليًا في إصدارات Safari القديمة. الحل: لا تفعل شيئًا. تتراجع الواجهة البرمجية بكياسة، وتعود إلى تحميلات الصفحات الفورية دون إلقاء أخطاء من جانب العميل.

FAQ

How do I add page transitions in Next.js 16?

قم بتفعيل إعداد experimental.viewTransition داخل ملف تكوين next.config.ts الخاص بك، ثم قم بتغليف التخطيط الجذري الخاص بك أو مكونات صفحة محددة بمكون React 19 <ViewTransition> الأصلي. يلتقط هذا تلقائيًا تنقلات App Router اللاحقة ويطبق تلاشيًا متقاطعًا أصليًا سلسًا للمتصفح بين حالات التطبيق الصادرة والواردة.

Does Next.js support the View Transitions API?

نعم، يدعم Next.js 16 واجهة برمجة التطبيقات View Transitions الأصلية بشكل شامل من خلال تكامل React 19. يعترض إطار العمل تنقلات App Router أصليًا ويتعامل مع دورة حياة لقطة الانتقال الأساسية تلقائيًا، مما يضمن ألا يحتاج المطورون بعد الآن إلى تعديل وظائف router.push() القياسية يدويًا.

What is the alternative to Framer Motion in Next.js?

يعد مكون <ViewTransition> الأصلي من React البديل الأفضل على الإطلاق لـ Framer Motion للتعامل مع الرسوم المتحركة المستندة إلى المسار. من خلال الاعتماد الحصري على واجهات برمجة تطبيقات المتصفح الأصلية وعناصر CSS الزائفة، فإنه يقدم تحولًا سلسًا للعناصر المشتركة دون إرسال أي حمولة JavaScript إضافية إلى المستخدمين.

How to use React ViewTransition component?

قم باستيراد <ViewTransition> مباشرة من حزمة react الأساسية وقم بتغليف عناصر واجهة المستخدم المستهدفة. للحصول على تأثيرات التحول بين الصفحات، ببساطة قم بتغليف كل من العناصر الصادرة والواردة بـ <ViewTransition> وقدم خاصية name نصية متطابقة تمامًا لربطها أثناء دورة العرض.

الخاتمة

تقوم Next.js view transitions بتبسيط جذري لكيفية قيام المطورين ببناء تطبيقات ويب عالية التفاعل ومصقولة. من خلال استخدام مكون React 19 <ViewTransition> بشكل أصلي داخل App Router، يمكنك باستمرار تحقيق رسوم متحركة سلسة تمامًا وبدون JS والتي كانت مقصورة سابقًا على مكتبات JavaScript الثقيلة. تذكر أن تقوم بتعيين خصائص name فريدة تمامًا لانتقالات العناصر المشتركة، واستخدم Tailwind CSS العام الخاص بك لتحسين مدة التحول.

إذا كنت مستعدًا لتقديم لوحات تحكم فائقة السرعة وواجهات متحركة بشكل جميل دون تضخم الحزمة، استكشف admin dashboard templates الجاهزة للإنتاج والمبنية خصيصًا للأطر الحديثة على Aniq UI.

هل وجدت هذا المقال مفيدًا؟

مشاركة:
world map

مجتمع المستخدمين العالمي

انضم إلى آلاف المطورين في جميع أنحاء العالم الذين يثقون بـ Aniq-UI لمشاريعهم. يتم استخدام قوالبنا في جميع أنحاء العالم لإنشاء تجارب ويب مذهلة.

تواصل معنا

Need custom work or reskin? Get in touch with us

Aniq-uiAniq-uiAniq-ui