Lesson 24 / 25
Performance Techniques
Preloading, streaming and lean updates.
Where the wins are
SvelteKit preloads code and data for links: the default template sets data-sveltekit-preload-data="hover" on the body, so data loading starts when the pointer hovers a link. Stream slow, non-critical data by returning un-awaited promises from server load functions. Avoid waterfalls: start independent requests in parallel with Promise.all, and keep parent layout loads light because child loads that call await parent() wait for them. In components, use keyed each blocks, $state.raw for large immutable data, $derived instead of effects, and lazy-load heavy components with dynamic import(). Prerender what never changes, set cache headers with setHeaders in load, and optimise images (for example with @sveltejs/enhanced-img).
Parallel loads, cache headers, lazy component
Dashboard route.
<!-- src/routes/dashboard/+page.server.ts
import type { PageServerLoad } from './$types';
import { getStats, getAlerts, getActivity } from '$lib/server/dashboard';
export const load: PageServerLoad = async ({ locals, setHeaders }) => {
setHeaders({ 'cache-control': 'private, max-age=30' });
const [stats, alerts] = await Promise.all([
getStats(locals.user!.id),
getAlerts(locals.user!.id)
]);
return { stats, alerts, activity: getActivity(locals.user!.id) }; // streamed
};
-->
<!-- src/routes/dashboard/+page.svelte -->
<script lang="ts">
let { data } = $props();
let showChart = $state(false);
</script>
<p>{data.stats.users} users, {data.alerts.length} alerts</p>
<button onclick={() => (showChart = true)}>Show chart</button>
{#if showChart}
{#await import('$lib/HeavyChart.svelte') then { default: HeavyChart }}
<HeavyChart points={data.stats.series} />
{/await}
{/if}Serving a meal in courses
Streaming is serving the starter while the main course cooks: the guest starts eating sooner instead of waiting for the whole meal.
Quick check: How do you let slow, non-critical data arrive after the page first renders?
- Set export const ssr = true
- Move the query into an $effect on the server
- Return an un-awaited promise from the server load and use {#await} in the page
- Wrap the page in a {#key} block
Answer
Return an un-awaited promise from the server load and use {#await} in the page — SvelteKit streams promises returned from load.