مكونات خادم React: بنية الحزمة الصفرية
من شلالات "useEffect" إلى "غير متزامن/انتظار". نظرة فنية عميقة على RSC وNext.js App Router وإجراءات الخادم والتسلسل الهرمي للتخزين المؤقت.
لمدة 10 سنوات، انجرف نظام React البيئي نحو “كل شيء من جانب العميل”. قمنا ببناء تطبيقات ضخمة للصفحة الواحدة (SPA). لقد جلبنا البيانات في “useEffect”. أظهرنا 10 غزالين أثناء حل الشلالات. وأرسلنا 500 كيلو بايت من JavaScript إلى مستخدم متصل بشبكة 3G في البرازيل، متسائلين عن سبب انخفاض “التحويل”.
مكونات خادم React (RSC) هو التصحيح. إنها ليست مجرد ميزة. إنه تحول معماري أساسي يعيد مركز الجاذبية إلى المكان الذي ينتمي إليه: مركز البيانات.
في Maison Code Paris، قمنا بنقل منصات التجارة الإلكترونية الضخمة إلى Next.js App Router. النتيجة؟ جافا سكريبت أقل بنسبة 40%، وأكبر نسخة محتوى أسرع مرتين (LCP)، وتجربة مطور تبدو وكأنها غش.
لماذا تتحدث Maison Code عن هذا
في Maison Code Paris، نعمل كضمير معمari لعملائنا. غالبًا ما نرث حزمًا “حديثة” تم بناؤها دون فهم أساسي للحجم.
نناقش هذا الموضوع لأنه يمثل نقطة تحول حاسمة في النضج الهندسي. التنفيذ الصحيح يميز MVP الهش عن منصة مؤسسية مرنة يمكنها التعامل مع حركة مرور الجمعة السوداء.
لماذا تراهن Maison Code على RSC
نحن لا نطارد كل إطار عمل جديد. نحن نطارد القيمة الدائمة للعملاء. RSC هي البنية الأولى التي تعمل على مواءمة الأداء الفني مع أهداف العمل:
- SEO: تسليم HTML مثالي لبرامج الزحف (Google Bot يحب RSC).
- التحويل: تفاعلات “إضافة إلى سلة التسوق” أسرع عبر واجهة مستخدم متفائلة.
- الاستدامة: تقليل استنزاف البطارية على أجهزة المستخدم عن طريق إلغاء تحميل العمليات الحسابية على السحابة. نحن نقوم بتدريب جميع شركائنا من الوكالات على هذه المجموعة لأنها تمثل مستقبل التجارة عالية الأداء.
النموذج العقلي: الخادم كشجرة مكونات
في العالم القديم (دليل الصفحات أو إنشاء تطبيق رد فعل)، أرسل الخادم HTML، ووظيفة المفتاح “المرطبة” للعميل. في عالم RSC، يتم تشغيل React على الخادم.
عندما يطلب المستخدم /product/123:
- يعرض الخادم “ProductPage”.
- يتم تنفيذ الأمر “في انتظار db.query()”.
- يحل البيانات.
- يقوم بتسلسل النتيجة إلى تنسيق خاص (بروتوكول الطيران).
- يقوم بدفق هذا إلى المتصفح.
- يعرض المتصفح واجهة المستخدم.
الأهم من ذلك: رمز مكون الخادم لا يغادر الخادم أبدًا.
إذا قمت باستيراد moment.js (200 كيلو بايت) في مكون الخادم لتنسيق تاريخ، فسيقوم المستخدم بتنزيل 0 كيلو بايت منه. إنهم يرون فقط النص “23 نوفمبر 2025”.
جلب البيانات: الموت لـ “useEffect”.
لقد انتهى عصر “تحميل المغازل” الناتج عن منطق العميل. لم نعد نقوم بإنشاء مسارات واجهة برمجة التطبيقات (API) فقط لتغذية الواجهة الأمامية الخاصة بنا.
النمط القديم (Client FetchH):
// مكون العميل
وظيفة المنتج () {
const [data, setData] = useState(null);
استخدام التأثير (() => {
fetch('/api/product').then(res => res.json()).then(setData);
}, []);
إذا (! البيانات) تُرجع <Spinner />؛
إرجاع <div>{data.name}</div>؛
}
النمط الجديد (RSC):
// مكون الخادم
استيراد { ديسيبل } من '@/lib/db'؛
تصدير وظيفة المزامنة الافتراضية ProductPage() {
// الوصول المباشر إلى قاعدة البيانات. يؤمن. سريع.
بيانات const = انتظار db.product.findFirst();
إرجاع <div>{data.name}</div>؛
}
هذا يعمل على الخلفية. البيانات تنتظر المستخدم، وليس العكس.
التفاعل: توجيه “استخدام العميل”.
لكن HTML الثابت ممل. نحن بحاجة إلى أزرار “أضف إلى السلة”. نحن نعيد تقديم التفاعل باستخدام مكونات العميل. يمكنك وضع علامة على ملف باستخدام “استخدام العميل”. وهذا يخبر Next.js: “قم بتضمين هذا الملف في حزمة JavaScript.”
نمط التركيب: استراتيجية “النقطة”. لا تجعل الصفحة بأكملها مكون عميل. قم بعمل أوراق مكونات العميل.
// مكون الخادم (التخطيط)
تصدير وظيفة المزامنة الافتراضية Page() {
منتج const = انتظار db.product.findFirst();
العودة (
<ديف>
<h1>{product.title}</h1> {/* حجم الحزمة صفر * /}
<PriceDisplay value={product.price} /> {/* حجم الحزمة صفر * /}
<AddToCartButton id={product.id} /> {/* مكون العميل (تفاعلي) */}
</div>
);
}
إجراءات الخادم: طفرات النوع الآمن
كيف نرسل النماذج؟ “طرق واجهة برمجة التطبيقات”؟ “أكسيوس”؟ “الراحة”؟ رقم إجراءات الخادم. نكتب دالة تعمل على الخادم، ونمررها كدعم للنموذج.
// الإجراءات.ts
"استخدام الخادم"
تصدير وظيفة غير متزامنة addToCart(formData: FormData) {
const ProductId =formData.get('productId');
انتظر db.cart.create({ ProductId });
// أخبر ذاكرة التخزين المؤقت المحلية بالتحديث
إعادة التحقق من المسار('/العربة');
}
// Button.tsx
استيراد { addToCart } من './actions'؛
وظيفة التصدير AddToCartButton () {
العودة (
<إجراء النموذج={addToCart}>
<button type="submit">إضافة</button>
</النموذج>
)
}
يعمل هذا ** بدون تمكين JavaScript ** (التحسين التدريجي). إذا تم تحميل JS، فإن Next.js يعترض عملية الإرسال ويقوم باستدعاء واجهة برمجة التطبيقات بشكل فعال. ولكن يبدو الأمر وكأنه استدعاء وظيفة.
واجهة المستخدم المتفائلة: استخدام المتفائل
عندما ينقر المستخدم على “إضافة”، نريد الحصول على تعليقات فورية. لا نريد أن ننتظر ذهابًا وإيابًا للخادم. يقدم RSC “useOptimistic”.
"استخدام العميل"
استيراد { useOptimistic } من 'react'؛
وظيفة التصدير LikeButton({ likeCount, action }) {
const [optimisticLikes, addOptimisticLike] = useOptimistic(
مثلالكونت,
(الحالة، نيولايك) => الحالة + 1
);
العودة (
<زر onClick={غير متزامن () => {
addOptimisticLike(1); // تحديث فوري لواجهة المستخدم
انتظر الإجراء () ؛ // مزامنة خلفية الخادم
}}>
الإعجابات: {optimisticLikes}
</زر>
);
}
التسلسل الهرمي للتخزين المؤقت
يقوم Next.js بتطبيق التخزين المؤقت القوي لجعل مراكز RSC سريعة. إن فهم هذا التسلسل الهرمي هو الجزء الأصعب في منحنى التعلم.
- طلب التذكير: إذا قمت باستدعاء
getUser()في التخطيط، وgetUser()في الصفحة، فسيقوم Next.js بإزالته. يتم تشغيله مرة واحدة فقط لكل طلب. - ذاكرة التخزين المؤقت للبيانات: يتم تخزين نتيجة
الجلبعلى القرص الموجود على الخادم. ويستمر عبر الطلبات.fetch('...', { next: { العلامات: ['المنتجات'] } }) - ** ذاكرة تخزين مؤقت كاملة للمسار **: يتم تخزين حمولة HTML + Flight المعروضة مؤقتًا في وقت الإنشاء (إنشاء موقع ثابت).
- ذاكرة التخزين المؤقت لجهاز التوجيه: يقوم المتصفح بتخزين الصفحات التي تمت زيارتها مؤقتًا في الذاكرة لمدة 30 ثانية للتنقل الفوري للخلف/للأمام.
البطلان:
عندما تقوم بتحديث منتج، يجب عليك استدعاء revalidateTag('products') في إجراء الخادم الخاص بك. يؤدي هذا إلى تطهير الطبقة الثانية والطبقة الثالثة على الفور.
10. العرض المسبق الجزئي (PPR)
ثابت (SSG) سريع ولكنه قديم. الديناميكي (SSR) جديد ولكنه بطيء. قدم Next.js 14 PPR. إنه نمط “الثقب في الدونات”. يتم عرض Shell (الرأس والتذييل والشريط الجانبي) مسبقًا في وقت الإنشاء. “سعر المنتج” هو الثقب. يتم تحميله بشكل ديناميكي. يحصل المستخدم على HTML فوري (The Shell)، وتدفق الأجزاء الديناميكية خلال 100 مللي ثانية لاحقًا. يؤدي هذا إلى منع ظهور “شاشة الموت البيضاء” أثناء استعلامات قاعدة البيانات.
11. حدود البث والتشويق
يقوم RSC بتقسيم الصفحة إلى أجزاء.
إرجاع <التشويق الاحتياطي={<Skeleton />}><SlowComponent /></Suspense>
يرسل الخادم رأس HTTP ترميز النقل: مقسم.
- القطعة 1:
<html>...<nav>... <Skeleton> - (انتهاء قاعدة البيانات)
- الجزء 2:
<script>replace(Skeleton, RealContent)</script>يعد وقت أول بايت (TTFB) أمرًا بالغ الأهمية لتحسين محركات البحث والأداء المتصور.
13. RSC مقابل هندسة الجزيرة (Astro)
قامت شركة Astro بترويج “الجزر” (HTML الثابت + فتحات صغيرة للتفاعل). RSC مشابه ولكنه مختلف.
- Astro: قم بشحن 0 JS بشكل افتراضي. هيدرات بشكل صريح
<عميل العداد:تحميل />. - RSC: شحن 0 JS بشكل افتراضي. هيدرات المكونات التي تحمل علامة “استخدام العميل”. الفرق هو جهاز التوجيه. يحتوي Next.js على جهاز توجيه من جانب العميل (يشعر SPA). يستخدم Astro التنقل متعدد الصفحات (إحساس كلاسيكي). بالنسبة للتجارة الإلكترونية (حيث يعد الحفاظ على حالة سلة التسوق عبر عمليات تحميل الصفحات أمرًا حيويًا)، فإن نموذج Next.js/RSC يتفوق بشكل عام على نموذج MPA النقي.
14. إدارة الدولة في عالم RSC
أين يذهب ريدوكس؟ في أي مكان. أنت لا تحتاج إليها. إذا كانت الحالة هي “بيانات الخادم” (المنتجات، ملف تعريف المستخدم)، فهي موجودة في مكون الخادم (يتم جلبها لكل طلب). إذا كانت الحالة هي “حالة واجهة المستخدم” (Modal Open، Accordion Expanded)، فإنها تعيش في “useState” داخل ورقة مكون العميل. نحن نستخدم فقط Global State (Zustand/Context) لبيانات العميل العالمية الحقيقية: Cart وAuth Token. يتم حذف كل شيء آخر (90٪ من متاجر Redux القديمة).
15. الاستنتاج
تعد مكونات React Server أكبر تغيير في تطوير الواجهة الأمامية منذ تقديم AJAX. إنها تسمح لنا ببناء “MPAs (تطبيقات متعددة الصفحات) بروح SPA”. لقد حصلنا على تحسين محركات البحث والأداء والبساطة في عرض الخادم. نحصل على التفاعل الغني لـ React.
بالنسبة للتجارة الإلكترونية واسعة النطاق، حيث يرتبط كل مللي ثانية من زمن الوصول بالإيرادات، فإن RSC هي البنية الوحيدة القابلة للتطبيق على مدى السنوات الخمس القادمة.
هل تريد الهجرة إلى Next.js؟
هل أنت عالق في تطبيق إنشاء رد فعل بطيء؟