Faule Lademodule in Svelte

So importieren Sie Ihre Komponente bei Bedarf

Dynamischer Import in Svelte

Beim Codieren in Svelte haben Sie möglicherweise die Anforderung, Komponenten nur bei Bedarf zu laden, wenn sie tatsächlich benötigt werden. React hat dieses Problem mit seiner „Suspense“-Komponente ziemlich meisterhaft gelöst. Wenn Sie in Svelte etwas Ähnliches erreichen möchten, habe ich gute Nachrichten für Sie.

Schlankes "Suspense" ohne Suspense

Grundsätzlich ist es erforderlich, den integrierten Mechanismus von Svelte zu verwenden, um auf asynchrone Funktionsaufrufe in der Komponente selbst zu warten. Das folgende einfache Beispiel zeigt, was ich damit meine.

<script>
  // Dummy function, just so that we
  // have some async stuff.
	async function getData() {
		await new Promise(res => setTimeout(res, 1000));
		return { key: "value" };
	}
</script>

{#await getData()}
	<p>Fetching data...</p>
{:then res}
	<p>Accessing data: "key": "{res.key}"</p>
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}

Wie Sie sehen können, warten wir einfach auf den Rückgabewert der Funktion und verwenden ihn dann in unserer Benutzeroberfläche. Die gleiche Technik kann zum Importieren ganzer Module verwendet werden.

Dynamischer Import mit Svelte

Mit dem in ES6 verfügbaren dynamischen „Import“ können wir einen einfachen faulen Komponentenimport schreiben.

//
// Live demo:
// https://svelte.dev/repl/b7551180977d4e738b07d428f3172d5e?version=3.46.4
//

//
// App.svelte
// 

<h1>App title</h1>

{#await import("./Content.svelte") then Module}
	<Module.default subtitle="Subtilte as prop" />
{/await}
//
// Content.svelte
//

<script>
	export let subtitle;
</script>

<article>
  <h2>
		Content title
	</h2>
	<h3>
		{subtitle}
	</h3>
	<p>
		Content body.
	</p>
</article>

Aufbauend auf diesem Wissen sind wir nun in der Lage, jede Komponente träge zu laden. Ein praktisches Beispiel, das ich tatsächlich für spikze.club verwende, ist die Implementierung einer einzelnen „Icon“-Komponente, die das spezifische Icon bei Bedarf lädt.

<!--
  Source: https://carbon-icons-svelte.onrender.com/
-->
<script lang="ts">
  // Using a link so that 'clsx' can eliminate
  // all other variant compared to an enum, which
  // should lead to a smaller size at runtime.
  export let variant: "internal-link" | "external-link" | "section-link" | "close" | "add-circle";
  let cn: string = undefined;
  export { cn as class };
</script>

{#if variant === "external-link"}
  {#await import("carbon-icons-svelte/lib/ArrowUpRight20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "internal-link"}
  {#await import("carbon-icons-svelte/lib/ArrowRight20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "section-link"}
  {#await import("carbon-icons-svelte/lib/ArrowDown20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "close"}
  {#await import("carbon-icons-svelte/lib/Close20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "add-circle"}
  {#await import("carbon-icons-svelte/lib/AddAlt20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

Einpacken

Sie haben gesehen, wie Sie den dynamischen Import von ES6 verwenden, um beliebige Daten einfach bei Bedarf zu importieren. Da dies sowohl für Ihre Komponenten als auch für Bibliotheken von Drittanbietern gilt, hält Sie nichts davon ab, Ihre nächste Svelte-App zu skalieren.