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/+page.svelte | 99 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 85 insertions(+), 14 deletions(-)

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

diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 21fd7b01..ecd799d8 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,30 +1,71 @@
 <script lang="ts">
+import type { Component } from "svelte";
 import Spacer from "$lib/Layout/Spacer.svelte";
 import { onDestroy, onMount } from "svelte";
-import MangaListTemplate from "$lib/List/Manga/MangaListTemplate.svelte";
-import UpcomingAnimeList from "$lib/List/Anime/UpcomingAnimeList.svelte";
 import userIdentity from "$stores/identity.js";
 import settings from "$stores/settings";
 import ListTitle from "$lib/List/ListTitle.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";
 import Landing from "$lib/Landing.svelte";
 import LandingHero from "$lib/LandingHero.svelte";
-import IndexColumn from "$lib/List/Anime/DueIndexColumn.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 UpcomingAnimeListSvelteComponent = Component<{
+	user: UserProp;
+}>;
+type IndexColumnSvelteComponent = Component<{
+	user: UserProp;
+	userIdentity: { id: number };
+}>;
+type MangaListTemplateSvelteComponent = Component<{
+	user: UserProp;
+	displayUnresolved: boolean;
+	due: boolean;
+}>;
 
 let removeHeightObserver: (() => void) | undefined;
+let LastActivityComponent: LastActivitySvelteComponent | null = $state(null);
+let UpcomingAnimeListComponent: UpcomingAnimeListSvelteComponent | null =
+	$state(null);
+let IndexColumnComponent: IndexColumnSvelteComponent | null = $state(null);
+let MangaListTemplateComponent: MangaListTemplateSvelteComponent | null =
+	$state(null);
+let authenticatedHomeSurfaceImport: Promise<void> | null = null;
+
+const loadAuthenticatedHomeSurface = () => {
+	if (data.user === undefined) return null;
+	if (authenticatedHomeSurfaceImport) return authenticatedHomeSurfaceImport;
+
+	authenticatedHomeSurfaceImport = Promise.all([
+		import("$lib/Home/LastActivity.svelte"),
+		import("$lib/List/Anime/UpcomingAnimeList.svelte"),
+		import("$lib/List/Anime/DueIndexColumn.svelte"),
+		import("$lib/List/Manga/MangaListTemplate.svelte"),
+	]).then(([lastActivity, upcomingAnimeList, indexColumn, mangaListTemplate]) => {
+		LastActivityComponent = lastActivity.default;
+		UpcomingAnimeListComponent = upcomingAnimeList.default;
+		IndexColumnComponent = indexColumn.default;
+		MangaListTemplateComponent = mangaListTemplate.default;
+	});
+
+	return authenticatedHomeSurfaceImport;
+};
 
 onMount(() => {
 	removeHeightObserver = createHeightObserver();
 	$stateBin.upcomingAnimeListOpen ??= true;
 	$stateBin.dueMangaListOpen ??= true;
+	void loadAuthenticatedHomeSurface();
 });
 
 onDestroy(() => removeHeightObserver?.());
@@ -32,7 +73,9 @@ onDestroy(() => removeHeightObserver?.());
 
 <HeadTitle />
 
-<LastActivity user={data.user} />
+{#if LastActivityComponent}
+  <LastActivityComponent user={data.user} />
+{/if}
 
 {#if data.user === undefined}
   <LandingHero />
@@ -57,7 +100,13 @@ onDestroy(() => removeHeightObserver?.());
       {#if !$settings.disableUpcomingAnime}
         <details bind:open={$stateBin.upcomingAnimeListOpen} class="list list-upcoming">
           {#if $userIdentity.id !== -2}
-            <UpcomingAnimeList user={data.user} />
+            {#if UpcomingAnimeListComponent}
+              <UpcomingAnimeListComponent user={data.user} />
+            {:else}
+              <ListTitle title={$locale().lists.upcoming.episodes} />
+
+              <Skeleton card={false} count={5} height="0.9rem" list />
+            {/if}
           {:else}
             <ListTitle title={$locale().lists.upcoming.episodes} />
 
@@ -67,23 +116,45 @@ onDestroy(() => removeHeightObserver?.());
       {/if}
 
       {#if !$settings.disableAnime && !$settings.disableManga}
-        <IndexColumn user={data.user} userIdentity={$userIdentity} />
+        {#if IndexColumnComponent}
+          <IndexColumnComponent user={data.user} userIdentity={$userIdentity} />
+        {:else}
+          <details bind:open={$stateBin.dueAnimeListOpen} class="list list-due">
+            <ListTitle title={$locale().lists.due.episodes} />
+
+            <Skeleton card={false} count={5} height="0.9rem" list />
+          </details>
+        {/if}
       {/if}
     </div>
 
     <div class="right-column">
       {#if !$settings.disableAnime && $settings.disableManga}
-        <IndexColumn user={data.user} userIdentity={$userIdentity} />
+        {#if IndexColumnComponent}
+          <IndexColumnComponent user={data.user} userIdentity={$userIdentity} />
+        {:else}
+          <details bind:open={$stateBin.dueAnimeListOpen} class="list list-due">
+            <ListTitle title={$locale().lists.due.episodes} />
+
+            <Skeleton card={false} count={5} height="0.9rem" list />
+          </details>
+        {/if}
       {/if}
 
       {#if !$settings.disableManga}
         <details bind:open={$stateBin.dueMangaListOpen} class="list list-manga">
           {#if $userIdentity.id !== -2}
-            <MangaListTemplate
-              user={data.user}
-              displayUnresolved={$settings.displayUnresolved}
-              due={true}
-            />
+            {#if MangaListTemplateComponent}
+              <MangaListTemplateComponent
+                user={data.user}
+                displayUnresolved={$settings.displayUnresolved}
+                due={true}
+              />
+            {:else}
+              <ListTitle title={$locale().lists.due.mangaAndLightNovels} />
+
+              <Skeleton card={false} count={5} height="0.9rem" list />
+            {/if}
           {:else}
             <ListTitle title={$locale().lists.due.mangaAndLightNovels} />
 
-- 
cgit v1.2.3

