Client Rendering vs Server Rendering — شنو يصير فعلياً
Client Rendering vs Server Rendering — What Actually Happens
أغلب المطورين يكولون إنهم "يعرفون" الفرق بين client-side و server-side rendering. بس لما تسألهم شنو يصير فعلياً — خطوة خطوة — الأمور تصير مو واضحة بسرعة.
خلنا نصلح هذا.
المشكلة بـ "بس نرسل HTML"
لما المستخدم يزور موقعك، المتصفح يحتاج شيئين حتى يعرضله شي مفيد:
- HTML — الهيكل
- JavaScript — السلوك
السؤال هو: وين يتبنى هذا الـ HTML؟
Client-Side Rendering (CSR)
بـ CSR، السيرفر يرسل ملف HTML تقريباً فاضي:
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
خلص. ما كو محتوى. المتصفح يحمّل حزمة الـ JavaScript، يشغلها، وReact يبني كل واجهة المستخدم داخل المتصفح.
شنو يشوف المستخدم:
- شاشة بيضاء فاضية
- سبينر تحميل (لو ضفته)
- الصفحة الكاملة تظهر
المشكلة: الخطوتين 1 و2 ممكن ياخذن 2-5 ثواني بنت اتصال بطيء. وروبوتات محركات البحث (crawlers) كثير مرات ما تشوف شي — بس ذاك الـ <div id="root"> الفاضي.
Server-Side Rendering (SSR)
بـ SSR، السيرفر يسوي الشغل:
User requests /products
↓
Server fetches data from database
↓
Server builds the full HTML string
↓
Browser receives complete HTML
↓
User sees content immediately
المتصفح يستلم HTML حقيقي بمحتوى فعلي. يعرضه فوراً. بعدها React يسوي "hydration" — يربط event listeners بالـ HTML الموجود حتى يصير تفاعلي.
شنو يشوف المستخدم:
- محتوى الصفحة الكامل (تقريباً فوراً)
- الصفحة تصير تفاعلية بعد الـ hydration
المقايضات الحقيقية
| CSR | SSR | |
|---|---|---|
| أول ظهور | بطيء | سريع |
| SEO | ضعيف | ممتاز |
| حمل السيرفر | واطي | عالي |
| التفاعلية | فورية بعد التحميل | تأخير بسيط (hydration) |
| زين لـ | Dashboards، تطبيقات | صفحات تسويقية، مدونات، متاجر |
وين Next.js غيّر كل شي
Next.js App Router جاب موديل جديد: React Server Components (RSC).
الفكرة راديكالية — بعض الـ components أصلاً ما يرسلون أي JavaScript للمتصفح. يترندرون بالسيرفر، يرسلون HTML، وخلص. ما يحتاجون hydration.
// This component runs ONLY on the server
// Zero JavaScript sent to the browser
async function ProductList() {
const products = await db.products.findMany()
return (
<ul>
{products.map(p => <li key={p.id}>{p.name}</li>)}
</ul>
)
}
Client components لسا موجودة — تختارها بـ 'use client' لما تحتاج تفاعلية (useState، useEffect، event handlers).
النموذج الذهني اللي يسهّل الفكرة
تصورها متل مطعم:
- CSR = يعطونك صحن فاضي وتطبخ الأكل بنفسك على الطاولة
- SSR = المطبخ يطبخ الأكل، يرسله جاهز للأكل
- RSC = المطبخ يطبخ الأجزاء الثابتة، وأنت تكمل الأجزاء التفاعلية على الطاولة
أفضل التطبيقات تستخدم الثلاثة مع بعض — server rendering للمحتوى، client rendering للتفاعلية.
شنو أستخدم بهالبورتفوليو
هذا الموقع يستخدم Next.js App Router بـ RSC كافتراضي. صفحات متل /blog، /projects، و/certificates هي Server Components خالصة — تجيب البيانات وتعرض HTML بدون أي JavaScript على جهة العميل. الـ Navbar يستخدم 'use client' لأنه يحتاج usePathname() حتى يبين الرابط النشط.
النتيجة: أول ظهور سريع، SEO زين، وتفاعلية بس وين تحتاجها فعلاً.
هذا هو التوازن الصحيح.