perf(frontend): lazy-load ShareDialog and MoveDialog
ShareDialog (~15 KB JS) and MoveDialog (~5 KB JS) were statically imported by the files, favorites, recent and shared routes, so they downloaded on every visit even if the user never opened a share/move dialog. Convert them to the existing lazyComponent pattern (as already used for FileViewer/WopiEditor): the chunk is fetched the first time the dialog is opened. The Vite manifest confirms both flip from static to isDynamicEntry. This defers ~26 KB raw / ~9.5 KB gzipped (JS + CSS) off the initial load of those four routes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,8 +19,6 @@
|
||||
import { renameFolder, deleteFolder } from '$lib/api/endpoints/folders';
|
||||
import type { FileItem } from '$lib/api/types';
|
||||
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||
import MoveDialog from '$lib/components/MoveDialog.svelte';
|
||||
import ShareDialog from '$lib/components/ShareDialog.svelte';
|
||||
import ResourceList, {
|
||||
type ContextAction,
|
||||
type GroupByDef,
|
||||
@@ -127,8 +125,12 @@
|
||||
// The file preview is loaded the first time a file is opened, keeping its
|
||||
// module out of this route's initial chunk.
|
||||
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
||||
const moveDialog = lazyComponent(() => import('$lib/components/MoveDialog.svelte'));
|
||||
const shareDialog = lazyComponent(() => import('$lib/components/ShareDialog.svelte'));
|
||||
$effect(() => {
|
||||
if (viewerOpen) void fileViewer.load();
|
||||
if (moveOpen) void moveDialog.load();
|
||||
if (shareOpen) void shareDialog.load();
|
||||
});
|
||||
|
||||
function open(entry: ResourceEntry) {
|
||||
@@ -317,13 +319,19 @@
|
||||
{@const FileViewer = fileViewer.component}
|
||||
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
||||
{/if}
|
||||
<MoveDialog
|
||||
bind:open={moveOpen}
|
||||
item={moveTarget}
|
||||
items={moveItems}
|
||||
onmoved={() => {
|
||||
selectedIds = new Set();
|
||||
load(true, orderByForGroup());
|
||||
}}
|
||||
/>
|
||||
<ShareDialog bind:open={shareOpen} item={shareTarget} />
|
||||
{#if moveDialog.component}
|
||||
{@const MoveDialog = moveDialog.component}
|
||||
<MoveDialog
|
||||
bind:open={moveOpen}
|
||||
item={moveTarget}
|
||||
items={moveItems}
|
||||
onmoved={() => {
|
||||
selectedIds = new Set();
|
||||
load(true, orderByForGroup());
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if shareDialog.component}
|
||||
{@const ShareDialog = shareDialog.component}
|
||||
<ShareDialog bind:open={shareOpen} item={shareTarget} />
|
||||
{/if}
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
import type { FileItem, FolderItem, ItemType } from '$lib/api/types';
|
||||
import ListToolbar from '$lib/components/ListToolbar.svelte';
|
||||
import VirtualList from '$lib/components/VirtualList.svelte';
|
||||
import MoveDialog from '$lib/components/MoveDialog.svelte';
|
||||
import ShareDialog from '$lib/components/ShareDialog.svelte';
|
||||
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||
import { t } from '$lib/i18n/index.svelte';
|
||||
import { confirmDialog, promptDialog } from '$lib/stores/dialogs.svelte';
|
||||
@@ -69,6 +67,8 @@
|
||||
// call `.load()` when `viewerOpen` / `wopiOpen` flip true).
|
||||
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
||||
const wopiEditor = lazyComponent(() => import('$lib/components/WopiEditor.svelte'));
|
||||
const moveDialog = lazyComponent(() => import('$lib/components/MoveDialog.svelte'));
|
||||
const shareDialog = lazyComponent(() => import('$lib/components/ShareDialog.svelte'));
|
||||
|
||||
// The URL rest param is the trail of folder ids from home's children down.
|
||||
// /files → home root; /files/a/b → folder b inside a inside home.
|
||||
@@ -1083,6 +1083,8 @@
|
||||
$effect(() => {
|
||||
if (viewerOpen) void fileViewer.load();
|
||||
if (wopiOpen) void wopiEditor.load();
|
||||
if (moveOpen) void moveDialog.load();
|
||||
if (shareOpen) void shareDialog.load();
|
||||
});
|
||||
// Editability of the current context-menu target file, resolved async.
|
||||
let ctxCanEditWopi = $state(false);
|
||||
@@ -1936,21 +1938,27 @@
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<MoveDialog
|
||||
bind:open={moveOpen}
|
||||
item={actionTarget}
|
||||
items={moveItems}
|
||||
mode={moveMode}
|
||||
onmoved={() => {
|
||||
clearSelection();
|
||||
void reload();
|
||||
}}
|
||||
/>
|
||||
<ShareDialog
|
||||
bind:open={shareOpen}
|
||||
item={actionTarget}
|
||||
onshared={(id) => (sharedIds = new SvelteSet(sharedIds).add(id))}
|
||||
/>
|
||||
{#if moveDialog.component}
|
||||
{@const MoveDialog = moveDialog.component}
|
||||
<MoveDialog
|
||||
bind:open={moveOpen}
|
||||
item={actionTarget}
|
||||
items={moveItems}
|
||||
mode={moveMode}
|
||||
onmoved={() => {
|
||||
clearSelection();
|
||||
void reload();
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if shareDialog.component}
|
||||
{@const ShareDialog = shareDialog.component}
|
||||
<ShareDialog
|
||||
bind:open={shareOpen}
|
||||
item={actionTarget}
|
||||
onshared={(id) => (sharedIds = new SvelteSet(sharedIds).add(id))}
|
||||
/>
|
||||
{/if}
|
||||
{#if fileViewer.component}
|
||||
{@const FileViewer = fileViewer.component}
|
||||
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
import { renameFolder, deleteFolder } from '$lib/api/endpoints/folders';
|
||||
import type { FileItem, ItemType } from '$lib/api/types';
|
||||
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||
import MoveDialog from '$lib/components/MoveDialog.svelte';
|
||||
import ShareDialog from '$lib/components/ShareDialog.svelte';
|
||||
import ResourceList, {
|
||||
type ContextAction,
|
||||
type GroupByDef,
|
||||
@@ -139,8 +137,12 @@
|
||||
// The file preview is loaded the first time a file is opened, keeping its
|
||||
// module out of this route's initial chunk.
|
||||
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
||||
const moveDialog = lazyComponent(() => import('$lib/components/MoveDialog.svelte'));
|
||||
const shareDialog = lazyComponent(() => import('$lib/components/ShareDialog.svelte'));
|
||||
$effect(() => {
|
||||
if (viewerOpen) void fileViewer.load();
|
||||
if (moveOpen) void moveDialog.load();
|
||||
if (shareOpen) void shareDialog.load();
|
||||
});
|
||||
|
||||
function open(entry: ResourceEntry) {
|
||||
@@ -362,13 +364,19 @@
|
||||
{@const FileViewer = fileViewer.component}
|
||||
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
||||
{/if}
|
||||
<MoveDialog
|
||||
bind:open={moveOpen}
|
||||
item={moveTarget}
|
||||
items={moveItems}
|
||||
onmoved={() => {
|
||||
selectedIds = new Set();
|
||||
load(true, orderByForGroup());
|
||||
}}
|
||||
/>
|
||||
<ShareDialog bind:open={shareOpen} item={shareTarget} />
|
||||
{#if moveDialog.component}
|
||||
{@const MoveDialog = moveDialog.component}
|
||||
<MoveDialog
|
||||
bind:open={moveOpen}
|
||||
item={moveTarget}
|
||||
items={moveItems}
|
||||
onmoved={() => {
|
||||
selectedIds = new Set();
|
||||
load(true, orderByForGroup());
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if shareDialog.component}
|
||||
{@const ShareDialog = shareDialog.component}
|
||||
<ShareDialog bind:open={shareOpen} item={shareTarget} />
|
||||
{/if}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import type { FileItem, FolderItem, ItemType } from '$lib/api/types';
|
||||
import Icon from '$lib/icons/Icon.svelte';
|
||||
import ListToolbar from '$lib/components/ListToolbar.svelte';
|
||||
import ShareDialog from '$lib/components/ShareDialog.svelte';
|
||||
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||
import UserVignette from '$lib/components/UserVignette.svelte';
|
||||
import { t } from '$lib/i18n/index.svelte';
|
||||
import { ui } from '$lib/stores/ui.svelte';
|
||||
@@ -55,6 +55,13 @@
|
||||
let dialogOpen = $state(false);
|
||||
let dialogItem = $state<{ id: string; name: string; kind: ItemType } | null>(null);
|
||||
|
||||
// ShareDialog is heavy and only opens on demand — keep it out of this route's
|
||||
// initial chunk and load it the first time the dialog is opened.
|
||||
const shareDialog = lazyComponent(() => import('$lib/components/ShareDialog.svelte'));
|
||||
$effect(() => {
|
||||
if (dialogOpen) void shareDialog.load();
|
||||
});
|
||||
|
||||
// Open kebab menu, keyed by grant id.
|
||||
let menuFor = $state<string | null>(null);
|
||||
|
||||
@@ -580,7 +587,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<ShareDialog bind:open={dialogOpen} item={dialogItem} />
|
||||
{#if shareDialog.component}
|
||||
{@const ShareDialog = shareDialog.component}
|
||||
<ShareDialog bind:open={dialogOpen} item={dialogItem} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.ms-lanes {
|
||||
|
||||
Reference in New Issue
Block a user