# Performance Techniques — Svelte / SvelteKit

Source: https://www.skillbyai.com/en/svelte/p-perf

> 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.

```svelte
<!-- 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.

**Quiz:** 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
- [x] 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.
