Behersk browserens ressourceindlæsning med avanceret JavaScript-modul preloading. Lær preload, prefetch og modulepreload for global optimering af web-performance, der forbedrer brugeroplevelsen verden over.
Frigørelse af Hyperhastighed: En Dybdegående Gennemgang af JavaScript Modul Preloading-Strategier for Global Web Performance
I nutidens sammenkoblede digitale verden, hvor brugere spænder over kontinenter og tilgår internettet på et utroligt udvalg af enheder og netværksforhold, er web-performance ikke længere blot en fordel – det er en absolut nødvendighed. Et langsomt website kan afskrække brugere, skade placeringer i søgemaskiner og direkte påvirke forretningsresultater, uanset geografisk placering. I hjertet af mange moderne webapplikationer ligger JavaScript, et kraftfuldt sprog, der bringer interaktivitet og dynamiske oplevelser. Men selve kraften i JavaScript kan blive dets akilleshæl, hvis det ikke håndteres korrekt, især når det kommer til indlæsning af ressourcer.
Moderne webapplikationer er ofte baseret på komplekse arkitekturer bygget med JavaScript-moduler. I takt med at disse applikationer vokser i kompleksitet og funktionalitet, vokser deres JavaScript-bundles også. At levere disse betydelige bundles effektivt til brugere over hele verden, fra bycentre med højhastighedsfiber til fjerntliggende områder med begrænset forbindelse, udgør en betydelig udfordring. Det er her, JavaScript modul preloading-strategier bliver afgørende. Ved intelligent at give browseren hints om ressourcer, den får brug for i den nærmeste fremtid, kan udviklere dramatisk reducere opfattede indlæsningstider, forbedre brugeroplevelsen og sikre, at deres applikationer yder optimalt på tværs af kloden.
Denne omfattende guide vil udforske nuancerne i browserens ressourceindlæsning, dykke ned i de forskellige JavaScript modul preloading-strategier og give handlingsorienterede indsigter til at implementere dem effektivt. Vores fokus vil forblive på praktisk anvendelse, teknisk dybde og et globalt perspektiv for at sikre, at de diskuterede teknikker er gavnlige for et internationalt publikum, der står over for forskellige driftsmiljøer.
Nødvendigheden af Web Performance i et Globaliseret Digitalt Landskab
Før vi dykker ned i de tekniske detaljer, er det afgørende at gentage hvorfor web-performance er altafgørende, især for et globalt publikum. Effekten af langsomme indlæsningstider strækker sig langt ud over mindre ulejlighed:
- Brugeroplevelse (UX): Et hurtigt-indlæsende website skaber et positivt førstehåndsindtryk, opmuntrer til engagement og reducerer bounce rates. Omvendt frustrerer et langsomt website brugerne, hvilket får dem til at forlade sider, før de overhovedet er fuldt indlæst. Denne effekt forstærkes for brugere i regioner med langsommere eller mindre pålidelig internetinfrastruktur, hvor hver kilobyte tæller.
- Søgemaskineoptimering (SEO): Store søgemaskiner, især Google, bruger eksplicit sidehastighed som en rangeringsfaktor. Hurtigere websites har større sandsynlighed for at rangere højere, hvilket øger synligheden og den organiske trafik. Core Web Vitals (Largest Contentful Paint, First Input Delay, Cumulative Layout Shift) er nøgletal, der afspejler brugeroplevelsen og direkte påvirker SEO.
- Konverteringsrater: For e-handelsplatforme, nyhedsportaler og tjenesteudbydere er sidehastighed direkte korreleret med konverteringsrater. Studier viser konsekvent, at selv en lille forsinkelse kan føre til betydelige fald i salg eller tilmeldinger. For virksomheder, der opererer globalt, kan denne effekt omsættes til betydelige omsætningstab på tværs af forskellige markeder.
- Tilgængelighed og Inklusion: Optimering af ressourceindlæsning sikrer, at din webapplikation er tilgængelig og brugbar for en bredere vifte af brugere, herunder dem på ældre enheder, med begrænsede dataplaner eller i områder med mindre udviklet netværksinfrastruktur. Denne globale inklusion er en hjørnesten i etisk webudvikling.
- Ressourceforbrug: Effektiv indlæsning reducerer mængden af overført data, hvilket er en fordel for brugere på forbrugsbaserede forbindelser eller dem, der er bekymrede for dataforbrug. Det reducerer også serverbelastning og energiforbrug, hvilket bidrager til et mere bæredygtigt web.
I betragtning af de store forskelle i internethastigheder, enhedskapaciteter og datakostnader på tværs af lande, er en 'one-size-fits-all'-tilgang til web-performance utilstrækkelig. Strategisk JavaScript modul preloading giver udviklere mulighed for proaktivt at håndtere disse variationer og levere en konsekvent god oplevelse til brugere over hele verden.
Forståelse af JavaScript-moduler og Deres Indlæsningsudfordringer
Moderne JavaScript-applikationer er struktureret ved hjælp af ECMAScript Modules (ES Modules), som giver en standardiseret måde at organisere kode på i genanvendelige enheder ved hjælp af import
- og export
-erklæringer. Denne modularitet forbedrer kodens vedligeholdelse, genanvendelighed og udviklersamarbejde. Men selve modulets natur, med deres sammenvævede afhængigheder, introducerer kompleksitet i indlæsningsprocessen.
Hvordan Browsere Indlæser ES-moduler
Når en browser støder på et ES-modul-script (typisk via <script type="module">
), følger den en specifik, flertrinsproces:
- Hent (Fetch): Browseren downloader hovedmodulfilen.
- Parse: Browseren parser modulets kode og identificerer alle dets
import
-erklæringer. - Hent Afhængigheder: For hver afhængighed henter og parser browseren rekursivt disse moduler og bygger en komplet modulgraf. Dette kan skabe en "vandfaldseffekt", hvor et modul skal hentes og parses, før dets afhængigheder overhovedet kan identificeres og hentes.
- Instantiér: Når alle moduler i grafen er hentet og parset, løser browseren alle import-export-bindinger.
- Evaluer: Til sidst eksekveres koden i hvert modul.
Denne sekventielle natur, især den rekursive hentning af afhængigheder, kan føre til betydelige forsinkelser, især for store applikationer med dybe modulgrafikker. Hvert trin medfører netværkslatens, CPU-behandling og potentiel render-blocking. Dette er den kerneudfordring, som preloading-strategier sigter mod at afbøde.
Preloading vs. Lazy Loading: En Afgørende Forskel
Det er vigtigt at skelne mellem preloading og lazy loading, da begge er optimeringsteknikker, men tjener forskellige formål:
- Lazy Loading: Udskyder indlæsningen af en ressource, indtil den rent faktisk er nødvendig. Dette er ideelt for ikke-kritiske ressourcer, såsom billeder uden for skærmen, dynamiske komponenter, der kun vises ved brugerinteraktion, eller hele ruter, der ikke besøges med det samme. Det reducerer den indledende indlæsningstid ved at indlæse mindre på forhånd.
- Preloading: Instruerer browseren i at hente en ressource tidligt i forventning om, at den snart bliver nødvendig, men uden at blokere den indledende rendering eller eksekvering. Det sigter mod at gøre en ressource tilgængelig med det samme, når dens tid kommer til at blive eksekveret, hvilket reducerer forsinkelsen mellem, hvornår en ressource anmodes om, og hvornår den rent faktisk bruges.
Mens lazy loading reducerer den indledende bundlestørrelse, optimerer preloading leveringen af ressourcer, der sandsynligvis vil blive brugt kort efter den indledende indlæsning. De to strategier er ofte komplementære og arbejder sammen for at levere en usædvanlig hurtig brugeroplevelse.
Søjlerne i Preloading: Kernestrategier for Moduloptimering
Webplatformen giver flere kraftfulde ressource-hints, som udviklere kan udnytte til preloading. At forstå deres forskelle og passende anvendelsestilfælde er nøglen til effektiv optimering.
<link rel="preload">: Den Tidlige Fugl Fanger Ormen
<link rel="preload">
-hintet informerer browseren om, at en ressource sandsynligvis snart vil være nødvendig for den aktuelle side. Browseren prioriterer derefter at hente denne ressource, hvilket gør den tilgængelig tidligere, end den ellers ville have været. Vigtigt er det, at preload
kun henter ressourcen; den eksekverer den ikke. Eksekvering sker, når ressourcen eksplicit anmodes om af HTML-parseren, et script eller en anden del af siden.
Sådan virker det:
Når browseren støder på et <link rel="preload">
-tag, tilføjer den den specificerede ressource til en højprioritetskø til hentning. Dette giver browseren mulighed for at downloade kritiske ressourcer (som JavaScript-moduler, CSS, skrifttyper eller billeder) meget tidligere i renderingsprocessen, ofte før den primære HTML-parser overhovedet har opdaget dem. Dette kan forhindre render-blocking og reducere time to interactive (TTI).
Anvendelsestilfælde for JavaScript-moduler:
- Kritiske Scripts: JavaScript-filer, der er essentielle for den indledende rendering og interaktivitet på siden.
- Dynamiske Importer: Moduler, der er lazy-loaded via
import()
-kald, men som med stor sandsynlighed vil være nødvendige kort efter sidens indlæsning (f.eks. en komponent, der vises efter en kort animation, eller et modul til en almindelig brugerhandling). Preloading af målet for en dynamisk import kan betydeligt reducere latensen, nårimport()
-kaldet endelig foretages. - Modulafhængigheder: Selvom
modulepreload
generelt er bedre til komplette modulgrafikker (diskuteres nedenfor), kanpreload
stadig være nyttigt for individuelle JavaScript-filer, der ikke nødvendigvis er ES-moduler, men som er kritiske.
Fordele:
- Højprioritetshentning: Ressourcer hentes tidligt, hvilket reducerer latens for, hvornår de rent faktisk er nødvendige.
- Adskillelse af Hentning og Eksekvering: Giver browseren mulighed for at downloade ressourcen uden straks at eksekvere den, hvilket forhindrer blokering af hovedtråden, indtil det er absolut nødvendigt.
- Ressourcetype Specificitet:
as
-attributten (f.eks.as="script"
,as="font"
) giver browseren mulighed for at anvende den korrekte content security policy, anmodnings-headers og prioriteringslogik for den specifikke ressourcetype.
Potentielle Faldgruber og Overvejelser:
- Overdreven Preloading: At preloade for mange ressourcer kan forbruge overdreven båndbredde og CPU, hvilket potentielt kan bremse den indledende indlæsning i stedet for at fremskynde den. Det er afgørende at identificere de reelt kritiske ressourcer.
- Spildt Båndbredde: Hvis en preloadet ressource i sidste ende ikke bliver brugt, er båndbredden og netværksressourcerne, der blev brugt på at hente den, spildt. Dette er især problematisk for brugere på forbrugsbaserede dataplaner eller i regioner med høje datakostnader.
- Browser Support: Selvom det er bredt understøttet, genkender ældre browsere muligvis ikke
preload
. En robust strategi inkluderer ofte fallbacks eller omhyggelig progressiv forbedring.
Kodeeksempel:
Preloading af et kritisk JavaScript-modul:
<head>
<link rel="preload" as="script" href="/assets/js/critical-module.js">
<!-- Andre head-elementer -->
</head>
<body>
<!-- ...senere i body eller dynamisk... -->
<script type="module" src="/assets/js/critical-module.js"></script>
</body>
Preloading af et modul for en dynamisk import:
<head>
<link rel="preload" as="script" href="/assets/js/modal-dialog.js">
</head>
<body>
<button id="openModalBtn">Åbn Modal</button>
<script type="module">
document.getElementById('openModalBtn').addEventListener('click', async () => {
const { openModal } = await import('/assets/js/modal-dialog.js');
openModal();
});
</script>
</body>
<link rel="prefetch">: At Se Fremad med Forudseenhed
<link rel="prefetch">
-hintet fortæller browseren, at en ressource muligvis er nødvendig for en fremtidig navigation eller interaktion. I modsætning til preload
hentes prefetch
-ressourcer med lav prioritet, typisk i browserens ledige øjeblikke. Det betyder, at de ikke vil konkurrere med kritiske ressourcer for den aktuelle sideindlæsning.
Sådan virker det:
Når en browser støder på et <link rel="prefetch">
-tag, sætter den ressourcen i kø til download. Denne download sker dog i baggrunden, forbruger minimale ressourcer og kun, når browseren vurderer, at den har ledig kapacitet. Når den er hentet, gemmes ressourcen i HTTP-cachen, klar til når brugeren til sidst navigerer til en side, der kræver den, eller udløser en interaktion, der bruger den.
Anvendelsestilfælde for JavaScript-moduler:
- Næste Sides Navigation: Forhåndshentning af JavaScript-moduler til sider, som en bruger med stor sandsynlighed vil besøge næste gang (f.eks. betalingssiden efter at have tilføjet en vare til kurven, eller den næste artikel i en serie).
- Betingede Funktioner: Moduler til funktioner, der ikke er en del af den oprindelige oplevelse, men som ofte tilgås af brugere (f.eks. et avanceret analyse-dashboard for loggede brugere, eller en kompleks editor, der kan startes fra en enklere visning).
- Optimering af Brugerrejse: Baseret på analyser af brugerflow, identificer almindelige stier og forhåndshent ressourcer til disse stier.
Fordele:
- Forbedret Opfattet Performance: Når en bruger navigerer til en forhåndshentet side eller udløser en forhåndshentet funktion, er ressourcerne allerede i cachen, hvilket fører til næsten øjeblikkelig indlæsning.
- Lav Prioritet: Konkurrerer ikke med kritiske ressourcer, hvilket sikrer, at den aktuelle sides performance ikke forringes.
- Effektiv for Multi-Page Applications (MPAs): Kan betydeligt forbedre oplevelsen i traditionelle MPAs ved at forudse brugerens navigation.
Potentielle Faldgruber og Overvejelser:
- Spildt Båndbredde: Hvis en forhåndshentet ressource aldrig rent faktisk bliver brugt, er båndbredden spildt. Dette er en større bekymring for prefetch end for preload, givet dens spekulative natur. Omhyggelig analyse af brugeradfærd er afgørende for at minimere spild. Dette er især relevant for globale brugere med forskellige dataplaner.
- Cache Invalidering: Sørg for, at korrekte cache-control headers er sat for forhåndshentede ressourcer for at undgå at servere forældet indhold.
- Browser Support: Bredt understøttet, men nogle ældre browsere understøtter det muligvis ikke.
Kodeeksempel:
Forhåndshentning af JavaScript til en sandsynlig næste side:
<head>
<link rel="prefetch" as="script" href="/assets/js/checkout-flow.js">
</head>
<body>
<p>Du har tilføjet varer til din kurv. Fortsæt til <a href="/checkout">betaling</a>.</p>
</body>
<link rel="modulepreload">: Den Moderne ES Modul Game Changer
<link rel="modulepreload">
er et specialiseret ressource-hint, der er introduceret specifikt til ES Modules. Det er designet til at overvinde vandfaldsproblemet, der er forbundet med traditionel modulindlæsning, ved ikke blot at hente modulet, men også at parse og kompilere det, sammen med hele dets afhængighedsgraf, på forhånd.
Sådan virker det:
Når browseren støder på <link rel="modulepreload">
, udfører den følgende trin:
- Hent Modulet: Downloader den specificerede ES-modulfil.
- Parse og Opdag Afhængigheder: Parser modulet og identificerer alle dets
import
-erklæringer. - Hent og Parse Afhængigheder Rekursivt: For hver afhængighed udfører den de samme hente- og parse-trin og opbygger den komplette modulgraf.
- Kompiler: Kompilerer alle moduler i grafen, hvilket gør dem klar til øjeblikkelig eksekvering.
Den afgørende forskel fra preload
(som kun henter) er for-parsing og for-kompilering. Dette betyder, at når et script til sidst anmoder om modulet (f.eks. via et <script type="module">
-tag eller en dynamisk import()
), kan browseren springe de tidskrævende parsing- og kompileringstrin over, hvilket fører til meget hurtigere eksekvering.
Anvendelsestilfælde for JavaScript-moduler:
- Primære Applikations-indgangspunkter: For single-page applications (SPAs) eller komplekse modulbaserede sites kan
modulepreload
hente og forberede hele hovedapplikationsbundtet og dets afhængigheder. - Højprioritets Dynamiske Importer: Moduler, der er lazy-loaded, men som er kritiske for den opfattede performance eller kernefunktionalitet, når en indledende interaktion sker.
- Delte Moduler: Preloading af almindelige hjælpe-moduler, der bruges på tværs af mange dele af applikationen.
Fordele:
- Eliminerer Vandfaldseffekt: Ved ivrigt at gennemgå og behandle modulgrafen reducerer det drastisk den blokeringstid, der ofte er forbundet med modulindlæsning.
- Hurtigere Eksekvering: Moduler parses og kompileres på forhånd, hvilket fører til næsten øjeblikkelig eksekvering, når de endelig er nødvendige.
- Optimeret til HTTP/2 og HTTP/3: Udnytter multiplexing til at hente flere modulfiler samtidigt, hvilket reducerer virkningen af netværkslatens.
- Bedre for ES Modul-baserede Applikationer: Specielt designet til de komplekse aspekter af ES Modules, hvilket giver en mere robust optimering end generisk
preload
for modulgrafikker.
Potentielle Faldgruber og Overvejelser:
- Browser Support:
modulepreload
er nyere og har mere begrænset browserunderstøttelse sammenlignet medpreload
ogprefetch
(primært Chromium-baserede browsere på tidspunktet for skrivning). En robust strategi kræver ofte fallbacks eller polyfills for bredere kompatibilitet. - Overdreven Preloading: Ligesom med
preload
kan preloading af for mange moduler eller hele modulgrafikker unødvendigt stadig forbruge betydelig båndbredde og CPU-ressourcer, hvilket potentielt kan have en negativ indvirkning på den indledende sideindlæsning. Intelligent udvælgelse er afgørende. - Cache Invalidering: Da moduler parses og kompileres, kræver ændringer i ethvert modul i grafen gen-hentning og gen-parsing. Effektive cache-busting-strategier er vitale.
Kodeeksempel:
Preloading af et hovedapplikationsmodul og dets afhængigheder:
<head>
<link rel="modulepreload" href="/assets/js/main-app.js">
<link rel="modulepreload" href="/assets/js/utility-lib.js"> <!-- Hvis utility-lib er en afhængighed af main-app -->
<!-- Browseren vil automatisk opdage og preloade main-app's *andre* afhængigheder -->
</head>
<body>
<script type="module" src="/assets/js/main-app.js"></script>
</body>
Dynamisk import()
: Indlæsning efter Behov
Selvom det ikke er en preloading-strategi i sig selv, er dynamisk import()
fundamentalt forbundet med, hvordan moduler indlæses, og bruges ofte i kombination med preloading-hints. Det giver dig mulighed for at indlæse ES-moduler asynkront og betinget under kørsel i stedet for ved den indledende sideindlæsning.
Sådan virker det:
import()
-syntaksen returnerer et Promise, der resolveres med modul-namespace-objektet. Modulet og dets afhængigheder hentes, parses og eksekveres kun, når import()
-kaldet foretages. Dette gør det til et kraftfuldt værktøj til code splitting og lazy loading.
Anvendelsestilfælde:
- Rutebaseret Code Splitting: Indlæsning af forskellige JavaScript-bundles til forskellige applikationsruter (f.eks. indlæs kun 'admin'-modulet, når brugeren navigerer til admin-sektionen).
- Lazy Loading på Komponentniveau: Indlæsning af specifikke UI-komponenter kun, når de bliver synlige eller interageres med (f.eks. et komplekst billedgalleri, en rich text editor).
- Feature Flags: Indlæsning af valgfrie funktioner baseret på brugerrettigheder eller konfiguration.
Synergi med Preloading:
Den sande styrke opstår, når dynamisk import()
kombineres med preloading-strategier:
- Du kan bruge
<link rel="preload" as="script" href="...">
til at forhåndshente det JavaScript-bundle, der vil blive indlæst af et fremtidigtimport()
-kald. Dette sikrer, at filen allerede er downloadet, nårimport()
påkaldes, hvilket reducerer netværkslatensen. - For ES-moduler er
<link rel="modulepreload" href="...">
endnu mere effektivt, da det henter, parser og kompilerer det dynamiske modul og dets afhængigheder, hvilket gørimport()
-opløsningen praktisk talt øjeblikkelig fra et CPU-perspektiv.
Kodeeksempel:
Kombination af dynamisk import med modulepreload
:
<head>
<link rel="modulepreload" href="/assets/js/chart-component.js">
</head>
<body>
<div id="chartContainer"></div>
<button id="loadChartBtn">Indlæs Diagram</button>
<script type="module">
document.getElementById('loadChartBtn').addEventListener('click', async () => {
// Modulet er allerede blevet preloadet, parset og kompileret.
// Denne import vil være betydeligt hurtigere.
const { renderChart } = await import('/assets/js/chart-component.js');
renderChart('chartContainer', { /* diagramdata */ });
});
</script>
</body>
Avancerede Strategier og Overvejelser for Global Implementering
Implementering af grundlæggende preloading er en god start, men for optimal performance på tværs af en global brugerbase kommer flere avancerede overvejelser i spil.
Kombination af Strategier for Optimal Effekt
De mest effektive preloading-strategier involverer ofte en gennemtænkt kombination af hints, skræddersyet til specifikke scenarier:
- Kritisk Indledende Indlæsning: Brug
<link rel="modulepreload">
til din applikations rod-ES-moduler og deres essentielle afhængigheder. For ikke-modul kritisk JavaScript, skrifttyper eller billeder, brug<link rel="preload">
. Dette sikrer, at kerneoplevelsen indlæses så hurtigt som muligt. - Forventede Brugerrejser: For moduler, der understøtter den næste sandsynlige side eller interaktion, anvend
<link rel="prefetch">
. Dette er især nyttigt for brugerflows, der er almindelige, men ikke essentielle for den allerførste paint (f.eks. en kompleks filter-UI på en søgeresultatside). - Interaktive Funktioner: For funktioner, der udløses af brugerinteraktion (som at åbne en modal, afsløre en rich text editor eller aktivere en kortkomponent), brug dynamisk
import()
. Afgørende er det at ledsage disse dynamiske importer med en tilsvarende<link rel="modulepreload">
(eller<link rel="preload">
for ikke-ESM-scripts) i<head>
for at sikre, at ressourcen er klar, når brugeren klikker.
Moderne build-værktøjer som Webpack, Rollup og Vite har ofte indbygget understøttelse for automatisk at generere disse hints, når du bruger dynamisk import()
(f.eks. Webpacks webpackPrefetch
og webpackPreload
-kommentarer). Dette automatiserer meget af det manuelle arbejde og sikrer korrekt syntaks.
HTTP/2 og HTTP/3: Netværkslagets Rolle
Den underliggende netværksprotokol påvirker i høj grad effektiviteten af preloading-strategier:
- HTTP/1.1: Lider af "head-of-line blocking", hvilket betyder, at kun én ressource kan downloades pr. TCP-forbindelse ad gangen. Dette begrænser alvorligt fordelene ved preloading, da ressourcer stadig stiller sig i kø.
- HTTP/2: Introducerede multiplexing, der tillader, at flere ressourcer downloades samtidigt over en enkelt TCP-forbindelse. Dette reducerer drastisk virkningen af netværkslatens og gør preloading (især
preload
ogmodulepreload
) langt mere effektivt, da browseren kan downloade hints og andre kritiske ressourcer parallelt. - HTTP/2 Server Push (Forældet til de fleste anvendelser): Historisk set tillod server push serveren at proaktivt sende ressourcer til klienten uden en eksplicit anmodning. Selvom det konceptuelt ligner preloading, viste det sig svært at implementere effektivt på grund af cache-problemer og browser-heuristikker.
<link rel="preload">
foretrækkes nu generelt, fordi det giver browseren mere kontrol over ressourceprioritering og caching. - HTTP/3: Bygget på QUIC forbedrer HTTP/3 yderligere performance ved at reducere forbindelsesopsætningstider og forbedre tabsgendannelse, hvilket er særligt gavnligt i upålidelige netværksmiljøer, der er almindelige i mange globale regioner. Dette forstærker gevinsterne fra intelligent preloading, da det grundlæggende netværkslag er mere effektivt.
At sikre, at din server understøtter og anvender HTTP/2 (og ideelt set HTTP/3) er et grundlæggende skridt for at maksimere virkningen af enhver preloading-strategi.
Browser Support og Fallbacks
Mens preload
og prefetch
nyder bred understøttelse, er modulepreload
nyere, og dets understøttelse udvikler sig stadig på tværs af browsere. En global udviklingsstrategi skal tage højde for dette:
- Feature Detection: Du kan programmatisk tjekke for understøttelse. For eksempel, for at tjekke for
modulepreload
, kan du parse DOM'en for<link>
-elementer medrel="modulepreload"
. Dette er dog normalt mindre praktisk for deklarative hints. - Progressiv Forbedring: Design din applikation, så den fungerer korrekt, selvom preloading-hints ignoreres. Preloading bør være en forbedring, ikke et krav for funktionalitet. Brugere på ældre browsere vil stadig få indholdet, bare potentielt langsommere.
- Værktøjer til Polyfills/Fallbacks: Nogle build-værktøjer kan generere `