Skjut upp laddning av bilder utanför skärmen på mobil
Skjut upp laddning av bilder utanför skärmen på mobil

Uppskjuten bildladdning på mobil: standarden
Mobilprestanda hålls ofta tillbaka av nätverkslatens (RTT) och tillgänglighet för main-thread CPU. Att skjuta upp bilder utanför skärmen på mobil adresserar båda problemen genom att förhindra bandbreddskonkurrens på den kritiska renderingsvägen och fördela bildavkodningskostnader över sessionens varaktighet.
Det här dokumentet förklarar hur man effektivt skjuter upp bildladdning på mobil, när man ska använda det och tar upp de specifika tekniska begränsningarna för mobila viewports.

1. Skjut upp bilder utanför skärmen på mobil: native lazy loading
När en webbläsare laddar en sida öppnar den ett begränsat antal parallella anslutningar (beroende på många faktorer men 6 per domän är ett vanligt genomsnitt). Om dessa anslutningar används för att ladda ner bilder utanför skärmen (t.ex. en logotyp i sidfoten eller en karusellbild) kommer nedladdningen av kritiska resurser (vanligtvis LCP-bilden, viktiga skript och typsnitt att konkurrera om platser och bandbredd). Detta fenomen, känt som Network Contention, försämrar Core Web Vitals direkt.
Genom att skjuta upp bilder utanför skärmen med det inbyggda loading-attributet kan vi prioritera viktiga resurser och optimera den kritiska renderingsvägen. Webbläsaren hämtar bara det som är omedelbart synligt och reserverar bandbredd för de tillgångar som strikt påverkar First Contentful Paint (FCP) och Largest Contentful Paint (LCP). Den inbyggda lazy loading-metoden överför denna prioriteringslogik till webbläsarens mycket snabbare interna mekanism, vilket eliminerar behovet av gamla och långsamma JavaScript-bibliotek.
Implementering
För alla bilder under den initiala viewporten ("the fold") lägg till attributet loading="lazy".
<!-- Standard Deferred Image -->
<img src="product-detail.jpg"
alt="Side view of the chassis"
width="800"
height="600"
decoding="async"> Hur lazy loading fungerar på mobil: webbläsarens heuristik
Native lazy loading är överlägset JavaScript-lösningar eftersom webbläsaren justerar laddningströskeln (när en bild triggas för nedladdning) baserat på Effective Connection Type (ECT).
- På 4G/WiFi: Blink-motorn (Chrome/Edge) använder en konservativ tröskel (t.ex. 1250px). Den antar låg latens och hämtar bilden först när användaren är relativt nära viewporten.
- På 3G/Slow-2G: Tröskeln utökas (t.ex. 2500px). Webbläsaren initierar begäran mycket tidigare i förhållande till scrollpositionen för att kompensera för höga rundturstider, vilket säkerställer att bilden är redo innan användaren scrollar den in i viewporten.
Kritiskt undantag: LCP-kandidaten
En vanlig prestandaregression uppstår när utvecklare tillämpar loading="lazy" på Largest Contentful Paint (LCP)-elementet (vanligtvis hjältebilden). Detta fördröjer hämtningen tills layouten är klar.
Korrekt LCP-strategi: LCP-bilden måste eager-laddas och prioriteras.
<!-- Hero Image: Eager and Prioritized -->
<img src="hero.jpg"
alt="Summer Collection"
width="1200"
height="800"
> 2. Mobila komplexiteter: Viewport och Touch
Mobila viewports introducerar specifika renderingsutmaningar som native-implementering hanterar mer robust än skriptbaserade lösningar.
- Viewporten: Det synliga rektangulära området i webbläsarfönstret. På mobil är detta dynamiskt; det ändrar dimensioner baserat på enhetens orientering (porträtt kontra landskap) och tillståndet för webbläsarkromet (URL-fält som dras tillbaka).
- The Fold: Den exakta nedre kanten av viewporten. Det är tröskeln som skiljer synligt innehåll från innehåll utanför skärmen.
- Above the Fold: Allt innehåll som är synligt omedelbart vid sidladdning utan scrollning. Bilder här är ofta kritiska och bör nästan aldrig lazy-laddas.
- Below the Fold: Allt innehåll som befinner sig vertikalt förbi the fold. Detta innehåll är icke-kritiskt och måste skjutas upp tills användaren scrollar nära det.

Den dynamiska viewporten
I mobila webbläsare är viewport-höjden (vh) flytande. När användaren initierar en touch-scroll drar sig URL-fältet och navigationskontrollerna ofta tillbaka, vilket ändrar storleken på det synliga området.
JavaScript-baserade bilduppskjutningsbibliotek beräknar vanligtvis viewport-höjden (window.innerHeight) bara en gång vid sidladdningen. När mobila webbläsare dynamiskt ändrar storlek på det synliga området genom att dölja URL-fältet under en scroll fortsätter JavaScript-metoder att använda det gamla, mindre höjdvärdet. Detta orsakade att bilder förblev oladdade även när de fysiskt kom in i det utökade viewport-området, vilket orsakade dålig UX för besökarna.
Native-hantering löser detta problem eftersom webbläsarens interna layoutmotor spårar den visuella viewporten automatiskt, vilket säkerställer att triggers avfyras oavsett eventuella viewport-storleksändringar.
3. Bildavkodning på mobil och CPU-begränsning
Mobila enheter har begränsad CPU och bildavkodning på mobil kan vara relativt långsam och kostsam. Att konvertera en JPEG till en bitmapp kräver många CPU-cykler. På en mobil processor kan avkodning av en sekvens av större bilder blockera main thread i 50ms–100ms vardera, vilket orsakar input-latens.
Lösningen: content-visibility
För att lösa detta kan vi använda CSS-egenskapen och värdet content-visibility: auto. Denna egenskap fungerar som en standard för "Lazy Rendering." Den instruerar webbläsaren att hoppa över layout- och målningsfaserna för element utanför skärmen helt. Elementet finns i DOM, men det finns inte i renderingsträdet förrän det närmar sig viewporten.
Eftersom denna optimering fungerar genom att hoppa över renderingen av ett elements underträd kan du inte tillämpa den direkt på en <img>-tagg (som inte har något underträd). Du bör tillämpa content-visibility på produktbehållaren eller bildkortet som innehåller dessa bilder och dess innehåll.
@media (max-width: 768px) {
.image-card, .product-card {
/* Skip rendering of the container and its children */
content-visibility: auto;
/* Essential: Prevents container from collapsing to 0px height */
contain-intrinsic-size: auto 300px;
}
}
Detta säkerställer att även om en bild laddas ner betalar webbläsaren inte layout/paint-kostnaden förrän användaren faktiskt scrollar till den.
4. Äldre metoder: Varför man bör undvika dem
Innan native-stöd förlitade sig utvecklare på JavaScript för mobil bilduppskjutning. Dessa metoder används fortfarande i stor utsträckning men bör betraktas som teknisk skuld!
"Scroll Handler"-eran (2010–2016)
Tidiga implementeringar kopplade händelselyssnare till scroll-eventet.
// OBSOLETE: Do not use
window.addEventListener('scroll', () => {
images.forEach(img => {
if (img.getBoundingClientRect().top < window.innerHeight) {
img.src = img.dataset.src;
}
});
}); Main Thread-blockering: Scroll-eventet avfyras dussintals gånger per sekund. Att exekvera logik och beräkna layout (getBoundingClientRect) under aktiv scrollning orsakade frame drops (jank).
Layout Thrashing: Att fråga efter geometriska egenskaper tvingar webbläsaren att synkront omberäkna layoutstilen, en beräkningsmässigt dyr operation på mobila CPU:er.
IntersectionObserver-eran (2016–2019)
IntersectionObserver API förbättrade prestandan genom att asynkront observera förändringar i elementsynlighet.
// DEPRECATED: Use native loading where possible
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});Skriptberoende: Det kräver JavaScript-exekvering. Om main thread är upptagen med att hydrera ett ramverk (React/Vue) förblir bilderna oladdade även om de är i viewporten.
Avsaknad av nätverksmedvetenhet: Till skillnad från native loading använder IntersectionObserver fasta marginaler (t.ex. rootMargin: '200px'). Den utökar inte automatiskt sin buffert på långsamma nätverk, vilket leder till "vita blinkar" för användare med dåliga anslutningar.
Urgent Fix Required?
Google Search Console failing? I offer rapid-response auditing to identify the failure point within 48 hours.
- 48hr Turnaround
- Rapid Response
- Failure Identification

