Comment mettre en cache une image dans Javascript

Mes amis et moi-même travaillons sur un site web où nous aimerions nous cache certaines images afin de les afficher plus rapidement à l'avenir. J'ai deux questions principales:

  1. comment cache-t-on une image?
  2. comment utiliser une image Une fois qu'elle a été mise en cache? (et juste pour vérifier, si une image est mise en cache sur la page A, il est possible de l'appeler depuis le cache pour l'utiliser sur la page B, non?)

aussi, est-il possibilité de définir quand la version en cache de l'image expirera?

nous vous saurions gré de bien vouloir inclure un exemple et/ou un lien vers une page qui décrit plus en détail ce point.

nous pouvons utiliser du Javascript brut ou la version jQuery.

55
demandé sur Lix 2012-04-20 08:07:06

8 réponses

une fois qu'une image a été chargée d'une manière ou d'une autre dans le navigateur, elle sera dans la mémoire cache du navigateur et se chargera beaucoup plus rapidement la prochaine fois qu'elle sera utilisée, que cette utilisation soit dans la page courante ou dans toute autre page, à condition que l'image soit utilisée avant qu'elle n'expire dans la mémoire cache du navigateur.

donc, pour précacher les images, tout ce que vous avez à faire est de les charger dans le navigateur. Si vous voulez précacher un tas d'images, il est probablement préférable de le faire avec javascript car il ne sera généralement pas tenir jusqu'au chargement de la page lorsque vous avez terminé de javascript. Vous pouvez le faire comme ceci:

function preloadImages(array) {
    if (!preloadImages.list) {
        preloadImages.list = [];
    }
    var list = preloadImages.list;
    for (var i = 0; i < array.length; i++) {
        var img = new Image();
        img.onload = function() {
            var index = list.indexOf(this);
            if (index !== -1) {
                // remove image from the array once it's loaded
                // for memory consumption reasons
                list.splice(index, 1);
            }
        }
        list.push(img);
        img.src = array[i];
    }
}

preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"]);

cette fonction peut être appelée autant de fois que vous le voulez et à chaque fois, elle ajoutera simplement plus d'images au precache.

une fois que les images ont été préchargées comme ceci via javascript, le navigateur les aura dans sa cache et vous pouvez juste vous référer aux URLs normales dans d'autres endroits (dans vos pages web) et le navigateur récupérera cette URL de sa cache plutôt que sur le réseau.

éventuellement avec le temps, le cache du navigateur peut remplir et jeter les choses les plus anciennes qui n'ont pas été utilisées depuis un certain temps. Ainsi, éventuellement, les images seront sorties de la cache, mais elles devraient y rester pendant un certain temps (en fonction de la taille de la cache et de la quantité d'autres recherches effectuées). Chaque fois que les images sont effectivement préchargées à nouveau ou utilisés dans une page web, il rafraîchit leur position dans le cache du navigateur automatiquement afin qu'ils sont moins probablement chassées du cache.

le cache du navigateur est une page croisée donc il fonctionne pour n'importe quelle page chargée dans le navigateur. Vous pouvez donc précacher à un endroit de votre site et le cache du navigateur fonctionnera alors pour toutes les autres pages de votre site.


en précachant comme ci-dessus, les images sont chargées de manière asynchrone afin qu'elles ne bloquent pas le chargement ou l'affichage de votre page. Mais, si votre page a beaucoup d'images de ses propres, ces images de precache peuvent rivaliser pour la bande passante ou les connexions avec les images qui sont affichées dans votre page. Normalement, ce n'est pas un problème perceptible, mais sur une connexion lente, cette précaching pourrait ralentir le chargement de la page principale. Si c'était OK pour que les images préchargées soient chargées en dernier, alors vous pourriez utiliser une version de la fonction qui attendrait pour démarrer le préchargement jusqu'à ce que toutes les autres ressources de la page soient déjà chargées.

function preloadImages(array, waitForOtherResources, timeout) {
    var loaded = false, list = preloadImages.list, imgs = array.slice(0), t = timeout || 15*1000, timer;
    if (!preloadImages.list) {
        preloadImages.list = [];
    }
    if (!waitForOtherResources || document.readyState === 'complete') {
        loadNow();
    } else {
        window.addEventListener("load", function() {
            clearTimeout(timer);
            loadNow();
        });
        // in case window.addEventListener doesn't get called (sometimes some resource gets stuck)
        // then preload the images anyway after some timeout time
        timer = setTimeout(loadNow, t);
    }

    function loadNow() {
        if (!loaded) {
            loaded = true;
            for (var i = 0; i < imgs.length; i++) {
                var img = new Image();
                img.onload = img.onerror = img.onabort = function() {
                    var index = list.indexOf(this);
                    if (index !== -1) {
                        // remove image from the array once it's loaded
                        // for memory consumption reasons
                        list.splice(index, 1);
                    }
                }
                list.push(img);
                img.src = imgs[i];
            }
        }
    }
}

preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"], true);
preloadImages(["url99.jpg", "url98.jpg"], true);
101
répondu jfriend00 2015-07-30 23:41:34

comme @Pointy a dit que vous ne cachez pas les images avec javascript, le navigateur le fait. et c'est peut-être ce que vous demandez et ne peut pas être... mais vous pouvez précharger les images en utilisant javascript. En mettant toutes les images que vous voulez précharger dans un tableau et en mettant toutes les images dans ce tableau dans des éléments img cachés, vous Préchargez (ou mettez en cache) les images.

var images = [
'/path/to/image1.png',
'/path/to/image2.png'
];

$(images).each(function() {
var image = $('<img />').attr('src', this);
});
10
répondu Trav McKinney 2012-04-20 04:13:23

Il ya quelques choses que vous pouvez regarder:

pré-chargement de vos images

Définir une heure de cache dans un.fichier htaccess

Taille du fichier des images et Base64 les encodant.

préchargement: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

la mise en Cache: http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html

il y a quelques idées différentes pour l'encodage de base64, certains disent que le http demande de réduire la bande passante, tandis que d'autres disent que le chargement" perçu " est meilleur. Je vais laisser cela en l'air.

2
répondu Tim 2012-04-20 04:13:51

j'ai un similaires réponse pour asynchrones préchargement des images via JS. Charger dynamiquement est la même chose que de les charger normalement. ils seront cache.

quant à la mise en cache, vous ne pouvez pas contrôler le navigateur mais vous pouvez le configurer via le serveur. si vous avez besoin de charger une ressource vraiment fraîche sur demande, vous pouvez utiliser la technique de Buster de cache pour forcer la charge d'une ressource fraîche.

1
répondu Joseph 2017-05-23 12:26:24

même si votre question dit" utiliser javascript", vous pouvez utiliser l'attribut prefetch d'une étiquette de lien pour précharger n'importe quel bien. En date de cette écriture (10 août 2016) il n'est pas pris en charge en Safari, mais est à peu près partout ailleurs:

<link rel="prefetch" href="(url)">

plus d'informations sur le support ici: http://caniuse.com/#search=prefetch

notez que IE 9,10 ne sont pas listés dans la matrice caniuse parce que Microsoft a cessé de les prendre en charge.

donc si vous étiez vraiment bloqué sur l'utilisation de javascript, vous pourriez utiliser jquery pour ajouter dynamiquement ces éléments à votre page aussi bien; -)

1
répondu Brad Parks 2016-08-10 12:39:36

j'utilise une technique similaire pour télécharger des images, mais je ne peux m'empêcher de remarquer que Javascript n'accède pas au cache du navigateur lors du premier chargement.

mon exemple:

j'ai une bannière tournante sur ma page d'accueil avec 4 images le curseur attendre 2 secondes, que le javascript charge l'image suivante, attend 2 secondes, etc.

ces images ont des urls uniques qui changent à chaque fois que je les modifie, donc ils obtiennent des en-têtes de cache qui vont cache dans le navigateur pendant un an.

max-age: 31536000, public

maintenant quand J'ouvre Chrome Devtools et que je m'assure que l'option de 'Disable cache' n'est pas active et charge la page pour la première fois (après avoir nettoyé le cache) toutes les images obtiennent fetch et ont un statut 200. Après un cycle complet de toutes les images dans la bannière le réseau demande l'arrêt et les images mises en cache sont utilisées.

maintenant quand je fais un rafraîchissement régulier ou aller à une sous-page et cliquez en arrière, les images qui sont dans le cache semble être ignoré. Je m'attendrais à voir un message gris "de cache disque" dans L'onglet Réseau de Chrome devtools. Au lieu de cela, je vois les requêtes passer toutes les deux secondes avec un cercle de statut vert au lieu de gris, je vois des données être transférées, donc j'ai l'impression que le cache n'est pas accédé du tout à partir de javascript. Il récupère simplement l'image chaque fois que la page est chargée.

ainsi chaque requête vers la page d'accueil déclenche 4 requêtes indépendamment de la mise en cache politique de l'image.

compte tenu de l'ensemble de ce qui précède et de la nouvelle norme http2 que la plupart des serveurs web et des navigateurs supportent maintenant, je pense qu'il est préférable d'arrêter d'utiliser lazyloading puisque http2 chargera toutes les images presque simultanément.

si C'est un bug dans Chrome Devtools, ça surprend vraiment que personne ne l'ait remarqué. ;)

Si ceci est vrai, utiliser lazyloading augmente seulement la bande d'utilisation.

Merci de corriger moi si je me trompe. :)

1
répondu Jean-Paul Ladage 2017-03-07 17:04:08

Oui, le navigateur cache les images pour vous, automatiquement.

vous pouvez, cependant, définir un cache d'image à expirer. Découvrez ce Débordement de Pile de questions et de réponses:

Expiration De La Mémoire Cache Sur Les Images Statiques

0
répondu magzalez 2017-05-23 11:47:20

je préfère toujours utiliser l'exemple mentionné dans Konva JS: image Events pour charger des images.

  1. vous devez avoir une liste d'URLs d'image comme objet ou tableau, par exemple:

    var sources = { lion: '/assets/lion.png', monkey: '/assets/monkey.png' };

  2. définit la définition de la fonction, où il reçoit la liste des URLs de l'image et une fonction de rappel dans sa liste d'arguments, ainsi quand il termine le chargement de l'image vous peut commencer l'édition sur votre page web:

    function loadImages(sources, callback) {
                var images = {};
                var loadedImages = 0;
                var numImages = 0;
                for (var src in sources) {
                    numImages++;
                }
                for (var src in sources) {
                    images[src] = new Image();
                    images[src].onload = function () {
                        if (++loadedImages >= numImages) {
                            callback(images);
                        }
                    };
                    images[src].src = sources[src];
                }
            }
  1. Enfin, vous devez appeler la fonction. Vous pouvez l'appeler par exemple de jQuery 's "1519260920 Document" Prêt

$(document).ready(function (){ loadImages(sources, buildStage); });

0
répondu Mahdi Alkhatib 2017-08-28 07:56:17