المدونة

Client Rendering vs Server Rendering — شنو يصير فعلياً

وقت القراءة 3 دقيقةAR
Next.jsReactWeb Performance

Client Rendering vs Server Rendering — What Actually Happens

أغلب المطورين يكولون إنهم "يعرفون" الفرق بين client-side و server-side rendering. بس لما تسألهم شنو يصير فعلياً — خطوة خطوة — الأمور تصير مو واضحة بسرعة.

خلنا نصلح هذا.


المشكلة بـ "بس نرسل HTML"

لما المستخدم يزور موقعك، المتصفح يحتاج شيئين حتى يعرضله شي مفيد:

  1. HTML — الهيكل
  2. 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. سبينر تحميل (لو ضفته)
  3. الصفحة الكاملة تظهر

المشكلة: الخطوتين 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 الموجود حتى يصير تفاعلي.

شنو يشوف المستخدم:

  1. محتوى الصفحة الكامل (تقريباً فوراً)
  2. الصفحة تصير تفاعلية بعد الـ hydration

المقايضات الحقيقية

CSRSSR
أول ظهوربطيءسريع
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 زين، وتفاعلية بس وين تحتاجها فعلاً.

هذا هو التوازن الصحيح.