Code-Splitting

Code-Aufteilung und Lazy Loading sind eine leistungsstarke Technik zur Verbesserung der Bundle-Größe und Ladeleistung einer Anwendung.

  • Reduziert die Menge des Codes, der beim ersten Laden der Seite geladen werden muss
  • Code wird bei Bedarf geladen, wenn er benötigt wird
  • Führt zu mehr Chunks, die kleiner sind und vom Browser leichter gecacht werden können.

Wie teilt TanStack Router Code?

TanStack Router teilt Code in zwei Kategorien auf

  • Kritische Routenkonfiguration – Der Code, der zur Rendere der aktuellen Route und zum frühestmöglichen Start des Datenladeprozesses erforderlich ist.

    • Pfad-Parsing/Serialisierung
    • Suchparameter-Validierung
    • Loader, Before Load
    • Routenkontext
    • Statische Daten
    • Links
    • Skripte
    • Stile
    • Alle anderen Routenkonfigurationen, die nicht unten aufgeführt sind
  • Nicht-kritische/Lazy Routenkonfiguration – Der Code, der nicht benötigt wird, um die Route abzugleichen, und der bei Bedarf geladen werden kann.

    • Routenkomponente
    • Fehlerkomponente
    • Wartende Komponente
    • Nicht-gefunden Komponente

🧠 Warum wird der Loader nicht aufgeteilt?

  • Der Loader ist bereits eine asynchrone Grenze, sodass Sie doppelt bezahlen, um sowohl den Chunk zu erhalten als auch auf die Ausführung des Loaders zu warten.

  • Kategorisch gesehen ist es unwahrscheinlicher, dass er zu einer großen Bundle-Größe beiträgt als eine Komponente.

  • Der Loader ist eines der wichtigsten vorab ladbaren Assets für eine Route, insbesondere wenn Sie eine Standard-Vorabladeabsicht verwenden, wie z. B. das Überfahren eines Links mit der Maus. Daher ist es wichtig, dass der Loader ohne zusätzlichen asynchronen Overhead verfügbar ist.

    Wenn Sie die Nachteile der Aufteilung des Loaders kennen und dennoch fortfahren möchten, gehen Sie zum Abschnitt Aufteilung von Daten-Loadern.

Kapselung der Dateien einer Route in einem Verzeichnis

Da das dateibasierte Routing-System von TanStack Router sowohl flache als auch verschachtelte Dateistrukturen unterstützt, ist es möglich, die Dateien einer Route ohne zusätzliche Konfiguration in einem einzigen Verzeichnis zu kapseln.

Um die Dateien einer Route in einem Verzeichnis zu kapseln, verschieben Sie die Routendatei selbst in eine .route-Datei innerhalb eines Verzeichnisses mit demselben Namen wie die Routendatei.

Wenn Sie beispielsweise eine Routendatei namens posts.tsx haben, erstellen Sie ein neues Verzeichnis namens posts und verschieben Sie die Datei posts.tsx in dieses Verzeichnis und benennen Sie sie in route.tsx um.

Vorher

  • posts.tsx

Nachher

  • posts
    • route.tsx

Ansätze zur Code-Aufteilung

TanStack Router unterstützt mehrere Ansätze zur Code-Aufteilung. Wenn Sie code-basiertes Routing verwenden, überspringen Sie zum Abschnitt Code-basierte Aufteilung.

Wenn Sie dateibasiertes Routing verwenden, können Sie die folgenden Ansätze zur Code-Aufteilung nutzen

Automatische Code-Aufteilung nutzen✨

Dies ist die einfachste und leistungsstärkste Methode, um Ihre Routendateien nach Code aufzuteilen.

Wenn Sie die Funktion autoCodeSplitting verwenden, teilt TanStack Router Ihre Routendateien automatisch basierend auf der oben genannten nicht-kritischen Routenkonfiguration auf.

Wichtig

Die Funktion zur automatischen Code-Aufteilung ist NUR verfügbar, wenn Sie dateibasiertes Routing mit einem unserer unterstützten Bundler verwenden. Dies funktioniert NICHT, wenn Sie nur die CLI (@tanstack/router-cli) verwenden.

Um die automatische Code-Aufteilung zu aktivieren, müssen Sie lediglich Folgendes zur Konfiguration Ihres TanStack Router Bundler-Plugins hinzufügen

ts
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      // ...
      autoCodeSplitting: true,
    }),
    react(), // Make sure to add this plugin after the TanStack Router Bundler plugin
  ],
})
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({
      // ...
      autoCodeSplitting: true,
    }),
    react(), // Make sure to add this plugin after the TanStack Router Bundler plugin
  ],
})

Das war's! TanStack Router wird automatisch alle Ihre Routendateien nach ihrer kritischen und nicht-kritischen Routenkonfiguration aufteilen.

Wenn Sie mehr Kontrolle über den Code-Aufteilungsprozess wünschen, besuchen Sie die Anleitung Automatische Code-Aufteilung, um mehr über die verfügbaren Optionen zu erfahren.

Verwendung des Suffixes .lazy.tsx

Wenn Sie die automatische Code-Aufteilungsfunktion nicht verwenden können, können Sie Ihre Routendateien weiterhin mit dem Suffix .lazy.tsx aufteilen. Es ist so einfach wie das Verschieben Ihres Codes in eine separate Datei mit dem Suffix .lazy.tsx und die Verwendung der Funktion createLazyFileRoute anstelle von createFileRoute.

Wichtig

Die Routendatei __root.tsx, die entweder createRootRoute oder createRootRouteWithContext verwendet, unterstützt keine Code-Aufteilung, da sie unabhängig von der aktuellen Route immer gerendert wird.

Dies sind die einzigen Optionen, die createLazyFileRoute unterstützt

Export-NameBeschreibung
componentDie Komponente, die für die Route gerendert werden soll.
errorComponentDie Komponente, die gerendert werden soll, wenn beim Laden der Route ein Fehler auftritt.
pendingComponentDie Komponente, die gerendert werden soll, während die Route geladen wird.
notFoundComponentDie Komponente, die gerendert werden soll, wenn ein "Nicht gefunden"-Fehler ausgelöst wird.

Beispiel für Code-Aufteilung mit .lazy.tsx

Wenn Sie .lazy.tsx verwenden, können Sie Ihre Route in zwei Dateien aufteilen, um die Code-Aufteilung zu ermöglichen

Vorher (Einzelne Datei)

tsx
// src/routes/posts.tsx
import { createFileRoute } from '@tanstack/solid-router'
import { fetchPosts } from './api'

export const Route = createFileRoute('/posts')({
  loader: fetchPosts,
  component: Posts,
})

function Posts() {
  // ...
}
// src/routes/posts.tsx
import { createFileRoute } from '@tanstack/solid-router'
import { fetchPosts } from './api'

export const Route = createFileRoute('/posts')({
  loader: fetchPosts,
  component: Posts,
})

function Posts() {
  // ...
}

Nachher (Aufgeteilt in zwei Dateien)

Diese Datei würde die kritische Routenkonfiguration enthalten

tsx
// src/routes/posts.tsx

import { createFileRoute } from '@tanstack/solid-router'
import { fetchPosts } from './api'

export const Route = createFileRoute('/posts')({
  loader: fetchPosts,
})
// src/routes/posts.tsx

import { createFileRoute } from '@tanstack/solid-router'
import { fetchPosts } from './api'

export const Route = createFileRoute('/posts')({
  loader: fetchPosts,
})

Während die nicht-kritische Routenkonfiguration in die Datei mit dem Suffix .lazy.tsx geht

tsx
// src/routes/posts.lazy.tsx
import { createLazyFileRoute } from '@tanstack/solid-router'

export const Route = createLazyFileRoute('/posts')({
  component: Posts,
})

function Posts() {
  // ...
}
// src/routes/posts.lazy.tsx
import { createLazyFileRoute } from '@tanstack/solid-router'

export const Route = createLazyFileRoute('/posts')({
  component: Posts,
})

function Posts() {
  // ...
}

Virtuelle Routen verwenden

Es kann vorkommen, dass Sie alles aus einer Routendatei auslagern und diese dann leer lassen! In diesem Fall löschen Sie einfach die Routendatei vollständig! Eine virtuelle Route wird automatisch für Sie generiert, die als Anker für Ihre Code-Split-Dateien dient. Diese virtuelle Route wird direkt in der generierten Routenbaumdatei platziert.

Vorher (Virtuelle Routen)

tsx
// src/routes/posts.tsx
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts')({
  // Hello?
})
// src/routes/posts.tsx
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts')({
  // Hello?
})
tsx
// src/routes/posts.lazy.tsx
import { createLazyFileRoute } from '@tanstack/solid-router'

export const Route = createLazyFileRoute('/posts')({
  component: Posts,
})

function Posts() {
  // ...
}
// src/routes/posts.lazy.tsx
import { createLazyFileRoute } from '@tanstack/solid-router'

export const Route = createLazyFileRoute('/posts')({
  component: Posts,
})

function Posts() {
  // ...
}

Nachher (Virtuelle Routen)

tsx
// src/routes/posts.lazy.tsx
import { createLazyFileRoute } from '@tanstack/solid-router'

export const Route = createLazyFileRoute('/posts')({
  component: Posts,
})

function Posts() {
  // ...
}
// src/routes/posts.lazy.tsx
import { createLazyFileRoute } from '@tanstack/solid-router'

export const Route = createLazyFileRoute('/posts')({
  component: Posts,
})

function Posts() {
  // ...
}

Tada! 🎉

Code-basierte Aufteilung

Wenn Sie code-basiertes Routing verwenden, können Sie Ihre Routen immer noch mit der Methode Route.lazy() und der Funktion createLazyRoute aufteilen. Sie müssen Ihre Routenkonfiguration in zwei Teile aufteilen

Erstellen Sie eine Lazy Route mit der Funktion createLazyRoute.

tsx
// src/posts.lazy.tsx
export const Route = createLazyRoute('/posts')({
  component: MyComponent,
})

function MyComponent() {
  return <div>My Component</div>
}
// src/posts.lazy.tsx
export const Route = createLazyRoute('/posts')({
  component: MyComponent,
})

function MyComponent() {
  return <div>My Component</div>
}

Rufen Sie dann die Methode .lazy auf der Routendefinition in Ihrer app.tsx auf, um die Lazy/Code-Split-Route mit der nicht-kritischen Routenkonfiguration zu importieren.

tsx
// src/app.tsx
const postsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/posts',
}).lazy(() => import('./posts.lazy').then((d) => d.Route))
// src/app.tsx
const postsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/posts',
}).lazy(() => import('./posts.lazy').then((d) => d.Route))

Aufteilung von Daten-Loadern

Seien Sie gewarnt!!! Das Aufteilen eines Routen-Loaders ist ein gefährliches Spiel.

Es kann ein mächtiges Werkzeug zur Reduzierung der Bundle-Größe sein, aber es hat seinen Preis, wie im Abschnitt Wie teilt TanStack Router Code? erwähnt.

Sie können Ihre Datenladelogik mithilfe der Option loader der Route nach Code aufteilen. Obwohl dieser Prozess die Aufrechterhaltung der Typsicherheit bei den an Ihren Loader übergebenen Parametern erschwert, können Sie immer den generischen LoaderContext-Typ verwenden, um weitgehend dorthin zu gelangen.

tsx
import { lazyFn } from '@tanstack/solid-router'

const route = createRoute({
  path: '/my-route',
  component: MyComponent,
  loader: lazyFn(() => import('./loader'), 'loader'),
})

// In another file...a
export const loader = async (context: LoaderContext) => {
  /// ...
}
import { lazyFn } from '@tanstack/solid-router'

const route = createRoute({
  path: '/my-route',
  component: MyComponent,
  loader: lazyFn(() => import('./loader'), 'loader'),
})

// In another file...a
export const loader = async (context: LoaderContext) => {
  /// ...
}

Wenn Sie dateibasiertes Routing verwenden, können Sie Ihren loader nur aufteilen, wenn Sie die Automatische Code-Aufteilung mit benutzerdefinierten Bündlungsoptionen verwenden.

Manueller Zugriff auf Routen-APIs in anderen Dateien mit dem Helfer getRouteApi

Wie Sie sich vielleicht schon gedacht haben, kann das Platzieren Ihres Komponentencodes in einer separaten Datei von Ihrer Route es schwierig machen, die Route selbst zu nutzen. Um Ihnen dabei zu helfen, exportiert TanStack Router eine praktische Funktion getRouteApi, die Sie verwenden können, um auf typsichere APIs einer Route in einer Datei zuzugreifen, ohne die Route selbst zu importieren.

  • my-route.tsx
tsx
import { createRoute } from '@tanstack/solid-router'
import { MyComponent } from './MyComponent'

const route = createRoute({
  path: '/my-route',
  loader: () => ({
    foo: 'bar',
  }),
  component: MyComponent,
})
import { createRoute } from '@tanstack/solid-router'
import { MyComponent } from './MyComponent'

const route = createRoute({
  path: '/my-route',
  loader: () => ({
    foo: 'bar',
  }),
  component: MyComponent,
})
  • MyComponent.tsx
tsx
import { getRouteApi } from '@tanstack/solid-router'

const route = getRouteApi('/my-route')

export function MyComponent() {
  const loaderData = route.useLoaderData()
  //    ^? { foo: string }

  return <div>...</div>
}
import { getRouteApi } from '@tanstack/solid-router'

const route = getRouteApi('/my-route')

export function MyComponent() {
  const loaderData = route.useLoaderData()
  //    ^? { foo: string }

  return <div>...</div>
}

Die Funktion getRouteApi ist nützlich für den Zugriff auf andere typsichere APIs

  • useLoaderData
  • useLoaderDeps
  • useMatch
  • useParams
  • useRouteContext
  • useSearch
Unsere Partner
Code Rabbit
Netlify
Neon
Clerk
Convex
Sentry
Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.

Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.