Lazy Loading Components in Svelte
Svelte is already very performant out of the box. Yet, there is a way to make your apps even faster: Lazy loading components. If you come from other frameworks, you might know the in-built APIs or popular libraries for lazy loading. In Svelte, the approach is a bit more bare bone, yet, not difficult.
By default, all of your project’s JavaScript and .svelte
files are bundled into the initial bundle. This means everything on your page will be loaded directly - even the things that aren’t visible right away.
But when using the import
function in Svelte, imported assets are bundled sparely.
Here’s the code.
Loading on hover
Loading when hovering another element is a common strategy.
This is the component we want to load lazily, saved in /lib/component/Second.svelte
<script lang="ts">
let props = $props();
</script>
<div>
<h1>{props.message}</h1>
<p>Lazily loaded</p>
</div>
In our /routes/+page.svelte:
<script lang="ts">
let Module: any = null;
async function loadComponent() {
if (!Module) {
const module = await import('$lib/components/Lazily.svelte');
Module = module.default;
}
}
</script>
<p
on:mouseenter={loadComponent}>
Hover here to load the component
</p>
{#if Module}
<Module message="Hello" />
{/if}
- We need to globally bind our lazy imported component, so we can render it.
- The import function then loads our Svelte component from anywhere - we can even use $-paths, as in the example. If you prefer, you can still use
../lib/components/Lazily.svelte
When the browser’s idle
Another strategy is to lazy load once the browser is done with all the important stuff. We can use the requestIdleCallbac
API for this.
Hint: This API isn’t supported in all browsers yet. Safari, for example, still lacks it. Alternatively, you can use a time out there or try to polyfill it.
That’s it! You should see the components appear as a JS file in the network tab: