diff --git a/src/lib/components/LazyImage.svelte b/src/lib/components/LazyImage.svelte
new file mode 100644
index 0000000..6012f1a
--- /dev/null
+++ b/src/lib/components/LazyImage.svelte
@@ -0,0 +1,42 @@
+
+
+
+ {#if load}
+ {#await loadImage(src)}
+
+ {:then data}
+

+ {/await}
+ {/if}
+
diff --git a/src/lib/lazyload.ts b/src/lib/lazyload.ts
new file mode 100644
index 0000000..4775dfb
--- /dev/null
+++ b/src/lib/lazyload.ts
@@ -0,0 +1,30 @@
+// https://www.alexschnabl.com/blog/articles/lazy-loading-images-and-components-in-svelte-and-sveltekit-using-typescript
+
+let observer: IntersectionObserver;
+
+const getObserver = () => {
+ if (observer) return;
+
+ observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ entry.target.dispatchEvent(new CustomEvent("LazyVisible"));
+ }
+ });
+ });
+};
+
+// This is used as an action on lazyloaded elements
+export const lazyload = (node: HTMLElement) => {
+ // The observer determines if the element is visible on screen
+ getObserver();
+
+ // If the element is visible, the "LazyVisible" event will be dispatched
+ observer.observe(node);
+
+ return {
+ destroy() {
+ observer.unobserve(node);
+ },
+ };
+};