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 { renameFolder, deleteFolder } from '$lib/api/endpoints/folders';
|
||||||
import type { FileItem } from '$lib/api/types';
|
import type { FileItem } from '$lib/api/types';
|
||||||
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||||
import MoveDialog from '$lib/components/MoveDialog.svelte';
|
|
||||||
import ShareDialog from '$lib/components/ShareDialog.svelte';
|
|
||||||
import ResourceList, {
|
import ResourceList, {
|
||||||
type ContextAction,
|
type ContextAction,
|
||||||
type GroupByDef,
|
type GroupByDef,
|
||||||
@@ -127,8 +125,12 @@
|
|||||||
// The file preview is loaded the first time a file is opened, keeping its
|
// The file preview is loaded the first time a file is opened, keeping its
|
||||||
// module out of this route's initial chunk.
|
// module out of this route's initial chunk.
|
||||||
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
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(() => {
|
$effect(() => {
|
||||||
if (viewerOpen) void fileViewer.load();
|
if (viewerOpen) void fileViewer.load();
|
||||||
|
if (moveOpen) void moveDialog.load();
|
||||||
|
if (shareOpen) void shareDialog.load();
|
||||||
});
|
});
|
||||||
|
|
||||||
function open(entry: ResourceEntry) {
|
function open(entry: ResourceEntry) {
|
||||||
@@ -317,13 +319,19 @@
|
|||||||
{@const FileViewer = fileViewer.component}
|
{@const FileViewer = fileViewer.component}
|
||||||
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
||||||
{/if}
|
{/if}
|
||||||
<MoveDialog
|
{#if moveDialog.component}
|
||||||
bind:open={moveOpen}
|
{@const MoveDialog = moveDialog.component}
|
||||||
item={moveTarget}
|
<MoveDialog
|
||||||
items={moveItems}
|
bind:open={moveOpen}
|
||||||
onmoved={() => {
|
item={moveTarget}
|
||||||
selectedIds = new Set();
|
items={moveItems}
|
||||||
load(true, orderByForGroup());
|
onmoved={() => {
|
||||||
}}
|
selectedIds = new Set();
|
||||||
/>
|
load(true, orderByForGroup());
|
||||||
<ShareDialog bind:open={shareOpen} item={shareTarget} />
|
}}
|
||||||
|
/>
|
||||||
|
{/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 type { FileItem, FolderItem, ItemType } from '$lib/api/types';
|
||||||
import ListToolbar from '$lib/components/ListToolbar.svelte';
|
import ListToolbar from '$lib/components/ListToolbar.svelte';
|
||||||
import VirtualList from '$lib/components/VirtualList.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 { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||||
import { t } from '$lib/i18n/index.svelte';
|
import { t } from '$lib/i18n/index.svelte';
|
||||||
import { confirmDialog, promptDialog } from '$lib/stores/dialogs.svelte';
|
import { confirmDialog, promptDialog } from '$lib/stores/dialogs.svelte';
|
||||||
@@ -69,6 +67,8 @@
|
|||||||
// call `.load()` when `viewerOpen` / `wopiOpen` flip true).
|
// call `.load()` when `viewerOpen` / `wopiOpen` flip true).
|
||||||
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
||||||
const wopiEditor = lazyComponent(() => import('$lib/components/WopiEditor.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.
|
// 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.
|
// /files → home root; /files/a/b → folder b inside a inside home.
|
||||||
@@ -1083,6 +1083,8 @@
|
|||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (viewerOpen) void fileViewer.load();
|
if (viewerOpen) void fileViewer.load();
|
||||||
if (wopiOpen) void wopiEditor.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.
|
// Editability of the current context-menu target file, resolved async.
|
||||||
let ctxCanEditWopi = $state(false);
|
let ctxCanEditWopi = $state(false);
|
||||||
@@ -1936,21 +1938,27 @@
|
|||||||
</div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<MoveDialog
|
{#if moveDialog.component}
|
||||||
bind:open={moveOpen}
|
{@const MoveDialog = moveDialog.component}
|
||||||
item={actionTarget}
|
<MoveDialog
|
||||||
items={moveItems}
|
bind:open={moveOpen}
|
||||||
mode={moveMode}
|
item={actionTarget}
|
||||||
onmoved={() => {
|
items={moveItems}
|
||||||
clearSelection();
|
mode={moveMode}
|
||||||
void reload();
|
onmoved={() => {
|
||||||
}}
|
clearSelection();
|
||||||
/>
|
void reload();
|
||||||
<ShareDialog
|
}}
|
||||||
bind:open={shareOpen}
|
/>
|
||||||
item={actionTarget}
|
{/if}
|
||||||
onshared={(id) => (sharedIds = new SvelteSet(sharedIds).add(id))}
|
{#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}
|
{#if fileViewer.component}
|
||||||
{@const FileViewer = fileViewer.component}
|
{@const FileViewer = fileViewer.component}
|
||||||
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
import { renameFolder, deleteFolder } from '$lib/api/endpoints/folders';
|
import { renameFolder, deleteFolder } from '$lib/api/endpoints/folders';
|
||||||
import type { FileItem, ItemType } from '$lib/api/types';
|
import type { FileItem, ItemType } from '$lib/api/types';
|
||||||
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
import { lazyComponent } from '$lib/composables/lazyComponent.svelte';
|
||||||
import MoveDialog from '$lib/components/MoveDialog.svelte';
|
|
||||||
import ShareDialog from '$lib/components/ShareDialog.svelte';
|
|
||||||
import ResourceList, {
|
import ResourceList, {
|
||||||
type ContextAction,
|
type ContextAction,
|
||||||
type GroupByDef,
|
type GroupByDef,
|
||||||
@@ -139,8 +137,12 @@
|
|||||||
// The file preview is loaded the first time a file is opened, keeping its
|
// The file preview is loaded the first time a file is opened, keeping its
|
||||||
// module out of this route's initial chunk.
|
// module out of this route's initial chunk.
|
||||||
const fileViewer = lazyComponent(() => import('$lib/components/FileViewer.svelte'));
|
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(() => {
|
$effect(() => {
|
||||||
if (viewerOpen) void fileViewer.load();
|
if (viewerOpen) void fileViewer.load();
|
||||||
|
if (moveOpen) void moveDialog.load();
|
||||||
|
if (shareOpen) void shareDialog.load();
|
||||||
});
|
});
|
||||||
|
|
||||||
function open(entry: ResourceEntry) {
|
function open(entry: ResourceEntry) {
|
||||||
@@ -362,13 +364,19 @@
|
|||||||
{@const FileViewer = fileViewer.component}
|
{@const FileViewer = fileViewer.component}
|
||||||
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
<FileViewer bind:open={viewerOpen} file={viewerFile} />
|
||||||
{/if}
|
{/if}
|
||||||
<MoveDialog
|
{#if moveDialog.component}
|
||||||
bind:open={moveOpen}
|
{@const MoveDialog = moveDialog.component}
|
||||||
item={moveTarget}
|
<MoveDialog
|
||||||
items={moveItems}
|
bind:open={moveOpen}
|
||||||
onmoved={() => {
|
item={moveTarget}
|
||||||
selectedIds = new Set();
|
items={moveItems}
|
||||||
load(true, orderByForGroup());
|
onmoved={() => {
|
||||||
}}
|
selectedIds = new Set();
|
||||||
/>
|
load(true, orderByForGroup());
|
||||||
<ShareDialog bind:open={shareOpen} item={shareTarget} />
|
}}
|
||||||
|
/>
|
||||||
|
{/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 type { FileItem, FolderItem, ItemType } from '$lib/api/types';
|
||||||
import Icon from '$lib/icons/Icon.svelte';
|
import Icon from '$lib/icons/Icon.svelte';
|
||||||
import ListToolbar from '$lib/components/ListToolbar.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 UserVignette from '$lib/components/UserVignette.svelte';
|
||||||
import { t } from '$lib/i18n/index.svelte';
|
import { t } from '$lib/i18n/index.svelte';
|
||||||
import { ui } from '$lib/stores/ui.svelte';
|
import { ui } from '$lib/stores/ui.svelte';
|
||||||
@@ -55,6 +55,13 @@
|
|||||||
let dialogOpen = $state(false);
|
let dialogOpen = $state(false);
|
||||||
let dialogItem = $state<{ id: string; name: string; kind: ItemType } | null>(null);
|
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.
|
// Open kebab menu, keyed by grant id.
|
||||||
let menuFor = $state<string | null>(null);
|
let menuFor = $state<string | null>(null);
|
||||||
|
|
||||||
@@ -580,7 +587,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<ShareDialog bind:open={dialogOpen} item={dialogItem} />
|
{#if shareDialog.component}
|
||||||
|
{@const ShareDialog = shareDialog.component}
|
||||||
|
<ShareDialog bind:open={dialogOpen} item={dialogItem} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.ms-lanes {
|
.ms-lanes {
|
||||||
|
|||||||
Reference in New Issue
Block a user