JavaScript Dynamiske Imports: Mestring af Code Splitting og Lazy Loading | MLOG | MLOG

Modal-komponenten indlæses kun, når brugeren klikker på knappen "Åbn Modal".

3. Funktionsbaseret Code Splitting

Denne tilgang fokuserer på at opdele kode baseret på særskilte funktioner eller funktionaliteter i din applikation. Dette er især nyttigt for store applikationer med komplekse funktioner, som ikke altid er nødvendige for alle brugere. For eksempel kan et e-handelssted lazy-loade kode relateret til produktanmeldelser eller ønskelister kun, når brugeren interagerer med disse funktioner.

Eksempel (lazy loading af en rapporteringsfunktion):

            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 && ( Indlæser Rapportering...
}> )}
); } export default AdminPanel;

ReportingDashboard-komponenten, som sandsynligvis indeholder komplekse datavisualiseringer og analyse-logik, indlæses kun, når administratoren klikker på knappen "Vis Rapporterings-dashboard".

4. Betinget Code Splitting

Denne teknik involverer dynamisk import af moduler baseret på bestemte betingelser, såsom brugerens enhed, browser eller placering. Dette giver dig mulighed for at skræddersy din applikations kode til hver enkelt brugers specifikke behov, hvilket yderligere optimerer ydeevne og ressourceudnyttelse. Overvej at servere forskellige billedformater (f.eks. WebP til understøttede browsere) eller kun indlæse polyfills til ældre browsere.

Eksempel (indlæsning af polyfills for ældre browsere):

            async function loadPolyfills() {
  if (!('fetch' in window)) {
    await import('whatwg-fetch');
    console.log('Fetch polyfill indlæst.');
  }

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

loadPolyfills();

            

Denne kode tjekker, om fetch API'en og Promise understøttes af browseren. Hvis ikke, importerer den dynamisk de tilsvarende polyfills.

Lazy Loading-strategier

Lazy loading er en teknik, der udskyder indlæsningen af ressourcer, indtil der rent faktisk er brug for dem. Dette kan markant forbedre de indledende sideindlæsningstider og reducere båndbreddeforbruget. Dynamiske imports er et kraftfuldt værktøj til at implementere lazy loading i JavaScript-applikationer.

1. Lazy Loading af Billeder

Billeder er ofte en stor bidragyder til sidestørrelsen. Lazy loading af billeder sikrer, at billeder 'below the fold' (dvs. dem, der ikke er umiddelbart synlige i viewporten) kun indlæses, når brugeren scroller ned på siden.

Eksempel (med 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);
});

            

I dette eksempel indeholder data-src-attributten URL'en til billedet. Intersection Observer API'et bruges til at registrere, hvornår billedet kommer ind i viewporten, hvorefter billedet indlæses.

2. Lazy Loading af Videoer

Ligesom billeder kan videoer også have en betydelig indvirkning på sideindlæsningstider. Lazy loading af videoer forhindrer dem i at blive indlæst, indtil brugeren interagerer med dem (f.eks. klikker på en afspilningsknap).

Eksempel (lazy loading af en video med en placeholder):

            
Video Placeholder

Videoen er i første omgang repræsenteret af et placeholder-billede. Når brugeren klikker på afspilningsknappen, indlæses videokilden, og videoen begynder at afspille.

3. Lazy Loading af Iframes

Iframes, der ofte bruges til at indlejre indhold fra tredjepartskilder, kan også påvirke sidens ydeevne. Lazy loading af iframes sikrer, at de kun indlæses, når brugeren scroller tæt på dem.

Eksempel (lazy loading af en iframe med 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);
});

            

Ligesom i eksemplet med lazy loading af billeder, bruger denne kode Intersection Observer API'et til at registrere, hvornår iframen kommer ind i viewporten, og indlæser derefter iframens indhold.

Webpack og Dynamiske Imports

Webpack er en populær module bundler, der giver fremragende understøttelse af dynamiske imports. Den registrerer automatisk dynamiske import-sætninger og opdeler din kode i separate chunks, som derefter kan indlæses efter behov.

Konfiguration:

Der kræves typisk ingen særlig konfiguration for at aktivere dynamiske imports i Webpack. Du vil dog måske ønske at konfigurere code splitting yderligere ved at bruge funktioner som:

Eksempel (Webpack-konfiguration for 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',
        },
      },
    },
  },
  // ...
};

            

Denne konfiguration opretter en separat chunk for tredjepartsbiblioteker (kode fra node_modules) og bruger et unikt hash for hver chunk for at muliggøre browsercaching.

React og Dynamiske Imports

React har indbygget understøttelse for lazy loading af komponenter ved hjælp af React.lazy()-funktionen og Suspense-komponenten. Dette gør det nemt at implementere code splitting i React-applikationer.

Eksempel (lazy loading af en React-komponent):

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

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

function App() {
  return (
    Indlæser...
}> ); } export default App;

React.lazy()-funktionen tager en funktion, der returnerer en dynamisk import. Suspense-komponenten leverer et fallback UI, mens komponenten indlæses.

Angular og Dynamiske Imports

Angular understøtter lazy loading af moduler via sin routing-konfiguration. Du kan definere ruter, der indlæser moduler efter behov, hvilket markant kan forbedre den indledende indlæsningstid for din Angular-applikation.

Eksempel (lazy loading af et modul i 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 { }

            

I dette eksempel indlæses FeatureModule kun, når brugeren navigerer til /feature-ruten.

Vue.js og Dynamiske Imports

Vue.js giver også understøttelse for lazy loading af komponenter ved hjælp af dynamiske imports. Du kan bruge import()-syntaksen i dine komponentdefinitioner til at indlæse komponenter efter behov.

Eksempel (lazy loading af en Vue.js-komponent):

            Vue.component('async-component', () => ({
  // Komponent der skal indlæses. Skal være et Promise
  component: import('./AsyncComponent.vue'),
  // En komponent der bruges mens den asynkrone komponent indlæses
  loading: LoadingComponent,
  // En komponent der bruges hvis indlæsningen fejler
  error: ErrorComponent,
  // Forsinkelse før loading-komponenten vises. Standard: 200ms.
  delay: 200,
  // Fejlkomponenten vil blive vist, hvis en timeout er
  // angivet og overskredet.
  timeout: 3000
}))

            

Dette eksempel definerer en asynkron komponent ved navn async-component, der indlæser AsyncComponent.vue-filen efter behov. Den giver også muligheder for loading-, fejl-, forsinkelses- og timeout-komponenter.

Bedste Praksis for Dynamiske Imports og Lazy Loading

For effektivt at udnytte dynamiske imports og lazy loading, bør du overveje følgende bedste praksis:

Globale Overvejelser

Når du implementerer dynamiske imports og lazy loading for et globalt publikum, er det afgørende at overveje følgende:

Konklusion

JavaScript dynamiske imports giver en kraftfuld mekanisme til at implementere code splitting og lazy loading, hvilket gør det muligt for dig at optimere din webapplikations ydeevne og levere en overlegen brugeroplevelse for et globalt publikum. Ved strategisk at opdele din kode baseret på ruter, komponenter eller funktioner, og ved at lazy-loade ressourcer efter behov, kan du markant reducere indledende indlæsningstider, forbedre responsiviteten og øge den samlede applikationseffektivitet. Husk at følge bedste praksis, overveje globale faktorer og løbende overvåge din applikations ydeevne for at sikre, at du leverer den bedst mulige oplevelse til brugere over hele verden. Omfavn disse teknikker, og se din applikation trives i det globale digitale landskab.