"Display: none" impedisce il caricamento di un'immagine?


336

Ogni tutorial di sviluppo di siti Web reattivi consiglia di utilizzare la display:noneproprietà CSS per nascondere il caricamento dei contenuti sui browser mobili in modo che il sito Web si carichi più velocemente. È vero? Non display:nonecarica le immagini o carica ancora il contenuto sul browser mobile? Esiste un modo per impedire il caricamento di contenuti non necessari sui browser mobili?


6
Sembra che ci siano alcuni modi per impedire il download con display: nessuno, ma non il modo vaniglia: timkadlec.com/2012/04/media-query-asset-downloading-results
mrwweb

1
Il W3C lo sta testando attivamente: w3.org/2009/03/image-display-none/test.php
Pino,

Risposte:


191

I browser stanno diventando più intelligenti. Oggi il tuo browser (a seconda della versione) potrebbe saltare il caricamento dell'immagine se può determinare che non è utile.

L'immagine ha un display:none stile ma le sue dimensioni possono essere lette dalla sceneggiatura. Chrome v68.0 non carica le immagini se il genitore è nascosto.

Puoi controllarlo qui: http://jsfiddle.net/tnk3j08s/

Potresti anche averlo verificato guardando la scheda "rete" degli strumenti di sviluppo del tuo browser.

Si noti che se il browser si trova su un piccolo computer CPU, non dover rendere l'immagine (e il layout della pagina) renderà più veloce l'intera operazione di rendering, ma dubito che questo sia qualcosa che abbia davvero senso oggi.

Se vuoi impedire il caricamento dell'immagine, potresti semplicemente non aggiungere l'elemento IMG al tuo documento (o impostare l' srcattributo IMG su "data:"o "about:blank").


50
un'immagine vuota src è pericolosa. Invia una richiesta aggiuntiva al server. una buona lettura su questo argomento nczonline.net/blog/2009/11/30/…
Srinivas

2
@SrinivasYedhuri Sì, hai ragione. Ho modificato con una soluzione migliore.
Denys Séguret,

8
Questa risposta è solo parzialmente corretta. Ho appena provato questo su Google Chrome (v35) e posso confermare che le immagini con display impostato su none non vengono scaricate. Ciò è probabilmente per rendere più semplice la progettazione reattiva per lo sviluppatore.
Shawn Whinnery,

15
Questa risposta non è più corretta. Vedi sotto per i risultati aggiornati di come vari browser, inclusa l'ultima versione di FF, gestiscono questa situazione in modo diverso
DMTintner,

2
Ancora oggi (ottobre 2017), il browser Chrome più comune scaricherà tutte le fonti degli elementi 'img', anche se sono nascoste. Non scaricherà immagini di sfondo nascoste.
TKoL,

130

Se trasformi l'immagine in un'immagine di sfondo di un div in CSS, quando quel div è impostato su "display: none", l'immagine non verrà caricata. Quando il CSS è disabilitato, non verrà ancora caricato, perché, beh, il CSS è disabilitato.


17
Questo è in realtà un suggerimento molto utile per un design reattivo secondo me.
ryandlf,

3
Funziona in FF, Chrome, Safari, Opera, Maxthon. Non ho provato nessun IE.
Brent,

13
Ultime novità dal fronte! <div hidden style="display:none;width:0;height:0;visibility:hidden;background:url('test.jpg')"></div>. Risultati: Firefox 29 e Opera 12 non vengono caricati. Caricamento di IE 11 e Chrome 34.
CoolCmd,

3
@CoolCmd per un design reattivo questa è ancora un'opzione praticabile, come è possibile nella query media CSS impostata background-imagesu noneper i casi in cui non si desidera caricare l'immagine. Non ho trovato alcuna alternativa migliore per questo caso d'uso che non utilizza JS.
Qtax

1
Ho testato un dispositivo di scorrimento delle immagini (che utilizzava immagini di sfondo) con una query multimediale di larghezza minima. Al di sotto di quella larghezza, il div padre aveva CSS display: none;. Test di rete con finestra al di sotto di quella larghezza: Chrome 35, IE11 e Edge non hanno caricato le immagini
binaryfunt,

57

La risposta non è facile come un semplice sì o no. Guarda i risultati di un test che ho fatto di recente:

  • In Chrome: tutte e 8 le schermate- * immagini caricate (img 1)
  • In Firefox: viene visualizzata solo l'immagine 1- * caricata attualmente visualizzata (img 2)

Quindi, dopo aver scavato ulteriormente, ho trovato questo , che spiega come ogni browser gestisce il caricamento delle risorse img in base alla visualizzazione CSS: nessuna;

Estratto dal post del blog:

  • Chrome e Safari (WebKit):
    WebKit scarica il file ogni volta, tranne quando viene applicato uno sfondo tramite una media query non corrispondente.
  • Firefox:
    Firefox non scaricherà l'immagine chiamata con l'immagine di sfondo se gli stili sono nascosti ma scaricheranno comunque risorse dai tag img.
  • Opera:
    Come Firefox, Opera non carica inutili immagini di sfondo.
  • Internet Explorer:
    IE, come WebKit, scaricherà le immagini di sfondo anche se sono visualizzate: nessuna; Qualcosa di strano appare con IE6: elementi con un'immagine di sfondo e display: nessuno impostato in linea non verrà scaricato ... Ma lo saranno se quegli stili non vengono applicati in linea.

Chrome- Tutte e 8 le schermate- * immagini caricate

Firefox: viene caricata solo l'immagine 1 screenshot- * attualmente visualizzata


1
Fintanto che tali risultati non fanno parte degli standard, sono piuttosto inutili. Chrome cambia il motore di rendering, anche l'opera cambia e IE verrà sostituito con qualcos'altro. Non puoi contare sull'implementazione di funzioni marginali come questa per rimanere stabili nel tempo. La soluzione sarà un modo per suggerire al browser quando una risorsa dovrebbe essere caricata pigramente se non del tutto.
Mark Kaplun il

5
@MarkKaplun Non stavo suggerendo che questi risultati dei test dovrebbero mostrarti esattamente cosa puoi aspettarti che accada sempre con ogni browser. Volevo solo dimostrare che la risposta non è "semplice come sì o no". ogni browser lo sta implementando in modo diverso e probabilmente continuerà a essere così per un po '
DMTintner

@DMTintner esattamente giusto. e fino ad oggi posso confermare immagini di sfondo caricate su Safari iOS di div che erano "display: none". l'approccio migliore è quello di non assumere nulla e se non si desidera caricare un'immagine, non farne riferimento in un tag html
bhu Boue vidya,

34

Il <picture>tag HTML5 ti aiuterà a risolvere l'origine dell'immagine corretta in base alla larghezza dello schermo

Apparentemente il comportamento dei browser non è cambiato molto negli ultimi 5 anni e molti scaricheranno comunque le immagini nascoste, anche se su di esse fosse display: noneimpostata una proprietà.

Anche se esiste una soluzione alternativa alle query multimediali , potrebbe essere utile solo quando l'immagine è stata impostata come sfondo nel CSS.

Mentre pensavo che ci fosse solo una soluzione JS al problema ( caricamento lento , riempimento di immagini , ecc.), Mi è sembrato che ci sia una bella soluzione HTML pura che viene fuori dalla scatola con HTML5.

E questo è il <picture>tag.

Ecco come lo descrive MDN :

L' elemento HTML<picture> è un contenitore utilizzato per specificare più <source>elementi per uno specifico <img>contenuto in esso. Il browser sceglierà la fonte più adatta in base al layout corrente della pagina (i vincoli del riquadro in cui apparirà l'immagine) e il dispositivo su cui verrà visualizzato (ad esempio un dispositivo normale o hiDPI.)

Ed ecco come usarlo:

<picture>
 <source srcset="mdn-logo-wide.png" media="(min-width: 600px)">
 <img src="mdn-logo-narrow.png" alt="MDN">
</picture>

La logica dietro

Il browser carica l'origine del imgtag, solo se nessuna delle regole multimediali si applica. Quando l' <picture>elemento non è supportato dal browser, tornerà nuovamente a mostrare il imgtag.

Normalmente si inserisce l'immagine più piccola come sorgente del file <img>e quindi non si caricano le immagini pesanti per schermi più grandi. Viceversa, se si applica una regola multimediale, la fonte del <img>non verrà scaricata, ma scaricherà il contenuto dell'URL del <source>tag corrispondente .

L'unico inconveniente qui è che se l'elemento non è supportato dal browser, caricherà solo l'immagine piccola. D'altra parte, nel 2017 dovremmo pensare e programmare nel primo approccio mobile .

E prima che qualcuno fosse troppo uscito, ecco l' attuale supporto del browser per <picture>:

Browser desktop

Supporto per browser desktop

Browser per dispositivi mobili

Supporto per browser mobili

Ulteriori informazioni sul supporto del browser sono disponibili su Posso usare .

La cosa buona è che la frase di html5please è usarla con un fallback . E personalmente intendo prendere il loro consiglio.

Maggiori informazioni sul tag sono disponibili nelle specifiche del W3C . C'è un disclaimer lì, che trovo importante menzionare:

L' pictureelemento è in qualche modo diverso dall'aspetto simile videoe dagli audioelementi. Mentre tutti contengono sourceelementi, l' srcattributo dell'elemento source non ha significato quando l'elemento è nidificato all'interno di un pictureelemento e l'algoritmo di selezione delle risorse è diverso. Inoltre, l' pictureelemento stesso non mostra nulla; fornisce semplicemente un contesto per il suo imgelemento contenuto che gli consente di scegliere tra più URL.

Quindi, ciò che dice è che ti aiuta a migliorare le prestazioni solo quando si carica un'immagine, fornendo un contesto ad essa.

E puoi ancora usare un po 'di magia CSS per nascondere l'immagine su piccoli dispositivi:

<style>
  picture { display: none; }

  @media (min-width: 600px) {
    picture {
      display: block;
    }
  }
</style>

<picture>
 <source srcset="the-real-image-source" media="(min-width: 600px)">
 <img src="a-1x1-pixel-image-that-will-be-hidden-in-the-css" alt="MDN">
</picture>

Pertanto, il browser non visualizzerà l'immagine reale e scaricherà solo l' 1x1immagine pixel (che può essere memorizzata nella cache se la si utilizza più di una volta). Tieni presente, tuttavia, che se il <picture>tag non è supportato dal browser, anche sugli schermi descktop l'immagine reale non verrà visualizzata (quindi avrai sicuramente bisogno di un backup polyfill lì).


4
Ho preso una strada simile a te, ma invece uso un data-img :) Ecco un post che ho scritto su swimburger.net/blog/web/…
Swimburger

10

Sì, il rendering sarà più veloce, leggermente, solo perché non è necessario renderizzare l'immagine ed è un elemento in meno da ordinare sullo schermo.

Se non vuoi caricarlo, lascia un DIV vuoto dove puoi caricare html in esso contenente successivamente un <img>tag.

Prova a utilizzare firebug o WireShark come ho già detto prima e vedrai che i file vengono trasferiti anche se display:noneè presente.

Opera è l'unico browser che non caricherà l'immagine se il display non è impostato su nessuno. Opera è ora passato al webkit e renderà tutte le immagini anche se il loro display non è impostato su nessuno.

Ecco una pagina di test che lo dimostrerà:

http://www.quirksmode.org/css/displayimg.html


9

** Risposta 2019 **

In una situazione normale display:nonenon impedisce il download dell'immagine

/*will be downloaded*/

#element1 {
    display: none;
    background-image: url('https://picsum.photos/id/237/100');
}

Ma se un elemento antenato ha display:nonele immagini del discendente non verranno scaricate


/* Markup */

<div id="father">
    <div id="son"></div>
</div>


/* Styles */

#father {
    display: none;
}

/* #son will not be downloaded because the #father div has display:none; */

#son {
    background-image: url('https://picsum.photos/id/234/500');
}

Altre situazioni che impediscono il download dell'immagine:

1- L'elemento target non esiste

/* never will be downloaded because the target element doesn't exist */

#element-dont-exist {
    background-image: url('https://picsum.photos/id/240/400');
}

2- Due classi uguali che caricano immagini diverse

/* The first image of #element2 will never be downloaded because the other #element2 class */

#element2 {
    background-image: url('https://picsum.photos/id/238/200');
}

/* The second image of #element2 will be downloaded */

#element2 {
    background-image: url('https://picsum.photos/id/239/300');
}

Puoi guardarlo qui: https://codepen.io/juanmamenendez15/pen/dLQPmX


8

Modalità Quirks: immagini e display: nessuna

Quando l'immagine ha display: noneo è all'interno di un elemento con display:none, il browser può scegliere di non scaricare l'immagine fino a quando non display viene impostato su un altro valore.

Solo Opera scarica l'immagine quando si passa displaya block. Tutti gli altri browser lo scaricano immediatamente.


8

L'immagine di sfondo di un elemento div verrà caricata se il div è impostato fare 'display: none'.

Comunque, se quello stesso div ha un genitore e quel genitore è impostato su 'display: none', l'immagine di sfondo dell'elemento figlio non verrà caricata . :)

Esempio usando bootstrap:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<div class="col-xs-12 visible-lg">
	<div style="background-image: url('http://via.placeholder.com/300x300'); background-repeat:no-repeat; height: 300px;">lg</div>
</div>
<div class="col-xs-12 visible-md">
	<div style="background-image: url('http://via.placeholder.com/200x200'); background-repeat:no-repeat; height: 200px;">md</div>
</div>
<div class="col-xs-12 visible-sm">
	<div style="background-image: url('http://via.placeholder.com/100x100'); background-repeat:no-repeat; height: 100px">sm</div>
</div>
<div class="col-xs-12 visible-xs">
	<div style="background-image: url('http://via.placeholder.com/50x50'); background-repeat:no-repeat; height: 50px">xs</div>
</div>



4

Se trasformi l'immagine in un'immagine di sfondo di un div in CSS, quando quel div è impostato su 'display: none', l'immagine non verrà caricata.

Sto solo espandendo la soluzione di Brent.

Puoi fare quanto segue per una soluzione CSS pura, inoltre fa sì che la scatola img si comporti effettivamente come una scatola img in un'impostazione di progettazione reattiva (è a questo che serve il png trasparente), che è particolarmente utile se la tua progettazione utilizza responsive-dinamicamente- ridimensionamento delle immagini.

<img style="display: none; height: auto; width:100%; background-image: 
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block 
visible-lg-block" src="img/400x186_trans.png" alt="pic 1 mofo">

L'immagine verrà caricata solo quando viene attivata la query multimediale legata a visible-lg-block e viene visualizzato: nessuno viene modificato per visualizzare: blocco. Il png trasparente viene utilizzato per consentire al browser di impostare l'altezza appropriata: rapporti di larghezza per il tuo blocco <img> (e quindi l'immagine di sfondo) in un design fluido (altezza: auto; larghezza: 100%).

1078/501 = ~2.15  (large screen)
400/186  = ~2.15  (small screen)

Quindi si finisce con qualcosa di simile al seguente, per 3 diversi viewport:

<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">

E durante il caricamento iniziale vengono caricate solo le dimensioni predefinite delle dimensioni della viewport multimediale, quindi, a seconda della viewport, le immagini verranno caricate in modo dinamico.

E nessun javascript!



2

Ciao ragazzi, stavo lottando con lo stesso problema, come non caricare un'immagine sul cellulare.

Ma ho trovato una buona soluzione. Prima crea un tag img e poi carica un svg vuoto nell'attributo src. Ora puoi impostare il tuo URL sull'immagine come uno stile in linea con il contenuto: url ('link alla tua immagine') ;. Ora avvolgi il tuo tag img in un wrapper di tua scelta.

<div class="test">
  <img src="data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/‌​svg%22/%3E" style="content:url('https://blog.prepscholar.com/hubfs/body_testinprogress.gif?t=1495225010554')">
</div>

  @media only screen and (max-width: 800px) {
      .test{
       display: none;
      }
    }

Impostare il wrapper per non visualizzare nessuno sul punto di interruzione in cui non si desidera caricare l'immagine. Il css inline del tag img ora viene ignorato poiché lo stile di un elemento avvolto in un wrapper con display none verrà ignorato, quindi l'immagine non viene caricata, fino a quando non si raggiunge un punto di interruzione in cui il wrapper ha un blocco display.

Ecco fatto, un modo davvero semplice di non caricare un img sul breakpoint mobile :)

Dai un'occhiata a questo codice, per un esempio funzionante: http://codepen.io/fennefoss/pen/jmXjvo


Adoro come il web continua a evolversi, non avevo mai visto questo trucco prima, usando la contentproprietà per modificare l'immagine mostrata, cioè. Puoi fornire alcune statistiche sulla compatibilità al riguardo?
Windgazer,

Peccato per Edge: /, almeno funziona nelle ultime versioni di Firefox, Chome e Safari.
Mikkel Fennefoss,

2

No. L'immagine verrà caricata come al solito e continuerà a utilizzare la larghezza di banda dell'utente se stai considerando il risparmio della larghezza di banda dell'utente del telefono cellulare. Quello che puoi fare è utilizzare la query multimediale e filtrare i dispositivi su cui desideri caricare l'immagine. l'immagine deve essere impostata come immagine di sfondo di un div, ecc. e NON di un tag poiché il tag immagine caricherà l'immagine indipendentemente dal fatto che le dimensioni dello schermo e il set di query multimediali.


1

Un'altra possibilità è usare un <noscript>tag e posizionare l'immagine all'interno del <noscript>tag. Quindi utilizzare JavaScript per rimuovere il noscripttag di cui hai bisogno dell'immagine. In questo modo è possibile caricare immagini su richiesta utilizzando il miglioramento progressivo.

Usa questo polyfill che ho scritto per leggere il contenuto dei <noscript>tag in IE8

https://github.com/jameswestgate/noscript-textcontent


1

Usa il CSS di query @media, fondamentalmente abbiamo appena rilasciato un progetto in cui avevamo una enorme immagine di un albero sul desktop a lato ma non mostrato in schermi da tavolo / mobili. Quindi impedire che l'immagine si carichi è abbastanza semplice

Ecco un piccolo frammento:

.tree {
    background: none top left no-repeat; 
}

@media only screen and (min-width: 1200px) {
    .tree {
        background: url(enormous-tree.png) top left no-repeat;
    }
}

Puoi usare lo stesso CSS per mostrare e nascondere con display / visibilità / opacità, ma l'immagine si stava ancora caricando, questo è stato il codice più sicuro che ci è venuto in mente.


0

stiamo parlando di immagini che non si caricano sul cellulare, giusto? quindi cosa succede se hai appena fatto un @media (larghezza minima: 400px) {background-image: thing.jpg}

non cercherebbe quindi l'immagine solo al di sopra di una certa larghezza dello schermo?


-2

Il trucco per usare display: nessuno con le immagini è assegnare loro un ID. Questo perché non c'era molto codice necessario per farlo funzionare. Ecco un esempio usando le media query e 3 fogli di stile. Uno per telefono, uno per tablet e uno per desktop. Ho 3 immagini, l'immagine di un telefono, un tablet e un desktop. Sullo schermo di un telefono verrà visualizzata solo un'immagine del telefono, un tablet visualizzerà solo l'immagine del tablet, un desktop verrà visualizzato sull'immagine del computer desktop. Ecco un esempio di codice per farlo funzionare:

Codice sorgente:

<div id="content">
<img id="phone" src="images/phone.png" />
<img id="tablet" src="images/tablet.png" />
<img id="desktop" src="images/desktop.png" />
</div>

Il CSS del telefono che non richiede una query multimediale. È il telefono img # che lo fa funzionare:

img#phone {
    display: block;
    margin: 6em auto 0 auto;
    width: 70%;
    }

img#tablet {display: none;}
img#desktop {display: none;}

Il tablet css:

@media only screen and (min-width: 641px) {
img#phone {display: none;}

img#tablet {
    display: block;
    margin: 6em auto 0 auto;
    width: 70%;
    }
}

E il desktop css:

@media only screen and (min-width: 1141px) {
img#tablet {display: none;}

img#desktop {
    display: block;
    margin: 6em auto 0 auto;
    width: 80%;
    }
}

Buona fortuna e fammi sapere come funziona per te.


4
La domanda non è come impostare un display: nonesu un'immagine. È: "display: none" impedisce il caricamento di un'immagine?
Evgenia Manolova,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.