Server-Side Rendering (SSR)
SvelteKit SSR Configuration and Implementation
SvelteKit SSR Basic Configuration:
// svelte.config.js
import adapter from '@sveltejs/adapter-node'; // Node.js server adapter
// or import adapter from '@sveltejs/adapter-vercel'; // Vercel adapter
export default {
kit: {
adapter: adapter(),
// SSR-related configuration
ssr: {
// Enable SSR (default: true)
enabled: true,
// List of external resources (not bundled into server)
external: ['@sentry/node']
}
}
};
Server-Side Data Prefetching Process:
- Client requests a page
- SvelteKit server executes
loadfunction to fetch data - Data is serialized and injected into page HTML
- Client reuses prefetched data during hydration
Custom Server Logic:
// src/hooks.server.js
export async function handle({ request, resolve }) {
// Pre-request handling (e.g., authentication)
const user = await authenticate(request);
request.locals.user = user;
// Process routing
const response = await resolve(request, {
// SSR configuration options
ssr: true,
transformPage: ({ html }) => {
// Modify final HTML
return html.replace('%USER%', user?.name || 'Guest');
}
});
// Post-response handling (e.g., adding headers)
response.headers['x-custom-header'] = 'value';
return response;
}
Data Prefetching and State Synchronization
Page-Level Data Prefetching:
<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
export let data;
// Data is prefetched and injected by load function
const { post } = data;
</script>
<h1>{post.title}</h1>
<p>{post.content}</p>
Load Function Implementation:
// src/routes/blog/[slug]/+page.js
export async function load({ params, fetch }) {
// Fetch data from API
const res = await fetch(`/api/blog/${params.slug}`);
const post = await res.json();
// Returned data is injected into page component
return {
post
};
}
Layout-Level Data Prefetching:
// src/routes/+layout.js
export async function load({ fetch }) {
// Fetch global navigation data
const navRes = await fetch('/api/navigation');
const navigation = await navRes.json();
return {
navigation
};
}
SSR Performance Optimization
Streaming SSR Implementation:
// src/routes/+page.svelte
<script>
// Mark sections for streaming rendering
export let streamData;
</script>
{#await streamData}
<p>Loading initial content...</p>
{:then data}
<StreamingContent {data} />
{/await}
Caching Strategy Configuration:
// svelte.config.js
export default {
kit: {
adapter: adapter({
// Cache configuration
cache: {
// Static assets caching
static: {
maxAge: 60 * 60 * 24 * 30 // 30 days
},
// Page caching
pages: {
maxAge: 60 // 1 minute
}
}
})
}
};
Incremental Static Regeneration (ISR):
// src/routes/blog/[slug]/+page.js
export async function load({ params, fetch }) {
// Check cache
const cacheKey = `post-${params.slug}`;
const cached = await caches.get(cacheKey);
if (cached) {
return cached;
}
// Fetch new data if cache miss
const res = await fetch(`/api/blog/${params.slug}`);
const post = await res.json();
// Set cache (expires after 60 seconds)
await caches.set(cacheKey, { post }, { ttl: 60 });
return { post };
}
SSR Security and Error Handling
Security Protection Measures:
// src/hooks.server.js
export async function handle({ request, resolve }) {
// 1. CSRF protection
if (request.method === 'POST') {
const csrfToken = request.headers['x-csrf-token'];
if (!validateCsrfToken(csrfToken)) {
return new Response('Invalid CSRF token', { status: 403 });
}
}
// 2. XSS protection
request.locals.sanitizedInput = sanitize(request.body);
// 3. Rate limiting
const ip = request.headers['x-forwarded-for'];
if (isRateLimited(ip)) {
return new Response('Too many requests', { status: 429 });
}
return resolve(request);
}
Error Handling Middleware:
// src/hooks.server.js
export async function handleError({ error, request }) {
// Log error
console.error(error);
// Handle different error types
if (error instanceof DatabaseError) {
return {
message: 'Database error occurred',
code: 'DB_ERROR'
};
}
if (error instanceof ValidationError) {
return {
message: 'Validation failed',
code: 'VALIDATION_ERROR',
details: error.details
};
}
// Default error response
return {
message: 'Internal server error',
code: 'INTERNAL_ERROR'
};
}
SSR Application Scenarios
SEO Optimization Implementation:
<!-- src/routes/products/+page.svelte -->
<script>
export let data;
// Data is prefetched by load function
const { products } = data;
</script>
<svelte:head>
<title>Product List - Our Store</title>
<meta name="description" content="Browse our wide selection of products">
<!-- Structured data markup -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{products[0].name}",
"description": "{products[0].description}"
}
</script>
</svelte:head>
<ul>
{#each products as product}
<li>{product.name} - ${product.price}</li>
{/each}
</ul>
First-Screen Performance Optimization:
- Inline critical CSS
- Preload fonts
- Lazy-load images
- Code splitting
<!-- src/routes/+page.svelte -->
<svelte:head>
<!-- Inline critical CSS -->
<style>
/* Critical CSS styles */
.hero { background: #fff; padding: 1rem; }
</style>
<!-- Font preloading -->
<link rel="preload" href="/fonts/example.woff2" as="font" type="font/woff2" crossorigin>
</svelte:head>
<!-- Lazy-load images -->
<img src="placeholder.jpg" data-src="real-image.jpg" loading="lazy" alt="Example">
Static Site Generation (SSG)
SvelteKit SSG Mechanism
Static Generation Process:
- Execute
loadfunction to fetch data during build - Generate corresponding HTML files
- Generate JavaScript required for client-side hydration
- Output to
builddirectory
Configuration Example:
// svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
// Deployment directories
pages: 'build',
assets: 'build',
// 404 page
fallback: '404.html'
})
}
};
Prerendering Control:
// src/routes/+page.js
export async function load() {
// Return fallback: true to mark as dynamic route
return {
fallback: true
};
}
Content Management and Dynamic Routing
CMS Integration Example:
// src/routes/blog/[slug]/+page.js
export async function load({ params }) {
// Fetch content from CMS API
const res = await fetch(`https://cms.example.com/api/posts/${params.slug}`);
if (!res.ok) {
// Return fallback to mark as dynamic route
return {
fallback: true
};
}
const post = await res.json();
return {
post
};
}
Dynamic Route Generation:
// src/routes/+layout.js
export async function load() {
// Fetch all blog posts
const res = await fetch('https://cms.example.com/api/posts');
const posts = await res.json();
// Generate dynamic route configuration
return {
posts,
// Prerender known routes
trailingSlash: 'always'
};
}
SSG Performance Optimization
Resource Optimization Strategies:
- Image optimization:
- Use WebP format
- Responsive images
- Lazy loading
- Code optimization:
- Tree-shaking
- Code splitting
- Compression and minification
Caching Strategy:
# Nginx configuration example
server {
location / {
# Cache static assets for 1 year
expires 1y;
add_header Cache-Control "public, immutable";
# No cache or short cache for HTML/JSON
if ($request_uri ~* \.(html|json)$) {
expires -1;
add_header Cache-Control "no-cache";
}
}
}
SSG and CMS Integration
Headless CMS Integration Process:
- Fetch content from CMS API during build
- Convert content to static HTML
- Generate data required for client-side hydration
- Deploy static files to CDN
Example Implementation:
// src/routes/blog/+page.js
export async function load() {
// Fetch post list
const postsRes = await fetch('https://cms.example.com/api/posts');
const posts = await postsRes.json();
// Prerender known posts
const knownPosts = posts.filter(post => post.published);
return {
posts: knownPosts,
// Mark unpublished posts as dynamic routes
fallback: posts.some(post => !post.published)
};
}
SSG Application Scenarios
Documentation Website Implementation:
src/routes/
├── docs/
│ ├── +layout.svelte # Documentation layout
│ ├── getting-started/ # /docs/getting-started
│ │ └── +page.svelte
│ ├── api-reference/ # /docs/api-reference
│ │ └── +page.svelte
│ └── +page.svelte # /docs
Blog System Optimization:
- Prerender published posts
- Dynamically handle draft posts
- Generate tag and category pages
- Implement RSS feed functionality
// src/routes/blog/+page.js
export async function load() {
// Fetch all published posts
const postsRes = await fetch('https://cms.example.com/api/posts?status=published');
const posts = await postsRes.json();
// Generate tag pages
const tags = [...new Set(posts.flatMap(post => post.tags))];
return {
posts,
tags,
// Mark draft posts as dynamic routes
fallback: posts.some(post => post.status === 'draft')
};
}
Real-Time Application Development
WebSocket Integration with Svelte
WebSocket Connection Management:
// src/lib/websocket.js
export function createWebSocket(url) {
const socket = new WebSocket(url);
const listeners = new Set();
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
listeners.forEach(listener => listener(data));
};
return {
subscribe(listener) {
listeners.add(listener);
return () => listeners.delete(listener);
},
send(data) {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(data));
}
},
close() {
socket.close();
}
};
}
Svelte Component Integration:
<script>
import { createWebSocket } from '$lib/websocket';
import { onMount, onDestroy } from 'svelte';
let messages = [];
const ws = createWebSocket('wss://api.example.com/ws');
const unsubscribe = ws.subscribe(message => {
messages = [...messages, message];
});
function sendMessage() {
ws.send({ type: 'chat', text: 'Hello' });
}
onMount(() => {
// Send authentication message after connection
ws.send({ type: 'auth', token: '...' });
});
onDestroy(() => {
unsubscribe();
ws.close();
});
</script>
<input bind:value={message} />
<button on:click={sendMessage}>Send</button>
<ul>
{#each messages as message}
<li>{message.text}</li>
{/each}
</ul>
GraphQL Integration with Svelte
Apollo Client Configuration:
// src/lib/apollo.js
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client/core';
import { setContext } from '@apollo/client/link/context';
const httpLink = new HttpLink({
uri: 'https://api.example.com/graphql',
});
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
}
};
});
export const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
GraphQL Query Component:
<script>
import { query } from '@sveltejs/apollo';
import { gql } from '@apollo/client/core';
const GET_POSTS = gql`
query GetPosts {
posts {
id
title
content
}
}
`;
const { data, error, loading } = query(client, {
query: GET_POSTS
});
</script>
{#if loading}
<p>Loading...</p>
{:else if error}
<p>Error: {error.message}</p>
{:else}
<ul>
{#each data.posts as post}
<li>{post.title}</li>
{/each}
</ul>
{/if}
Real-Time Collaborative Editing Implementation
CRDT Algorithm Integration:
// src/lib/crdt.js
import { Y } from 'yjs';
import { WebsocketProvider } from 'y-websocket';
export function createCollaborativeDoc(roomId) {
const ydoc = new Y.Doc();
const provider = new WebsocketProvider(
'wss://collab.example.com',
roomId,
ydoc
);
return {
ydoc,
provider,
getText(name = 'default') {
return ydoc.getText(name);
}
};
}
Svelte Component Integration:
<script>
import { onMount, onDestroy } from 'svelte';
import { createCollaborativeDoc } from '$lib/crdt';
let doc;
let text = '';
onMount(() => {
doc = createCollaborativeDoc('room-123');
const ytext = doc.getText();
// Sync local edits to CRDT
const binding = new Y.TextBinding(ytext, {
text: {
get value() { return text; },
set value(v) { text = v; }
}
});
return () => {
binding.destroy();
doc.provider.destroy();
};
});
</script>
<textarea bind:value={text} />
Real-Time Communication Performance Optimization
Bandwidth Optimization Strategies:
- Data Compression: Use gzip or Brotli
- Differential Updates: Send only changed data
- Throttling: Limit update frequency
Example Implementation:
// src/lib/realtime.js
export function createOptimizedWebSocket(url) {
const socket = new WebSocket(url);
let lastSent = {};
function sendUpdate(update) {
// Calculate diff
const diff = calculateDiff(lastSent, update);
if (Object.keys(diff).length > 0) {
// Throttle control
if (Date.now() - lastSendTime > 100) {
socket.send(JSON.stringify(diff));
lastSent = update;
lastSendTime = Date.now();
} else {
// Queue for later sending
pendingUpdates.push(diff);
}
}
}
return {
sendUpdate
};
}
Real-Time Application Security and Permissions
Authentication and Authorization Implementation:
// src/hooks.server.js
export async function handle({ request, resolve }) {
// 1. Validate WebSocket connection
if (request.headers['upgrade'] === 'websocket') {
const token = request.headers['sec-websocket-protocol'];
if (!validateToken(token)) {
return new Response(null, { status: 401 });
}
}
// 2. HTTP request authentication
const token = request.headers['authorization'];
if (token && !validateToken(token)) {
return new Response('Unauthorized', { status: 401 });
}
return resolve(request);
}
Permission Control Example:
<script>
import { onMount } from 'svelte';
import { getPermissions } from '$lib/auth';
let permissions = [];
onMount(async () => {
permissions = await getPermissions();
});
</script>
{#if permissions.includes('edit')}
<button>Edit Document</button>
{/if}
{#if permissions.includes('delete')}
<button>Delete Document</button>
{/if}
By leveraging these advanced features, you can build feature-rich, high-performance Svelte applications. The key is to select appropriate technical solutions based on specific scenarios while continuously monitoring performance metrics and user experience during development.



