From bf633af5eab9e402b5f5c382e6eb1bb95eaf5886 Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.net>
Date: Sun, 22 Mar 2026 04:11:18 +0000
Subject: perf: lazy-load authenticated list surfaces

---
 src/routes/completed/+page.svelte | 71 +++++++++++++++++++++++++++++++++------
 1 file changed, 60 insertions(+), 11 deletions(-)

(limited to 'src/routes/completed/+page.svelte')

diff --git a/src/routes/completed/+page.svelte b/src/routes/completed/+page.svelte
index 96df8b90..220901bf 100644
--- a/src/routes/completed/+page.svelte
+++ b/src/routes/completed/+page.svelte
@@ -1,13 +1,11 @@
 <script lang="ts">
+import type { Component } from "svelte";
 import Spacer from "$lib/Layout/Spacer.svelte";
 import { onDestroy, onMount } from "svelte";
 import userIdentity from "$stores/identity.js";
 import settings from "$stores/settings";
-import WatchingAnimeList from "$lib/List/Anime/CompletedAnimeList.svelte";
 import ListTitle from "$lib/List/ListTitle.svelte";
-import MangaListTemplate from "$lib/List/Manga/MangaListTemplate.svelte";
 import HeadTitle from "$lib/Home/HeadTitle.svelte";
-import LastActivity from "$lib/Home/LastActivity.svelte";
 import { createHeightObserver } from "$lib/Utility/html.js";
 import Skeleton from "$lib/Loading/Skeleton.svelte";
 import locale from "$stores/locale.js";
@@ -15,14 +13,51 @@ import Landing from "$lib/Landing.svelte";
 import stateBin from "$stores/stateBin.js";
 import type { PageData } from "./$types";
 
-export let data: PageData;
+let { data }: { data: PageData } = $props();
+
+type UserProp = PageData["user"];
+type LastActivitySvelteComponent = Component<{
+	user: UserProp;
+}>;
+type WatchingAnimeListSvelteComponent = Component<{
+	user: UserProp;
+}>;
+type MangaListTemplateSvelteComponent = Component<{
+	user: UserProp;
+	displayUnresolved: boolean;
+	due: boolean;
+}>;
 
 let removeHeightObserver: (() => void) | undefined;
+let LastActivityComponent: LastActivitySvelteComponent | null = $state(null);
+let WatchingAnimeListComponent: WatchingAnimeListSvelteComponent | null =
+	$state(null);
+let MangaListTemplateComponent: MangaListTemplateSvelteComponent | null =
+	$state(null);
+let completedSurfaceImport: Promise<void> | null = null;
+
+const loadCompletedSurface = () => {
+	if (data.user === undefined) return null;
+	if (completedSurfaceImport) return completedSurfaceImport;
+
+	completedSurfaceImport = Promise.all([
+		import("$lib/Home/LastActivity.svelte"),
+		import("$lib/List/Anime/CompletedAnimeList.svelte"),
+		import("$lib/List/Manga/MangaListTemplate.svelte"),
+	]).then(([lastActivity, watchingAnimeList, mangaListTemplate]) => {
+		LastActivityComponent = lastActivity.default;
+		WatchingAnimeListComponent = watchingAnimeList.default;
+		MangaListTemplateComponent = mangaListTemplate.default;
+	});
+
+	return completedSurfaceImport;
+};
 
 onMount(() => {
 	removeHeightObserver = createHeightObserver();
 	$stateBin.completedAnimeListOpen ??= true;
 	$stateBin.completedMangaListOpen ??= true;
+	void loadCompletedSurface();
 });
 
 onDestroy(() => removeHeightObserver?.());
@@ -30,7 +65,9 @@ onDestroy(() => removeHeightObserver?.());
 
 <HeadTitle route="Completed" path="/completed" />
 
-<LastActivity user={data.user} />
+{#if LastActivityComponent}
+  <LastActivityComponent user={data.user} />
+{/if}
 
 {#if data.user === undefined}
   <div class="card">Please log in to view completed media.</div>
@@ -43,7 +80,13 @@ onDestroy(() => removeHeightObserver?.());
     {#if !$settings.displayFiltersIncludeCompleted || !$settings.disableAnime}
       <details bind:open={$stateBin.completedAnimeListOpen} class="list">
         {#if $userIdentity.id !== -2}
-          <WatchingAnimeList user={data.user} />
+          {#if WatchingAnimeListComponent}
+            <WatchingAnimeListComponent user={data.user} />
+          {:else}
+            <ListTitle title={$locale().lists.completed.anime} />
+
+            <Skeleton card={false} count={5} height="0.9rem" list />
+          {/if}
         {:else}
           <ListTitle title={$locale().lists.completed.anime} />
 
@@ -55,11 +98,17 @@ onDestroy(() => removeHeightObserver?.());
     {#if !$settings.displayFiltersIncludeCompleted || !$settings.disableManga}
       <details bind:open={$stateBin.completedMangaListOpen} class="list">
         {#if $userIdentity.id !== -2}
-          <MangaListTemplate
-            user={data.user}
-            displayUnresolved={$settings.displayUnresolved}
-            due={false}
-          />
+          {#if MangaListTemplateComponent}
+            <MangaListTemplateComponent
+              user={data.user}
+              displayUnresolved={$settings.displayUnresolved}
+              due={false}
+            />
+          {:else}
+            <ListTitle title={$locale().lists.completed.mangaAndLightNovels} />
+
+            <Skeleton card={false} count={5} height="0.9rem" list />
+          {/if}
         {:else}
           <ListTitle title={$locale().lists.completed.mangaAndLightNovels} />
 
-- 
cgit v1.2.3

