ข้ามไปยังเนื้อหา

SSR, CSR และ Prerendering

Next.js กำหนด rendering mode ผ่านฟังก์ชัน getServerSideProps, getStaticProps, หรือ React Server Components SvelteKit ใช้แนวทางที่สม่ำเสมอกว่า: ทุก page มีค่า default เป็น SSR และคุณ opt out ได้ต่อ page ผ่าน page options ที่ export ออกมาจาก +page.js หรือ +layout.js

เมื่อ user เปิดหน้าเว็บเป็นครั้งแรก SvelteKit จะ render บนฝั่ง server แล้วส่ง HTML ไปพร้อมกับ JavaScript สำหรับ hydration — เหมือนกับ Next.js SSR ทุกประการ แต่คุณไม่ต้องเลือก mode ใด ๆ เป็น default อยู่แล้ว

React
// Next.js App Router — SSR คือ default สำหรับ Server Components
// app/products/page.tsx
async function ProductsPage() {
const products = await fetchProducts(); // รันบน server
return (
<ul>
{products.map(p => (
<li key={p.id}>{p.name}</li>
))}
</ul>
);
}
export default ProductsPage;
Svelte
<!-- src/routes/products/+page.server.js -->
export async function load() {
const products = await fetchProducts(); // รันบน server
return { products };
}
<!-- src/routes/products/+page.svelte -->
<script>
let { data } = $props();
</script>
<ul>
{#each data.products as product}
<li>{product.name}</li>
{/each}
</ul>

+page.server.js ไม่เคยส่งโค้ดไปยัง browser เลย — ปลอดภัยสำหรับ database queries, API keys, และ secrets ทุกอย่าง

บาง page ไม่จำเป็นต้องใช้ SSR เช่น dashboard ที่ต้องการ authentication หรือ page ที่ข้อมูลทั้งหมดโหลดจาก client-side ส่ง ssr = false เพื่อบอก SvelteKit ให้ skip server render

+page.js
export const ssr = false;
export async function load({ fetch }) {
// โหลดข้อมูลบน client เท่านั้น
const res = await fetch('/api/user-data');
return { userData: await res.json() };
}

เทียบได้กับการใช้ 'use client' directive ใน Next.js App Router หรือใช้ Pages Router โดยไม่มี getServerSideProps

สำหรับหน้าที่ข้อมูลไม่เปลี่ยนบ่อย เช่น หน้า about, blog posts, หรือ marketing pages ให้ prerender ตอน build time เทียบได้กับ getStaticProps ของ Next.js

React
// Next.js Pages Router — Static Generation
// pages/about.tsx
export async function getStaticProps() {
return {
props: { buildTime: new Date().toISOString() },
};
}
export default function About({ buildTime }) {
return <p>Built at: {buildTime}</p>;
}
Svelte
<!-- +page.js -->
export const prerender = true;
export async function load() {
return {
buildTime: new Date().toISOString(),
};
}
<!-- +page.svelte -->
<script>
let { data } = $props();
</script>
<p>Built at: {data.buildTime}</p>

ตั้งค่า export const prerender = true ใน +layout.js ของ root เพื่อ prerender ทั้ง site (Static Site Generation) หรือตั้งค่าต่อ page ก็ได้

// +page.js หรือ +layout.js
export const ssr = true; // default: true — render บน server ก่อน
export const csr = true; // default: true — hydrate บน client
export const prerender = false; // default: false — render ตอน build time
export const trailingSlash = 'never'; // 'always' | 'never' | 'ignore'

ตัวเลือกเหล่านี้ inherit จาก layout ลงมา ถ้าตั้งค่า prerender = true ใน root layout ทุก page จะถูก prerender ยกเว้นจะ override ต่อ page

SvelteKit ใช้ adapters เพื่อ compile app สำหรับ deployment target ต่าง ๆ แนวคิดนี้ไม่มีใน Next.js (Next.js ผูกกับ Vercel) แต่ SvelteKit ออกแบบมาให้ portable ตั้งแต่แรก

Adapterใช้เมื่อ
@sveltejs/adapter-autodetect environment อัตโนมัติ (Vercel, Netlify, Cloudflare)
@sveltejs/adapter-nodeNode.js server (self-hosted, Docker)
@sveltejs/adapter-staticStatic files เท่านั้น (ต้อง prerender ทั้งหมด)
@sveltejs/adapter-cloudflareCloudflare Workers + Pages
@sveltejs/adapter-vercelVercel Edge Functions
svelte.config.js
import adapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: adapter({ out: 'build' }),
},
};

เทียบกับ Next.js: Next.js ทำงานได้ดีที่สุดบน Vercel แต่ต้องการ workaround สำหรับ host อื่น SvelteKit สลับ adapter แล้ว build ได้ทันที ไม่ต้องแก้โค้ด

SvelteKit ให้ผสม mode ในแต่ละ route ได้:

flowchart TB
  routes(["src/routes/"])
  routes --> rootLayout["+layout.js → ssr: true (default)"]
  routes --> rootPage["+page.svelte → SSR (home page)"]
  routes --> about["about/"]
  about --> aboutConfig["+page.js → prerender: true"]
  about --> aboutPage["+page.svelte → static (prerendered)"]
  routes --> dashboard["dashboard/"]
  dashboard --> dashConfig["+layout.js → ssr: false"]
  dashboard --> dashPage["+page.svelte → CSR only (protected page)"]
Mixing rendering modes per route
Rendering mode เริ่มต้นของ SvelteKit page คืออะไร?
Page option ตัวไหนทำให้ SvelteKit สร้าง static HTML ตอน build time?
คุณต้องการ deploy ไปยัง Node.js server ควรใช้ adapter ตัวไหน?