Server Side Rendering (SSR)

Server Side Rendering (SSR) adalah teknik rendering dimana HTML halaman web di-generate di server sebelum dikirim ke browser client, berbeda dengan Client Side Rendering yang me-render di browser. SSR adalah salah satu fitur utama [[NextJS Next.js]] untuk meningkatkan [[SEO Optimization SEO]] dan [[Web Performance performance]].

Apa itu SSR?

SSR adalah proses dimana server mengeksekusi JavaScript code, me-render React components menjadi HTML string, dan mengirimkan HTML yang sudah lengkap ke browser.

Alur Kerja SSR

sequenceDiagram
    participant Browser
    participant Server
    participant Database
    
    Browser->>Server: Request halaman
    Server->>Database: Fetch data
    Database->>Server: Return data
    Server->>Server: Render React components
    Server->>Browser: Send complete HTML
    Browser->>Browser: Hydrate JavaScript
    Browser->>Browser: Interactive page

SSR vs CSR vs SSG

Aspek SSR CSR SSG
Rendering Server Client Build time
First Paint Cepat Lambat Sangat cepat
SEO Excellent Poor Excellent
Server Load Tinggi Rendah Rendah
Interactivity Delayed Immediate Delayed
Dynamic Content Yes Yes Limited

Keuntungan SSR

1. SEO Optimization

<!-- HTML yang diterima search engine crawler -->
<html>
<head>
  <title>Product Page - Amazing Product</title>
  <meta name="description" content="This is an amazing product...">
</head>
<body>
  <h1>Amazing Product</h1>
  <p>Product description here...</p>
  <!-- Content sudah ada, bukan loading spinner -->
</body>
</html>

2. Faster First Contentful Paint

  • User melihat content immediately
  • Tidak perlu menunggu JavaScript download
  • Better perceived performance

3. Better Social Media Sharing

<!-- Open Graph tags untuk social sharing -->
<meta property="og:title" content="Amazing Product">
<meta property="og:description" content="Product description">
<meta property="og:image" content="/product-image.jpg">

Kerugian SSR

1. Server Complexity

  • Butuh server yang selalu running
  • Higher server costs
  • Complex caching strategies

2. Slower Time to Interactive (TTI)

  • HTML muncul cepat tapi belum interactive
  • Harus menunggu JavaScript hydration
  • Potential “uncanny valley” effect

3. Server Load

  • Setiap request butuh server processing
  • Scaling challenges untuk traffic tinggi
  • Memory usage per request

Implementasi SSR di Next.js

1. getServerSideProps

// pages/product/[id].tsx
export async function getServerSideProps(context) {
  const { id } = context.params
  
  // Fetch data di server
  const product = await fetch(`https://api.example.com/products/${id}`)
    .then(res => res.json())
  
  // Return props ke component
  return {
    props: {
      product
    }
  }
}

export default function ProductPage({ product }) {
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
    </div>
  )
}

2. App Router SSR

// app/product/[id]/page.tsx
async function getProduct(id: string) {
  const res = await fetch(`https://api.example.com/products/${id}`, {
    cache: 'no-store' // Disable caching for SSR
  })
  return res.json()
}

export default async function ProductPage({ params }) {
  const product = await getProduct(params.id)
  
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    </div>
  )
}

SSR Performance Optimization

1. Caching Strategies

// Cache di berbagai level
export async function getServerSideProps(context) {
  // Set cache headers
  context.res.setHeader(
    'Cache-Control',
    'public, s-maxage=10, stale-while-revalidate=59'
  )
  
  const data = await getCachedData(context.params.id)
  
  return {
    props: { data }
  }
}

2. Streaming SSR

// React 18 Streaming
import { Suspense } from 'react'

export default function Page() {
  return (
    <div>
      <h1>Page Title</h1>
      <Suspense fallback={<ProductSkeleton />}>
        <ProductList />
      </Suspense>
    </div>
  )
}

3. Partial Hydration

// Hydrate hanya komponen yang butuh interactivity
'use client'
import { useState } from 'react'

export default function InteractiveButton() {
  const [count, setCount] = useState(0)
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  )
}

SSR Best Practices

1. Data Fetching

// ✅ Good - Parallel data fetching
export async function getServerSideProps() {
  const [user, posts, comments] = await Promise.all([
    fetchUser(),
    fetchPosts(),
    fetchComments()
  ])
  
  return {
    props: { user, posts, comments }
  }
}

// ❌ Bad - Sequential data fetching
export async function getServerSideProps() {
  const user = await fetchUser()
  const posts = await fetchPosts()
  const comments = await fetchComments()
  
  return {
    props: { user, posts, comments }
  }
}

2. Error Handling

export async function getServerSideProps(context) {
  try {
    const data = await fetchData(context.params.id)
    
    return {
      props: { data }
    }
  } catch (error) {
    // Handle errors gracefully
    if (error.status === 404) {
      return {
        notFound: true
      }
    }
    
    return {
      props: {
        error: 'Failed to load data'
      }
    }
  }
}

3. Security Considerations

export async function getServerSideProps(context) {
  // Validate user authentication
  const session = await getSession(context.req)
  
  if (!session) {
    return {
      redirect: {
        destination: '/login',
        permanent: false
      }
    }
  }
  
  // Only fetch data user has access to
  const data = await fetchUserData(session.userId)
  
  return {
    props: { data }
  }
}

Kapan Menggunakan SSR

✅ Gunakan SSR Ketika:

  • [[SEO Optimization SEO]] sangat penting
  • Content berubah frequently
  • Personalized content per user
  • Real-time data requirements
  • Social media sharing critical

❌ Hindari SSR Ketika:

  • Aplikasi internal/dashboard
  • Content mostly static (gunakan [[SSG Static Site Generation]])
  • High traffic dengan budget terbatas
  • Complex client-side interactions
  • Real-time collaborative apps

SSR Alternatives

1. [[Static Site Generation]] (SSG)

// Generate static pages at build time
export async function getStaticProps() {
  const posts = await fetchPosts()
  
  return {
    props: { posts },
    revalidate: 3600 // ISR - revalidate every hour
  }
}

2. Client Side Rendering (CSR)

// Render di client dengan loading state
export default function ProductPage() {
  const [product, setProduct] = useState(null)
  const [loading, setLoading] = useState(true)
  
  useEffect(() => {
    fetchProduct().then(data => {
      setProduct(data)
      setLoading(false)
    })
  }, [])
  
  if (loading) return <div>Loading...</div>
  
  return <ProductDetails product={product} />
}

3. Incremental Static Regeneration (ISR)

// Best of both worlds - static + dynamic
export async function getStaticProps() {
  const data = await fetchData()
  
  return {
    props: { data },
    revalidate: 60 // Regenerate every 60 seconds
  }
}

Monitoring SSR Performance

1. Key Metrics

  • Time to First Byte (TTFB) - Server response time
  • First Contentful Paint (FCP) - When content appears
  • Time to Interactive (TTI) - When page becomes interactive
  • Cumulative Layout Shift (CLS) - Visual stability

2. Monitoring Tools

// Web Vitals monitoring
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'

getCLS(console.log)
getFID(console.log)
getFCP(console.log)
getLCP(console.log)
getTTFB(console.log)

Kesimpulan

SSR adalah teknik powerful untuk meningkatkan SEO dan perceived performance, tapi datang dengan trade-offs dalam complexity dan server costs.

Pilih SSR ketika:

  • SEO adalah prioritas utama
  • Content dynamic dan personalized
  • Budget server memadai
  • Team memiliki expertise server-side

Pertimbangkan alternatif ketika:

  • Content mostly static → [[Static Site Generation]]
  • Budget terbatas → CSR dengan good loading states
  • Performance critical → ISR untuk balance

Related Notes:

  • [[NextJS Next.js]] - Framework dengan SSR support excellent
  • [[SSG Static Site Generation]] - Alternative rendering strategy
  • [[App Router App Router]] - SSR implementation di Next.js 13+
  • [[Pages Router Pages Router]] - SSR dengan getServerSideProps
  • [[Web Performance Performance Optimization]] - Optimasi performa web
  • [[SEO Optimization SEO]] - Search engine optimization

External Links:

  • [[Next.js SSR Guide::https://nextjs.org/docs/basic-features/pages]]
  • [[React SSR::https://react.dev/reference/react-dom/server]]
  • [[Web Vitals::https://web.dev/vitals/]]