«Afficher: aucun» empêche-t-il le chargement d'une image?

336

Chaque didacticiel de développement de site Web réactif recommande d'utiliser la display:nonepropriété CSS pour masquer le contenu du chargement sur les navigateurs mobiles afin que le site Web se charge plus rapidement. Est-ce vrai? Ne display:nonecharge pas les images ou charge-t-il toujours le contenu sur le navigateur mobile? Existe-t-il un moyen d'empêcher le chargement de contenu inutile sur les navigateurs mobiles?

méchant
la source
6
Il semble qu'il existe des moyens d'empêcher le téléchargement avec affichage: aucun, mais pas la manière vanille: timkadlec.com/2012/04/media-query-asset-downloading-results
mrwweb
1
Le W3C le teste activement: w3.org/2009/03/image-display-none/test.php
Pino

Réponses:

191

Les navigateurs deviennent plus intelligents. Aujourd'hui, votre navigateur (selon la version) peut ignorer le chargement de l'image s'il peut déterminer que cela n'est pas utile.

L'image a un display:nonestyle mais sa taille peut être lue par le script. Chrome v68.0 ne charge pas les images si le parent est masqué.

Vous pouvez le vérifier ici: http://jsfiddle.net/tnk3j08s/

Vous auriez également pu le vérifier en consultant l'onglet "réseau" des outils de développement de votre navigateur.

Notez que si le navigateur est sur un petit ordinateur CPU, ne pas avoir à rendre l'image (et mettre en page la page) rendra l'opération de rendu plus rapide mais je doute que ce soit vraiment logique aujourd'hui.

Si vous souhaitez empêcher le chargement de l'image, vous pouvez simplement ne pas ajouter l'élément IMG à votre document (ou définir l' srcattribut IMG sur "data:"ou "about:blank").

Denys Séguret
la source
50
une image vide src est dangereuse. Il envoie une demande supplémentaire au serveur. une bonne lecture sur ce sujet nczonline.net/blog/2009/11/30/…
Srinivas
2
@SrinivasYedhuri Oui, vous avez raison. J'ai édité avec une meilleure solution.
Denys Séguret
8
Cette réponse n'est que partiellement correcte. Je viens de tester cela sur Google Chrome (v35) et je peux confirmer que les images avec un affichage défini sur aucun ne sont pas téléchargées. C'est probablement pour rendre la conception réactive plus facile pour le développeur.
Shawn Whinnery
15
Cette réponse n'est plus correcte. Voir ci-dessous pour les résultats mis à jour de la façon dont différents navigateurs, y compris la dernière version de FF, gèrent cette situation différemment
DMTintner
2
Même aujourd'hui (octobre 2017), le navigateur le plus courant, Chrome, téléchargera toutes les sources d'éléments `` img '', même si elles sont masquées. Il ne téléchargera pas d'images d'arrière-plan cachées.
TKoL
130

Si vous faites de l'image une image d'arrière-plan d'un div en CSS, lorsque ce div est défini sur "display: none", l'image ne se charge pas. Lorsque CSS est désactivé, il ne se charge toujours pas, car, bien, CSS est désactivé.

Brent
la source
17
C'est en fait une astuce très utile pour un design réactif à mon avis.
ryandlf
3
Cela fonctionne dans FF, Chrome, Safari, Opera, Maxthon. Je n'ai essayé aucun IE.
Brent
13
Du nouveau sur le devant! <div hidden style="display:none;width:0;height:0;visibility:hidden;background:url('test.jpg')"></div>. Résultats: Firefox 29 et Opera 12 ne se chargent pas. Charge IE 11 et Chrome 34.
CoolCmd
3
@CoolCmd pour la conception réactive cela est encore une option viable, que vous pouvez dans l'ensemble de vos médias CSS background-imageà nonedes cas où vous ne voulez pas l'image à la charge. N'ont pas trouvé de meilleure alternative pour ce cas d'utilisation qui n'utilise pas JS.
Qtax
1
J'ai testé un curseur d'image (qui utilisait des images d'arrière-plan) qui avait une requête multimédia de largeur minimale. En dessous de cette largeur, le div parent avait CSS display: none;. Test de réseau avec une fenêtre inférieure à cette largeur: Chrome 35, IE11 et Edge n'ont pas chargé les images
binaryfunt
57

La réponse n'est pas aussi simple qu'un simple oui ou non. Découvrez les résultats d'un test que j'ai fait récemment:

  • Dans Chrome: les 8 captures d'écran- * images chargées (img 1)
  • Dans Firefox: seule la 1 capture d'écran- * image chargée actuellement affichée (img 2)

Donc, après avoir creusé plus loin, j'ai trouvé cela , ce qui explique comment chaque navigateur gère le chargement des ressources img en fonction de l'affichage css: aucun;

Extrait du billet de blog:

  • Chrome et Safari (WebKit):
    WebKit télécharge le fichier à chaque fois, sauf lorsqu'un arrière-plan est appliqué via une requête multimédia non correspondante.
  • Firefox:
    Firefox ne téléchargera pas l'image appelée avec l'image d'arrière-plan si les styles sont masqués, mais ils téléchargeront toujours les ressources des balises img.
  • Opera:
    comme Firefox, Opera ne chargera pas d'images d'arrière-plan inutiles.
  • Internet Explorer:
    IE, comme WebKit, téléchargera des images d'arrière-plan même si elles ont un affichage: aucun; Quelque chose d'étrange apparaît avec IE6: Éléments avec une image d'arrière-plan et un affichage: aucun ensemble en ligne ne sera pas téléchargé ... Mais ils le seront si ces styles ne sont pas appliqués en ligne.

Chrome - 8 captures d'écran - * images chargées

Firefox- Seule la 1 capture d'écran- * image chargée actuellement affichée

DMTintner
la source
1
Tant que ces résultats ne font pas partie des normes, ils sont tout à fait inutiles. Chrome change le moteur de rendu, les changements d'opéra également et IE sera remplacé par autre chose. Vous ne pouvez tout simplement pas compter sur la mise en œuvre de fonctionnalités marginales comme celle-ci pour rester stable dans le temps. La solution sera un moyen d'indiquer au navigateur quand un élément doit être chargé paresseusement, voire pas du tout.
Mark Kaplun
5
@MarkKaplun Je ne suggérais pas que ces résultats de test devraient vous montrer exactement ce que vous pouvez vous attendre à ce qu'il se passe toujours avec chaque navigateur. Je voulais seulement démontrer que la réponse n'est "pas aussi simple que oui ou non". chaque navigateur implémente actuellement cela différemment et cela continuera probablement de cette façon pendant un certain temps
DMTintner
@DMTintner exactement à droite. et dès aujourd'hui, je peux confirmer les images d'arrière-plan de div chargées par safari iOS qui étaient `display: none '. la meilleure approche est de ne rien supposer et si vous ne voulez pas qu'une image soit chargée, ne la référencez pas dans une balise html
bhu Boue vidya
34

La <picture>balise HTML5 vous aidera à résoudre la bonne source d'image en fonction de la largeur de l'écran

Apparemment, le comportement des navigateurs n'a pas beaucoup changé au cours des 5 dernières années et beaucoup téléchargeraient toujours les images cachées, même s'il y avait une display: nonepropriété définie dessus.

Même s'il existe une solution de contournement des requêtes multimédias , elle ne peut être utile que lorsque l'image a été définie comme arrière-plan dans le CSS.

Alors que je pensais qu'il n'y avait qu'une solution JS au problème ( chargement paresseux , remplissage d'image , etc.), il est apparu qu'il y avait une belle solution HTML pure qui sortait de la boîte avec HTML5.

Et c'est la <picture>balise.

Voici comment MDN le décrit:

L' élément HTML<picture> est un conteneur utilisé pour spécifier plusieurs <source>éléments pour un <img>contenu spécifique qu'il contient. Le navigateur choisira la source la plus appropriée en fonction de la disposition actuelle de la page (les contraintes de la boîte dans laquelle l'image apparaîtra) et l'appareil sur lequel elle sera affichée (par exemple, un appareil normal ou hiDPI.)

Et voici comment l'utiliser:

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

La logique derrière

Le navigateur chargerait la source de la imgbalise, uniquement si aucune des règles multimédias ne s'applique. Lorsque l' <picture>élément n'est pas pris en charge par le navigateur, il reviendra à nouveau à l'affichage de la imgbalise.

Normalement, vous mettriez la plus petite image comme source du <img>et donc ne chargeriez pas les images lourdes pour les écrans plus grands. Inversement, si une règle multimédia s'applique, la source du <img>fichier ne sera pas téléchargée, mais téléchargera le contenu de l'URL de la <source>balise correspondante .

Le seul écueil ici est que si l'élément n'est pas pris en charge par le navigateur, il ne chargera que la petite image. D'autre part, en 2017, nous devons penser et coder dans la première approche mobile .

Et avant que quelqu'un ne soit trop excité, voici le support actuel du navigateur pour <picture>:

Navigateurs de bureau

Prise en charge des navigateurs de bureau

Navigateurs mobiles

Prise en charge des navigateurs mobiles

Plus d'informations sur le support du navigateur que vous pouvez trouver sur Puis-je utiliser .

La bonne chose est que la phrase de html5please est de l' utiliser avec un repli . Et j'ai personnellement l'intention de prendre leur avis.

En savoir plus sur la balise que vous pouvez trouver dans les spécifications du W3C . Il y a un avertissement, que je trouve important de mentionner:

L' pictureélément est un peu différent des ressemblantes videoet des audioéléments. Bien qu'ils contiennent tous des sourceéléments, l' srcattribut de l'élément source n'a aucune signification lorsque l'élément est imbriqué dans un pictureélément et que l'algorithme de sélection des ressources est différent. De plus, l' pictureélément lui-même n'affiche rien; il fournit simplement un contexte pour son imgélément contenu qui lui permet de choisir parmi plusieurs URL.

Ce qu'il dit, c'est qu'il ne vous aide qu'à améliorer les performances lors du chargement d'une image, en lui fournissant un peu de contexte.

Et vous pouvez toujours utiliser de la magie CSS pour masquer l'image sur de petits appareils:

<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>

Ainsi, le navigateur n'affichera pas l'image réelle et ne téléchargera que l' 1x1image pixel (qui peut être mise en cache si vous l'utilisez plusieurs fois). Sachez cependant que si la <picture>balise n'est pas prise en charge par le navigateur, même sur les écrans descktop, l'image réelle ne sera pas affichée (vous aurez donc certainement besoin d'une sauvegarde polyfill).

Evgenia Manolova
la source
4
J'ai pris un itinéraire similaire à vous, mais utilisez plutôt un data-img :) Voici un article que j'ai écrit dessus swimburger.net/blog/web/…
Swimburger
10

Oui, le rendu sera plus rapide, légèrement, uniquement parce qu'il n'a pas à rendre l'image et qu'il s'agit d'un élément de moins à trier à l'écran.

Si vous ne voulez pas qu'il soit chargé, laissez un DIV vide où vous pourrez y charger du code HTML contenant plus tard une <img>balise.

Essayez d'utiliser Firebug ou Wireshark comme je l'ai mentionné précédemment et vous verrez que les fichiers sont transférés même s'ils display:nonesont présents.

Opera est le seul navigateur qui ne chargera pas l'image si l'affichage est réglé sur aucun. Opera est maintenant passé au webkit et rendra toutes les images même si leur affichage est défini sur aucun.

Voici une page de test qui le prouvera:

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

Dorian
la source
9

** Réponse 2019 **

Dans une situation normale display:nonen'empêche pas le téléchargement de l'image

/*will be downloaded*/

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

Mais si un élément ancêtre a display:nonealors les images du descendant ne seront pas téléchargées


/* 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');
}

Autres situations empêchant le téléchargement de l'image:

1- L'élément cible n'existe pas

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

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

2- Deux classes égales chargeant des images différentes

/* 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');
}

Vous pouvez regarder par vous-même ici: https://codepen.io/juanmamenendez15/pen/dLQPmX

Juanma Menendez
la source
8

Mode Quirks: images et affichage: aucun

Lorsque l'image contient display: noneou se trouve dans un élément avec display:none, le navigateur peut choisir de ne pas télécharger l'image tant que la valeur display n'est pas définie sur une autre valeur.

Seul Opera télécharge l'image lorsque vous basculez displayvers block. Tous les autres navigateurs le téléchargent immédiatement.

onlyurei
la source
8

L'image d'arrière-plan d'un élément div se chargera si le div est défini. 'Display: none'.

Quoi qu'il en soit, si ce même div a un parent et que ce parent est défini sur 'display: none', l'image d'arrière-plan de l'élément enfant ne se chargera pas . :)

Exemple utilisant 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>

ninja_corp
la source
4

Si vous faites de l'image une image d'arrière-plan d'un div en CSS, lorsque ce div est réglé sur 'display: none', l'image ne se charge pas.

Développer simplement la solution de Brent.

Vous pouvez effectuer les opérations suivantes pour une solution CSS pure, cela permet également à la boîte img de se comporter comme une boîte img dans un paramètre de conception réactif (c'est à cela que sert le png transparent), ce qui est particulièrement utile si votre conception utilise responsive-dynamically- redimensionnement des images.

<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'image ne sera chargée que lorsque la requête multimédia liée à visible-lg-block est déclenchée et affiche: aucune n'est modifiée pour afficher: bloc. Le png transparent est utilisé pour permettre au navigateur de définir des rapports hauteur / largeur appropriés pour votre bloc <img> (et donc l'image d'arrière-plan) dans une conception fluide (hauteur: auto; largeur: 100%).

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

Vous vous retrouvez donc avec quelque chose comme ce qui suit, pour 3 fenêtres différentes:

<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">

Et seules les images par défaut de la taille de la fenêtre d'affichage des médias se chargent pendant le chargement initial, puis après, selon votre fenêtre d'affichage, les images se chargeront dynamiquement.

Et pas de javascript!

ats
la source
2

Salut les gars, je me débattais avec le même problème, comment ne pas charger une image sur mobile.

Mais j'ai trouvé une bonne solution. Créez d'abord une balise img, puis chargez un svg vide dans l'attribut src. Vous pouvez maintenant définir votre URL vers l'image comme un style en ligne avec le contenu: url ('lien vers votre image') ;. Maintenant, enveloppez votre balise img dans un emballage de votre choix.

<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;
      }
    }

Définissez l'encapsuleur pour n'en afficher aucun sur le point d'arrêt où vous ne souhaitez pas charger l'image. Le css en ligne de la balise img est désormais ignoré car le style d'un élément enveloppé dans un wrapper avec display none sera ignoré, donc l'image n'est pas chargée, jusqu'à ce que vous atteigniez un point d'arrêt où le wrapper a un bloc d'affichage.

Voilà, moyen très simple de ne pas charger un img sur un point d'arrêt mobile :)

Consultez ce codepen, pour un exemple de travail: http://codepen.io/fennefoss/pen/jmXjvo

Mikkel Fennefoss
la source
J'adore la façon dont le Web continue d'évoluer, je n'avais jamais vu cette astuce auparavant, en utilisant la contentpropriété pour modifier l'image affichée, c'est-à-dire. Pouvez-vous donner des statistiques sur la compatibilité à ce sujet?
Windgazer
Dommage pour Edge: /, au moins cela fonctionne dans les dernières versions de Firefox, Chome et Safari.
Mikkel Fennefoss
2

Non, l'image sera chargée comme d'habitude et utilisera toujours la bande passante de l'utilisateur si vous envisagez d'économiser la bande passante de l'utilisateur du téléphone mobile.Ce que vous pouvez faire est d'utiliser la requête multimédia et de filtrer les appareils que vous souhaitez que votre image soit chargée. l'image doit être définie comme image d'arrière-plan d'un div, etc. et NON comme une balise car la balise d'image chargera l'image indépendamment de la taille d'écran et de la requête de média définies.

IsuNas Labs
la source
1

Une autre possibilité consiste à utiliser une <noscript>balise et à placer l'image à l'intérieur de la <noscript>balise. Ensuite, utilisez javascript pour supprimer la noscriptbalise car vous avez besoin de l'image. De cette façon, vous pouvez charger des images à la demande en utilisant l'amélioration progressive.

Utilisez ce polyfill que j'ai écrit pour lire le contenu des <noscript>balises dans IE8

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

James Westgate
la source
1

Utilisez @media query CSS, fondamentalement, nous venons de publier un projet où nous avions une énorme image d'un arbre sur le bureau sur le côté mais ne montrant pas dans les écrans de table / mobiles. Donc, empêchez l'image de se charger assez facilement

Voici un petit extrait:

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

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

Vous pouvez utiliser le même CSS pour afficher et masquer avec affichage / visibilité / opacité mais l'image était toujours en cours de chargement, c'était le code le plus sûr que nous ayons trouvé.

Joakim Ling
la source
0

nous parlons d'images ne se chargeant pas sur mobile, non? et si vous venez de faire un @media (min-width: 400px) {background-image: thing.jpg}

ne chercherait-il alors que l'image au-dessus d'une certaine largeur d'écran?

Superfly5000
la source
-2

L'astuce pour utiliser l'affichage: aucune avec des images est de leur attribuer un identifiant. C'était qu'il n'y avait pas beaucoup de code nécessaire pour le faire fonctionner. Voici un exemple utilisant des requêtes multimédias et 3 feuilles de style. Un pour téléphone, un pour tablette et un pour ordinateur de bureau. J'ai 3 images, l'image d'un téléphone, d'une tablette et d'un ordinateur de bureau. Sur un écran de téléphone, seule une image du téléphone s'affiche, une tablette affiche uniquement l'image de la tablette, un bureau s'affiche sur l'image de l'ordinateur de bureau. Voici un exemple de code pour le faire fonctionner:

Code source:

<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>

Le CSS du téléphone qui n'a pas besoin d'une requête multimédia. C'est le téléphone img # qui le fait fonctionner:

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

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

La tablette CSS:

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

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

Et le css de bureau:

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

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

Bonne chance et faites-moi savoir comment cela fonctionne pour vous.

Duane
la source
4
La question n'est pas de savoir comment définir un display: nonesur une image. C'est: «Afficher: aucun» empêche le chargement d'une image?
Evgenia Manolova