web-dev-qa-db-fra.com

Préchargement des images CSS

J'ai un formulaire de contact caché qui est déployé en cliquant sur un bouton. Ses champs sont définis en tant qu'images d'arrière-plan CSS et ils apparaissent toujours un peu plus tard que la div qui a été basculée.

J'utilisais cet extrait dans le <head> section, mais sans succès (après avoir vidé la mémoire cache):

<script>
$(document).ready(function() {
        pic = new Image();
        pic2 = new Image();
        pic3 = new Image();
        pic.src="<?php bloginfo('template_directory'); ?>/images/inputs/input1.png";
        pic2.src="<?php bloginfo('template_directory'); ?>/images/inputs/input2.png";
        pic3.src="<?php bloginfo('template_directory'); ?>/images/inputs/input3.png";
});
</script>

J'utilise jQuery comme bibliothèque et ce serait bien si je pouvais l'utiliser également pour arranger ce problème.

Merci pour vos pensées.

103
Peanuts

Je peux confirmer que mon code d'origine semble fonctionner. Je collais avec désinvolture à une image avec un mauvais chemin.

Voici un test: http://paragraphe.org/slidetoggletest/test.html

<script>
    var pic = new Image();
    var pic2 = new Image();
    var pic3 = new Image();
    pic.src="images/inputs/input1.png";
    pic2.src="images/inputs/input2.png";
    pic3.src="images/inputs/input3.png";
</script>
26
Peanuts

Préchargement d'images à l'aide de CSS uniquement

Dans le code ci-dessous, je choisis de manière aléatoire l'élément body, car c'est l'un des seuls éléments garantis pour exister sur la page.

Pour que "l'astuce" fonctionne, nous allons utiliser la propriété content qui permet de configurer facilement plusieurs URL , mais comme indiqué , le ::after Le pseudo-élément est conservé masqué afin que les images ne soient pas restituées:

body::after{
   position:absolute; width:0; height:0; overflow:hidden; z-index:-1; // hide images
   content:url(img1.png) url(img2.png) url(img3.gif) url(img4.jpg);   // load images
}

démo


il est préférable d'utiliser un image Sprite pour réduire le nombre de requêtes http ... (s'il y a beaucoup d'images de taille relativement petite) et vous assurer que les images sont hébergées là où HTTP2 est utilisé.

229
vsync

http://css-tricks.com/snippets/css/css-only-image-preloading/

Technique n ° 1

Chargez l'image dans l'état normal de l'élément, déplacez-la uniquement avec la position de l'arrière-plan. Puis déplacez la position de fond pour l'afficher en vol stationnaire.

#grass { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background-position: bottom left; }

Technique n ° 2

Si l'élément en question a déjà une image d'arrière-plan appliquée et que vous devez changer cette image, ce qui précède ne fonctionnera pas. En règle générale, vous choisiriez ici un Sprite (une image d’arrière-plan combinée) et il vous suffirait de déplacer la position de l’arrière-plan. Mais si cela n'est pas possible, essayez ceci. Appliquez l'image d'arrière-plan à un autre élément de page déjà utilisé mais pour lequel il n'y a pas d'image d'arrière-plan.

#random-unsuspecting-element { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background: url(images/grass.png) no-repeat; }
13
Fatih Hayrioğlu

Préchargement d'images à l'aide d'une balise HTML <link>

Je pense que la plupart des visiteurs de cette question cherchent la réponse de "Comment puis-je précharger une image avant le début du rendu de la page?" et la meilleure solution à ce problème consiste à utiliser <link> Parce que <link> Est capable de bloquer le rendu ultérieur de la page. Voir préemptif

Ces deux options de valeur de l'attribut rel ( relation entre le document actuel et le document lié) sont les plus pertinentes pour le problème:

  • prefetch : charge la ressource donnée lors du rendu de la page
  • préchargement : charge la ressource donnée avant le début du rendu de la page

Donc, si vous voulez charger une ressource ( dans ce cas, c'est une image) avant le début du processus de rendu de la balise <body>, Utilisez:

<link rel="preload" as="image" href="IMAGE_URL">

et si vous voulez charger une ressource alors que <body> est en cours de rendu mais que vous envisagez de l'utiliser ultérieurement de manière dynamique et que vous ne voulez pas déranger l'utilisateur avec le temps de chargement, utilisez:

<link rel="prefetch" href="RESOURCE_URL">
12
mertyildiran

essayez avec ceci:

var c=new Image("Path to the background image");
c.onload=function(){
   //render the form
}

Avec ce code, vous préchargez l'image d'arrière-plan et rendez le formulaire lorsqu'il est chargé.

9
mck89

Si vous réutilisez ces images bg ailleurs sur votre site pour la saisie de formulaires, vous souhaiterez probablement utiliser un Sprite image. De cette façon, vous pouvez gérer vos images de manière centralisée (au lieu d’avoir pic1, pic2, pic3, etc ...).

Les sprites sont généralement plus rapides pour le client, car ils ne demandent qu’un seul fichier (bien que légèrement plus grand) au serveur au lieu de plusieurs fichiers. Voir l'article SO article pour plus d'avantages:

sprites d'image CSS

Là encore, cela pourrait ne pas être utile du tout si vous utilisez seulement ceux-ci pour un formulaire et que vous voulez vraiment les charger uniquement si l'utilisateur demande le formulaire de contact ... peut-être logique cependant.

http://www.alistapart.com/articles/sprites

5
ajhit406

Pour le préchargement des images d’arrière-plan définies avec CSS, la réponse la plus efficace que j’ai trouvée était une version modifiée de certains codes que je trouvais qui ne fonctionnait pas:

$(':hidden').each(function() {
  var backgroundImage = $(this).css("background-image");
  if (backgroundImage != 'none') {
    tempImage = new Image();
    tempImage.src = backgroundImage;
  }
});

L'avantage énorme de ceci est que vous n'avez pas besoin de le mettre à jour lorsque vous importez de nouvelles images d'arrière-plan à l'avenir, il va rechercher les nouvelles et les précharger!

5
Deminetix

Vous pouvez utiliser ce plugin jQuery waitForImage ou vous pouvez placer vos images dans un div caché ((width: 0 et height: 0) et utiliser l’événement onload sur les images.

Si vous ne disposez que de 2 ou 3 images, vous pouvez lier des événements et les déclencher de manière à pouvoir créer du code après chaque image.

1
user1236048

que diriez-vous de charger cette image de fond quelque part cachée. Ainsi, il sera chargé à l'ouverture de la page et ne prendra plus de temps une fois le formulaire créé avec ajax:

body {
background: #ffffff url('img_tree.png') no-repeat -100px -100px;
}
1
Santi

Lorsqu'il n'y a aucun moyen de modifier le code CSS et de précharger des images avec des règles CSS pour :before ou :after pseudo-éléments Une autre approche avec du code JavaScript traversant les règles CSS des feuilles de style chargées peut être utilisée. Afin de le rendre fonctionnel les scripts doivent être inclus après les feuilles de style en HTML, par exemple, avant de fermer la balise body ou juste après les feuilles de style.

getUrls() {
    const urlRegExp = /url\(('|")?([^'"()]+)('|")\)?/;

    let urls = [];
    for (let i = 0; i < document.styleSheets.length; i++) {
        let cssRules = document.styleSheets[i].cssRules;
        for (let j = 0; j < cssRules.length; j++) {
            let cssRule = cssRules[j];
            if (!cssRule.selectorText) {
                continue;
            }

            for (let k = 0; k < cssRule.style.length; k++) {
                let property = cssRule.style[k],
                    urlMatch = cssRule.style[property].match(urlRegExp);
                if (urlMatch !== null) {
                    urls.Push(urlMatch[2]);
                }
            }
        }
    }
    return urls;
}

preloadImages() {
    return new Promise(resolve => {
        let urls = getUrls(),
            loadedCount = 0;

        const onImageLoad = () => {
            loadedCount++;
            if (urls.length === loadedCount) {
                resolve();
            }
        };

        for (var i = 0; i < urls.length; i++) {
            let image = new Image();
            image.src = urls[i];
            image.onload = onImageLoad;
        }
    });
}

document.addEventListener('DOMContentLoaded', () => {
    preloadImages().then(() => {
        // CSS images are loaded here
    });
});
1
Ezze

Le seul moyen est d’encoder l’image en Base64 et de la placer dans le code HTML afin qu’elle n’ait pas besoin de contacter le serveur pour télécharger l’image.

This va encoder une image à partir de l'URL afin que vous puissiez copier le code du fichier image et l'insérer dans votre page, comme suit ...

body {
  background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...);
}
1
mheager

Si les éléments de page et leurs images d’arrière-plan sont déjà dans le DOM (c’est-à-dire que vous ne les créez pas/ne les modifiez pas dynamiquement), leurs images d’arrière-plan seront déjà chargées. À ce stade, vous voudrez peut-être examiner les méthodes de compression :)

0
c_harm