Dynamische JavaScript-Importe: Code Splitting und Lazy Loading meistern | MLOG | MLOG

Die Modal-Komponente wird nur geladen, wenn der Benutzer auf die Schaltfläche „Modal öffnen“ klickt.

3. Feature-basiertes Code Splitting

Dieser Ansatz konzentriert sich auf die Aufteilung des Codes basierend auf bestimmten Merkmalen oder Funktionalitäten innerhalb Ihrer Anwendung. Dies ist besonders nützlich für große Anwendungen mit komplexen Funktionen, die nicht immer von allen Benutzern benötigt werden. Beispielsweise könnte eine E-Commerce-Website Code für Produktbewertungen oder Wunschlisten nur dann verzögert laden, wenn der Benutzer mit diesen Funktionen interagiert.

Beispiel (verzögertes Laden einer Reporting-Funktion):

            import React, { useState, lazy, Suspense } from 'react';

const ReportingDashboard = lazy(() => import('./features/ReportingDashboard'));

function AdminPanel() {
  const [showReporting, setShowReporting] = useState(false);

  const handleShowReporting = () => {
    setShowReporting(true);
  };

  return (
    
{showReporting && ( Reporting wird geladen...
}> )}
); } export default AdminPanel;

Die ReportingDashboard-Komponente, die wahrscheinlich komplexe Datenvisualisierungen und Analyselogik enthält, wird nur geladen, wenn der Administrator auf die Schaltfläche „Reporting-Dashboard anzeigen“ klickt.

4. Bedingtes Code Splitting

Diese Technik beinhaltet den dynamischen Import von Modulen basierend auf bestimmten Bedingungen, wie z. B. dem Gerät, dem Browser oder dem Standort des Benutzers. Dies ermöglicht es Ihnen, den Code Ihrer Anwendung auf die spezifischen Bedürfnisse jedes Benutzers zuzuschneiden und so die Leistung und Ressourcennutzung weiter zu optimieren. Ziehen Sie in Betracht, unterschiedliche Bildformate (z. B. WebP für unterstützte Browser) bereitzustellen oder Polyfills nur für ältere Browser zu laden.

Beispiel (Laden von Polyfills für ältere Browser):

            async function loadPolyfills() {
  if (!('fetch' in window)) {
    await import('whatwg-fetch');
    console.log('Fetch-Polyfill geladen.');
  }

  if (!('Promise' in window)) {
    await import('promise-polyfill/src/polyfill');
    console.log('Promise-Polyfill geladen.');
  }
}

loadPolyfills();

            

Dieser Code prüft, ob die fetch-API und Promise vom Browser unterstützt werden. Wenn nicht, importiert er dynamisch die entsprechenden Polyfills.

Lazy-Loading-Strategien

Lazy Loading ist eine Technik, die das Laden von Ressourcen aufschiebt, bis sie tatsächlich benötigt werden. Dies kann die anfänglichen Seitenladezeiten erheblich verbessern und den Bandbreitenverbrauch reduzieren. Dynamische Importe sind ein leistungsstarkes Werkzeug zur Implementierung von Lazy Loading in JavaScript-Anwendungen.

1. Lazy Loading von Bildern

Bilder tragen oft erheblich zur Seitengröße bei. Lazy Loading von Bildern stellt sicher, dass Bilder, die sich „below the fold“ befinden (d. h. nicht sofort im Ansichtsfenster sichtbar sind), erst geladen werden, wenn der Benutzer auf der Seite nach unten scrollt.

Beispiel (mit der Intersection Observer API):

            const images = document.querySelectorAll('img[data-src]');

function preloadImage(img) {
  img.src = img.dataset.src;
  img.onload = () => {
    img.removeAttribute('data-src');
  };
}

const imgObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      preloadImage(entry.target);
      observer.unobserve(entry.target);
    }
  });
});

images.forEach(img => {
  imgObserver.observe(img);
});

            

In diesem Beispiel enthält das data-src-Attribut die URL des Bildes. Die Intersection Observer API wird verwendet, um zu erkennen, wann das Bild in den Ansichtsbereich gelangt, woraufhin das Bild geladen wird.

2. Lazy Loading von Videos

Ähnlich wie Bilder können auch Videos die Seitenladezeiten erheblich beeinflussen. Lazy Loading von Videos verhindert, dass sie geladen werden, bis der Benutzer mit ihnen interagiert (z. B. auf eine Wiedergabeschaltfläche klickt).

Beispiel (verzögertes Laden eines Videos mit einem Platzhalter):

            
Video-Platzhalter

Das Video wird zunächst durch ein Platzhalterbild dargestellt. Wenn der Benutzer auf die Wiedergabeschaltfläche klickt, wird die Videoquelle geladen und die Wiedergabe beginnt.

3. Lazy Loading von Iframes

Iframes, die oft zum Einbetten von Inhalten von Drittanbietern verwendet werden, können ebenfalls die Seitenleistung beeinträchtigen. Lazy Loading von Iframes stellt sicher, dass sie erst geladen werden, wenn der Benutzer in ihre Nähe scrollt.

Beispiel (verzögertes Laden eines Iframes mit der Intersection Observer API):

            const iframes = document.querySelectorAll('iframe[data-src]');

function loadIframe(iframe) {
  iframe.src = iframe.dataset.src;
  iframe.onload = () => {
    iframe.removeAttribute('data-src');
  };
}

const iframeObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      loadIframe(entry.target);
      observer.unobserve(entry.target);
    }
  });
});

iframes.forEach(iframe => {
  iframeObserver.observe(iframe);
});

            

Ähnlich wie im Beispiel für das Lazy Loading von Bildern verwendet dieser Code die Intersection Observer API, um zu erkennen, wann der Iframe in den Ansichtsbereich gelangt, und lädt dann den Inhalt des Iframes.

Webpack und dynamische Importe

Webpack ist ein beliebter Modul-Bundler, der eine hervorragende Unterstützung für dynamische Importe bietet. Er erkennt automatisch dynamische Import-Anweisungen und teilt Ihren Code in separate Chunks auf, die dann bei Bedarf geladen werden können.

Konfiguration:

Normalerweise ist keine spezielle Konfiguration erforderlich, um dynamische Importe in Webpack zu aktivieren. Möglicherweise möchten Sie jedoch das Code Splitting weiter konfigurieren, indem Sie Funktionen wie die folgenden verwenden:

Beispiel (Webpack-Konfiguration für Code Splitting):

            module.exports = {
  // ...
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
    path: path.resolve(__dirname, 'dist'),
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      },
    },
  },
  // ...
};

            

Diese Konfiguration erstellt einen separaten Chunk für Anbieterbibliotheken (Code aus node_modules) und verwendet für jeden Chunk einen eindeutigen Hash, um das Browser-Caching zu ermöglichen.

React und dynamische Importe

React bietet integrierte Unterstützung für das verzögerte Laden von Komponenten mit der Funktion React.lazy() und der Suspense-Komponente. Dies erleichtert die Implementierung von Code Splitting in React-Anwendungen.

Beispiel (verzögertes Laden einer React-Komponente):

            import React, { lazy, Suspense } from 'react';

const MyComponent = lazy(() => import('./MyComponent'));

function App() {
  return (
    Wird geladen...
}> ); } export default App;

Die Funktion React.lazy() akzeptiert eine Funktion, die einen dynamischen Import zurückgibt. Die Suspense-Komponente stellt eine Fallback-UI bereit, während die Komponente geladen wird.

Angular und dynamische Importe

Angular unterstützt das verzögerte Laden von Modulen über seine Routing-Konfiguration. Sie können Routen definieren, die Module bei Bedarf laden, was die anfängliche Ladezeit Ihrer Angular-Anwendung erheblich verbessern kann.

Beispiel (verzögertes Laden eines Moduls in Angular):

            import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: 'feature',
    loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

            

In diesem Beispiel wird das FeatureModule nur geladen, wenn der Benutzer zur Route /feature navigiert.

Vue.js und dynamische Importe

Vue.js bietet ebenfalls Unterstützung für das verzögerte Laden von Komponenten mithilfe von dynamischen Importen. Sie können die import()-Syntax innerhalb Ihrer Komponentendefinitionen verwenden, um Komponenten bei Bedarf zu laden.

Beispiel (verzögertes Laden einer Vue.js-Komponente):

            Vue.component('async-component', () => ({
  // Die zu ladende Komponente. Sollte ein Promise sein
  component: import('./AsyncComponent.vue'),
  // Eine Komponente, die verwendet wird, während die asynchrone Komponente lädt
  loading: LoadingComponent,
  // Eine Komponente, die verwendet wird, wenn das Laden fehlschlägt
  error: ErrorComponent,
  // Verzögerung vor dem Anzeigen der Ladekomponente. Standard: 200ms.
  delay: 200,
  // Die Fehlerkomponente wird angezeigt, wenn ein Timeout
  // angegeben und überschritten wird.
  timeout: 3000
}))

            

Dieses Beispiel definiert eine asynchrone Komponente namens async-component, die die Datei AsyncComponent.vue bei Bedarf lädt. Es bietet auch Optionen für Lade-, Fehler-, Verzögerungs- und Timeout-Komponenten.

Best Practices für dynamische Importe und Lazy Loading

Um dynamische Importe und Lazy Loading effektiv zu nutzen, sollten Sie die folgenden Best Practices beachten:

Globale Überlegungen

Bei der Implementierung von dynamischen Importen und Lazy Loading für ein globales Publikum ist es entscheidend, Folgendes zu berücksichtigen:

Fazit

Dynamische JavaScript-Importe bieten einen leistungsstarken Mechanismus zur Implementierung von Code Splitting und Lazy Loading, mit dem Sie die Leistung Ihrer Webanwendung optimieren und eine überlegene Benutzererfahrung für ein globales Publikum bieten können. Indem Sie Ihren Code strategisch nach Routen, Komponenten oder Funktionen aufteilen und Ressourcen bei Bedarf verzögert laden, können Sie die anfänglichen Ladezeiten erheblich reduzieren, die Reaktionsfähigkeit verbessern und die Gesamteffizienz der Anwendung steigern. Denken Sie daran, Best Practices zu befolgen, globale Überlegungen zu berücksichtigen und die Leistung Ihrer Anwendung kontinuierlich zu überwachen, um sicherzustellen, dass Sie den Benutzern weltweit das bestmögliche Erlebnis bieten. Nutzen Sie diese Techniken und beobachten Sie, wie Ihre Anwendung in der globalen digitalen Landschaft floriert.