2012-04-20 17 views
48

I miei amici e io stiamo lavorando su un sito Web in cui vorremmo memorizzare alcune immagini per poterle visualizzare più velocemente in futuro. Ho due domande principali:Come memorizzare un'immagine in Javascript

  1. Come si memorizza un'immagine?
  2. Come si utilizza un'immagine una volta che è stata memorizzata nella cache? (E solo per verificare, se un'immagine è memorizzato nella cache a pagina A, è possibile chiamare dalla cache di usarlo a pagina B, giusto?)

Inoltre, è possibile impostare quando la versione cache dell'immagine scadrà?

Sarebbe molto apprezzato se fosse incluso un esempio e/o un collegamento a una pagina che descrive questo ulteriormente.

Siamo a posto con Javascript non elaborato o con la versione jQuery.

+10

Non lo sai. Il browser fa. – Pointy

+0

il browser memorizza automaticamente le immagini nella cache? –

+6

@Logan: Sì, il browser memorizza automaticamente le immagini nella cache, a condizione che il server invii le intestazioni necessarie per comunicare al browser che è sicuro salvarlo nella cache. (Queste intestazioni possono anche indicare al browser la data di scadenza, che è parte della tua domanda.) – icktoofay

risposta

92

Una volta che l'immagine è stata caricata in qualche modo nel browser, sarà nella cache del browser e verrà caricata molto più velocemente la prossima volta che verrà usata, sia che l'uso sia nella pagina corrente o in qualsiasi altra pagina finchè come l'immagine viene utilizzata prima che scada dalla cache del browser.

Quindi, per precache immagini, tutto ciò che dovete fare è caricarle nel browser. Se vuoi precache un mucchio di immagini, probabilmente è meglio farlo con javascript in quanto in genere non regge il caricamento della pagina quando viene eseguito da javascript. Potete farlo in questo modo:

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"]); 

Questa funzione può essere richiamata tutte le volte che si desidera e di volta in volta, sarà solo aggiungere altre immagini alla precache.

Una volta che le immagini sono state precaricate in questo modo tramite javascript, il browser le avrà nella sua cache e puoi semplicemente fare riferimento ai normali URL in altri luoghi (nelle tue pagine web) e il browser recupererà quell'URL dalla sua cache piuttosto che attraverso la rete.

Eventualmente nel tempo, la cache del browser potrebbe riempirsi e sballare le cose più vecchie che non sono state utilizzate da un po '. Quindi, alla fine, le immagini saranno scaricate dalla cache, ma dovrebbero rimanere lì per un po '(a seconda di quanto è grande la cache e quanta altra navigazione è fatta). Ogni volta che le immagini vengono effettivamente caricate di nuovo o utilizzate in una pagina Web, aggiornano automaticamente la loro posizione nella cache del browser in modo che sia meno probabile che vengano svuotate dalla cache.

La cache del browser è cross-page quindi funziona per qualsiasi pagina caricata nel browser. Quindi puoi precache in un posto nel tuo sito e la cache del browser funzionerà per tutte le altre pagine del tuo sito.


quando si precarica come sopra, le immagini vengono caricate in modo asincrono in modo da non bloccare il caricamento o la visualizzazione della pagina. Tuttavia, se la tua pagina ha molte immagini proprie, queste immagini precache possono competere per larghezza di banda o connessioni con le immagini visualizzate nella tua pagina. Normalmente, questo non è un problema evidente, ma su una connessione lenta, questo precaching potrebbe rallentare il caricamento della pagina principale. Se era OK per caricare le immagini di precarico per ultimo, è possibile utilizzare una versione della funzione che aspetterebbe di avviare il preloading fino a quando tutte le altre risorse di pagina non fossero già state caricate.

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); 
+0

In questo esempio si sta creando un nuovo oggetto Immagine per ogni URL. Se imposti la variabile img al di fuori del ciclo e aggiorni semplicemente lo src, dovrebbe avere lo stesso effetto e ridurre le risorse – cadlac

+0

@cadlac - Ma per essere certi che il browser possa effettivamente scaricare e memorizzare nella cache ogni immagine, dovresti attendi fino al termine del download di un'immagine prima di impostare una nuova proprietà .src. In caso contrario, il browser potrebbe semplicemente interrompere il download precedente e non memorizzarlo mai correttamente. – jfriend00

+0

Sembra funzionare sulle versioni più recenti dei browser senza attendere, ma è un buon punto. Dovrò provarlo su alcuni vecchi browser per vedere la sua compatibilità :) – cadlac

10

come @Pointy ha detto che non si memorizzano nella cache le immagini con javascript, il browser lo fa. quindi questo potrebbe essere quello che stai chiedendo e potrebbe non essere ... ma puoi precaricare le immagini usando javascript. Inserendo tutte le immagini che si desidera precaricare in un array e inserendo tutte le immagini di quell'array in elementi img nascosti, si pre-caricano (o memorizzano in cache) effettivamente le immagini.

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

$(images).each(function() { 
var image = $('<img />').attr('src', this); 
}); 
+2

sarebbe possibile precaricare un'immagine su una pagina (senza visualizzarla), quindi visualizzarla nella pagina successiva? –

+1

a mia conoscenza se si precarica un'immagine su una pagina verrà inserito nella cache del browser e quindi verrà visualizzato più rapidamente su qualsiasi altra pagina. se questo è sbagliato, qualcuno mi corregga per favore. –

2

ci sono alcune cose che si possono guardare:

precarico le immagini
impostando un tempo di cache in un file .htaccess
dimensioni file di immagini e Base64 li codificano.

precarico: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

Caching: http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html

Ci sono un paio di pensieri diversi per la codifica Base64, alcuni dicono che le richieste HTTP impantanarsi larghezza di banda, mentre altri dicono che il "percepito" di carico è meglio. Lascerò questo in aria.

0

Sì, il browser memorizza automaticamente le immagini nella cache.

È possibile, tuttavia, impostare la scadenza della cache dell'immagine. Dai un'occhiata a questo domande overflow dello stack e rispondere:

Cache Expiration On Static Images

1

Ho un similar answer per il precaricamento asincrono immagini tramite JS. Caricarli dinamicamente è come caricarli normalmente. loro cache.

come per la memorizzazione nella cache, non è possibile controllare il browser ma è possibile impostarlo tramite server. se è necessario caricare una risorsa veramente fresca su richiesta, è possibile utilizzare cache buster technique per forzare il caricamento di una nuova risorsa.

1

Anche se la tua domanda dice "utilizzando JavaScript", è possibile utilizzare l'attributo prefetch di un tag link per precaricare qualsiasi attività. Momento in cui scriviamo (10 agosto 2016) non è supportato in Safari, ma è praticamente ovunque:

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

Maggiori informazioni sul supporto qui: http://caniuse.com/#search=prefetch

Nota che IE 9 , 10 non sono elencati nella matrice caniuse perché Microsoft ha interrotto il supporto per loro.

Quindi, se si fosse veramente bloccato su utilizzando JavaScript, è possibile utilizzare jQuery per aggiungere dinamicamente questi elementi alla tua pagina pure ;-)

+0

Bello bello bello bello! –

1

Io uso una tecnica simile a LazyLoad le immagini, ma non può fare a meno si noti che Javascript non accede alla cache del browser al primo caricamento.

Il mio esempio:

ho un banner a rotazione nella mia home page con 4 immagini del cursore attendere 2 secondi, che il javascript carica l'immagine successiva, attende 2 secondi, ecc

Queste immagini hanno URL unici che cambiano ogni volta che li modifico, quindi ottengono le intestazioni di cache che si memorizzeranno nel browser per un anno.

max-age: 31536000, public 

Ora quando ho aperto Chrome Devtools e assicurarsi de 'opzione 'Disabilita cache' non è attivo e caricare la pagina per la prima volta (dopo svuotare la cache) tutte le immagini ottenere prendere e hanno uno status 200. Dopo un ciclo completo di tutte le immagini nel banner, le richieste di rete vengono interrotte e vengono utilizzate le immagini memorizzate nella cache.

Ora quando eseguo un aggiornamento regolare o andare a una sottopagina e fare clic su Indietro, le immagini che si trovano nella cache sembrano essere ignorate. Mi aspetto di vedere un messaggio grigio "dalla cache del disco" nella scheda Rete di Chrome devtools. Invece vedo che le richieste passano ogni due secondi con un cerchio di stato verde anziché grigio, vedo i dati che vengono trasferiti, quindi ho l'impressione che la cache non sia affatto visitata da javascript. Semplicemente recupera l'immagine ogni volta che la pagina viene caricata.

Quindi ogni richiesta sulla home page attiva 4 richieste indipendentemente dalla politica di memorizzazione nella cache dell'immagine.

Considerando quanto sopra e il nuovo standard http2 ora supportano la maggior parte dei server e dei browser Web, penso sia meglio smettere di usare lazyloading poiché http2 caricherà tutte le immagini quasi simultaneamente.

Se si tratta di un bug in Chrome Devtools, sorprende davvero che nessuno lo abbia ancora notato. ;)

Se ciò è vero, l'uso di lazyloading aumenta solo l'utilizzo della larghezza di banda.

Per favore correggimi se sbaglio. :)

0

Preferisco sempre utilizzare l'esempio indicato in Konva JS: Image Events per caricare le immagini.

  1. È necessario disporre di un elenco di URL di immagine come oggetto o un array, per esempio:

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

  2. Definire la definizione della funzione, dove riceve la lista di URL di immagine e di una funzione di callback nella sua lista di argomenti, in modo che quando si finisce di caricare un'immagine è possibile avviare excution sulla tua pagina 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. Infine, è necessario chiamare la funzione. Si può chiamare per esempio da jQuery s' Documento pronto

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

Problemi correlati