web-dev-qa-db-fra.com

"Display: none" empêche-t-il le chargement d'une image?

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

317
nasty

Ces images sont chargées. Le navigateur, en raison de la possibilité qu'un script vérifie dynamiquement un élément du DOM, n'optimise pas les éléments (ou le contenu des éléments).

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

L'image a un style display:none mais sa taille est lue par le script. Vous pourriez également l'avoir vérifiée en consultant l'onglet "Réseau" des outils de développement de votre navigateur.

Notez que si le navigateur est sur un petit ordinateur doté d'un processeur, le fait de ne pas rendre l'image (ni la mise en page) rendra l'ensemble de l'opération de rendu plus rapide, mais je doute que cela ait vraiment du sens 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'attribut IMG src sur "data:" ou "about:blank".).

EDIT:

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 ce n'est pas utile.

180
Denys Séguret

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

122
Brent

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:

  • Sous Chrome: Tous les 8 screenshot- * images chargées (img 1)
  • Sous Firefox: seule la 1 capture d'écran- * image chargée en cours d'affichage (img 2)

Donc, après avoir approfondi mes recherches, j’ai trouvé this , ce qui explique comment chaque navigateur gère le chargement d’img assets en fonction de l’affichage css: none;

Extrait de l'article 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 image d'arrière-plan si les styles sont masqués, mais téléchargera toujours les fichiers à partir de balises img.
  • Opéra:
    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: aucune; 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 téléchargé ... Mais ils le seront si ces styles ne sont pas appliqués en ligne.

Chrome- All 8 screenshot-* images loaded

Firefox- Only the 1 screenshot-* image loaded that is currently being displayed

55
DMTintner

La balise HTML5 <picture> vous aidera à résoudre la source d'image appropriée 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 encore les images cachées, même si une propriété display: none leur était affectée.

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

Alors que je pensais qu’il n’ya qu’une solution JS au problème ( charge lente , remplissage , etc.), il est apparu qu’il existait une solution Nice pure HTML issue de la boîte avec HTML5.

Et c'est la balise <picture>.

Voici comment MDN le décrit:

L'élément HTML <picture> est un conteneur utilisé pour spécifier plusieurs éléments <source> pour un <img> spécifique contenu dans celui-ci. . Le navigateur choisira la source la mieux adaptée en fonction de la présentation actuelle de la page (les contraintes de la boîte dans laquelle l'image apparaîtra) et du périphérique sur lequel elle sera affichée (par exemple, un périphérique 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 balise img uniquement si aucune des règles de média ne s'applique. Lorsque l'élément <picture> n'est pas pris en charge par le navigateur, il revient à nouveau à l'affichage de la balise img.

Normalement, vous utiliseriez la plus petite image comme source du <img> sans charger les images lourdes pour les écrans plus grands. Inversement, si une règle de média s'applique, la source du <img> ne sera pas téléchargée. Elle téléchargera le contenu de l'URL du tag <source> correspondant.

Le seul inconvénient 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 devrions penser et coder selon l'approche mobile first.

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

Navigateurs de bureau

Desktop browsers support

Navigateurs mobiles

Mobile browsers support

Vous trouverez plus d'informations sur le support du navigateur sur Puis-je utiliser .

La bonne chose est que la phrase de html5please est: tilisez-la avec un repli. Et j'ai personnellement l'intention de prendre leurs conseils.

Vous trouverez plus d'informations sur le tag dans le spécification du W3C . Il y a une clause de non-responsabilité que je trouve importante de mentionner:

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

Donc, cela dit que cela ne fait que vous aider à améliorer les performances lors du chargement d'une image, en lui fournissant un contexte.

Et vous pouvez toujours utiliser un peu de 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’affiche pas l’image réelle et ne télécharge que l’image 1x1 pixel (qui peut être mise en cache si vous l’utilisez plus d’une fois). Sachez cependant que si la balise <picture> n'est pas supportée par le navigateur, même sur les écrans de descktop, l'image réelle ne sera pas affichée (vous aurez donc certainement besoin d'une sauvegarde polyfill Là).

27
Evgenia Manolova

Oui, le rendu sera plus rapide, légèrement, uniquement parce qu'il ne nécessite pas le rendu de l'image et constitue un élément de moins à trier à l'écran.

Si vous ne voulez pas le charger, laissez un DIV vide où vous pourrez charger du code HTML contenant plus tard une balise <img>.

Essayez d’utiliser Firebug ou Warshark comme je l’ai déjà mentionné et vous verrez que les fichiers sont transférés, même si display:none est présent.

Opera est le seul navigateur qui ne chargera pas l'image si l'affichage est défini sur none. Opera a été déplacé vers Webkit et restituera toutes les images même si leur affichage est défini sur Aucune.

Voici une page de test qui le prouvera:

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

9
Dorian

L'image d'arrière-plan d'un élément div va charger si la div est définie, faites '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 d'utilisation de 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>
8
ninja_corp

Mode Quirks: images et affichage: aucun

Lorsque l'image a display: none ou est 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.

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

8
onlyurei

Si c'est le cas, y a-t-il un moyen de ne pas charger le contenu inutile sur les navigateurs mobiles?

utiliser <img src="" srcset="">

http://www.webdesignerdepot.com/2015/08/the-state-of-responsive-images/

https://caniuse.com/#feat=srcset

6
commonpike

Si vous faites de l'image l'image d'arrière-plan d'une div en CSS, lorsque cette div est définie sur "display: none", l'image ne se chargera pas.

Développons juste la solution de Brent.

Vous pouvez effectuer les opérations suivantes pour une solution CSS pure, cela fait également en sorte que la boîte img se comporte comme une boîte img dans un paramètre de conception réactif (c’est le rôle du fichier 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 de média liée à visible-lg-block est déclenchée et que display: none est modifié pour afficher: block. Le format png transparent permet au navigateur de définir les 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)

Donc, vous vous retrouvez 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 de taille par défaut de votre fenêtre média se chargent pendant le chargement initial, puis, en fonction de votre fenêtre d'affichage, les images se chargent dynamiquement.

Et pas de javascript!

4
ats

** 2019 réponse **

En situation normale, display:none n'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:none alors 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

4
Juanma Menendez

Pour empêcher l'extraction de ressources, utilisez l'élément <template> des composants Web .

3
ma11hew28

Non. L’image sera chargée comme d’habitude et utilisera toujours la bande passante de l’utilisateur si vous envisagez d’économiser de la bande passante pour le téléphone mobile. Vous pouvez utiliser une requête multimédia et filtrer les périphériques sur lesquels vous souhaitez charger l'image doit être définie en tant qu'image d'arrière-plan d'une div, etc. et NON d'une balise, car la balise image chargera l'image, que la taille de l'écran et la requête de support soient définies.

2
IsuNas Labs

Utilisez @media query CSS, nous publions simplement un projet dans lequel nous avions une énorme image d’un arbre sur le bureau, mais ne s’affichant pas dans les écrans de table/mobiles. Donc, empêcher l'image de charger c'est assez facile

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 code CSS pour afficher et masquer avec affichage/visibilité/opacité, mais le chargement de l’image continuait, c’était le code le plus sûr que nous ayons créé.

1
Joakim Ling

Une autre possibilité consiste à utiliser une balise <noscript> et à placer l'image à l'intérieur de la balise <noscript>. Ensuite, utilisez javascript pour supprimer la balise noscript car vous avez besoin de l'image. De cette manière, 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 balises <noscript> dans IE8

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

1
James Westgate

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

Mais j'ai trouvé une bonne solution. Commencez par créer une balise img puis chargez un svg vide dans l'attribut src. Vous pouvez maintenant définir votre URL pour l'image comme un style en ligne avec un contenu: url ("lien vers votre image") ;. Emballez maintenant votre tag img dans l’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 le wrapper pour qu’il n’en affiche aucun sur le point d’arrêt où vous ne voulez pas charger l’image. Le css en ligne de la balise img est maintenant ignoré car le style d'un élément enveloppé dans un wrapper avec display no sera ignoré. Par conséquent, 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à, un moyen très facile de ne pas charger un img sur un point d'arrêt mobile :)

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

1
Mikkel Fennefoss

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

ne cherchez-vous pas alors l'image au-dessus d'une certaine largeur d'écran?

0
Superfly5000