diff options
| author | Fuwn <[email protected]> | 2026-03-22 04:11:18 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-22 04:20:41 +0000 |
| commit | bf633af5eab9e402b5f5c382e6eb1bb95eaf5886 (patch) | |
| tree | c4b2bfe3f03b11000c189ecf16f51e57d02b825f /src/routes/+page.svelte | |
| parent | refactor: isolate last activity fetch path (diff) | |
| download | due.moe-bf633af5eab9e402b5f5c382e6eb1bb95eaf5886.tar.xz due.moe-bf633af5eab9e402b5f5c382e6eb1bb95eaf5886.zip | |
perf: lazy-load authenticated list surfaces
Diffstat (limited to 'src/routes/+page.svelte')
| -rw-r--r-- | src/routes/+page.svelte | 99 |
1 files changed, 85 insertions, 14 deletions
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} /> |