Next to text compression image lazyloading is one of the best ways to improve performance on a website. And with Svelte its no different. So here I’m going to share a radically simple way to accomplish lazyloading with Svelte.
Let’s begin.
Include svelte-intersection-observer into your project:
pnpm i -D svelte-intersection-observer
Create an ImageLoader component:
touch src/lib/ImageLoader.svelte
Dump in the following code:
<!-- src/lib/ImageLoader.svelte -->
<script lang="ts">
export let src: string,
klass?: string,
loading = 'lazy',
alt: string;
import IntersectionObserver from 'svelte-intersection-observer';
import { fly } from 'svelte/transition';
let node: HTMLElement;
</script>
<IntersectionObserver once element={node} let:intersecting>
<div bind:this={node}>
{#if intersecting}
<img class={klass} {src} {alt} {loading} in:fly={{ x: -5, delay: 200 }} />
{/if}
</div>
</IntersectionObserver>
Import and use the component:
<!-- src/lib/ProductGrid.svelte -->
<script lang="ts">
import ImageLoader from '$lib/ImageLoader.svelte';
export let items: { edges: any; };
const { edges: products } = items;
</script>
{#each products as product}
<ImageLoader
src={product.node.images[0].url}
alt={product.node.images[0].alt}
/>
{/each}
Note: Above code assumes you’re using TypeScript in a SvelteKit project. If you’re not using SvelteKit or TypeScript, adjust the source accordingly.
With the basic grid styling applied you should see:
I did say deadsimple right? You’re done.
Summary
In this post I showed you a deadsimple way to add lazyloading to your Svelte app. This method is ideal as a first iteration, before integrating sharp or other image processing libraries into your app to gain even more performance. Depending on your browser support requirements, you may also want to consider adjusting the loading attribute on the img tag as described by Donovan Hutchinson on CSS-Tricks. Before visiting CSS-Tricks, however, ensure you’ve got uBlock Origin enabled as the site does little in the way of respecting user privacy.