wake-up-neo.com

Wie können Sie ein Bild in Javascript zwischenspeichern?

Meine Freunde und ich arbeiten an einer Website, auf der wir bestimmte Bilder zwischenspeichern möchten, um sie in Zukunft schneller anzeigen zu können. Ich habe zwei Hauptfragen:

  1. Wie zwischenspeichern Sie ein Bild?
  2. Wie verwenden Sie ein Bild, nachdem es zwischengespeichert wurde? (Und nur um zu überprüfen, ob ein Bild auf Seite A zwischengespeichert ist, kann es aus dem Cache aufgerufen werden, um es auf Seite B zu verwenden, oder?)

Kann auch eingestellt werden, wenn die zwischengespeicherte Version des Bildes abläuft?

Es würde uns sehr freuen, wenn ein Beispiel und/oder ein Link zu einer Seite enthalten würde, die dies weiter beschreibt.

Wir können entweder mit rohem Javascript oder mit der jQuery-Version umgehen.

60
Logan Besecker

Sobald ein Bild auf irgendeine Weise in den Browser geladen wurde, befindet es sich im Browser-Cache und wird bei der nächsten Verwendung wesentlich schneller geladen, unabhängig davon, ob es sich auf der aktuellen Seite oder auf einer anderen Seite befindet, sofern das Bild vorhanden ist verwendet, bevor es vom Browser-Cache abläuft.

Um Bilder vorzubereiten, müssen Sie sie nur in den Browser laden. Wenn Sie eine Reihe von Bildern vorbearbeiten möchten, ist es wahrscheinlich am besten, dies mit Javascript zu tun, da es in der Regel nicht das Laden der Seite mit Javascript unterstützt. Das kannst du so machen:

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

Diese Funktion kann so oft aufgerufen werden, wie Sie möchten, und jedes Mal werden dem Precache weitere Bilder hinzugefügt.

Sobald Bilder auf diese Weise über Javascript vorab geladen wurden, werden sie vom Browser im Cache abgelegt, und Sie können einfach auf die normalen URLs an anderen Stellen (auf Ihren Webseiten) verweisen, und der Browser holt diese URL aus dem Cache statt über die Netzwerk.

Im Laufe der Zeit kann der Browser-Cache die ältesten Dinge füllen, die seit einiger Zeit nicht mehr verwendet wurden. Irgendwann werden die Bilder dann aus dem Cache gelöscht, sie sollten jedoch eine Weile dort bleiben (abhängig davon, wie groß der Cache ist und wie viel anderer Browser durchsucht wird). Jedes Mal, wenn die Bilder tatsächlich erneut geladen oder in einer Webseite verwendet werden, wird ihre Position im Browser-Cache automatisch aktualisiert, sodass die Wahrscheinlichkeit geringer ist, dass sie aus dem Cache gelöscht werden.

Der Browser-Cache ist seitenübergreifend und funktioniert für jede im Browser geladene Seite. Sie können also an einer Stelle auf Ihrer Website einen Precache-Befehl ausführen, und der Browser-Cache funktioniert dann für alle anderen Seiten Ihrer Website.


Wenn Sie wie oben beschrieben vorab cachen, werden die Bilder asynchron geladen, sodass das Laden oder die Anzeige Ihrer Seite nicht blockiert wird. Wenn Ihre Seite über viele eigene Bilder verfügt, können diese Precache-Images um die Bandbreite oder Verbindungen mit den auf Ihrer Seite angezeigten Bildern konkurrieren. Normalerweise ist dies kein auffälliges Problem, aber bei einer langsamen Verbindung kann diese Vorverarbeitung das Laden der Hauptseite verlangsamen. Wenn das Laden der Images vor dem letzten Laden in Ordnung war, können Sie eine Version der Funktion verwenden, die mit dem Starten des Vorladevorgangs wartet, bis alle anderen Seitenressourcen bereits geladen sind.

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);
108
jfriend00

da @Pointy sagte, dass Sie keine Bilder mit Javascript zwischenspeichern, tut dies der Browser. Dies ist möglicherweise das, wonach Sie fragen und möglicherweise nicht ... aber Sie können Bilder mit Javascript vorladen. Wenn Sie alle Bilder, die Sie vorab laden möchten, in ein Array einlegen und alle Bilder in diesem Array in ausgeblendete img-Elemente einfügen, können Sie die Bilder effektiv vorladen (oder im Cache speichern).

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

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

Es gibt einige Dinge, die Sie sich ansehen können:

Laden Sie Ihre Bilder vor
Festlegen einer Cache-Zeit in einer .htaccess-Datei
Dateigröße der Bilder und Base64-Kodierung. 

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

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

Für die base64-Codierung gibt es ein paar verschiedene Gedanken, einige sagen, dass die http-Anforderungen die Bandbreite nachlassen, während andere sagen, dass das "wahrgenommene" Laden besser ist. Ich werde das in der Luft lassen.

2
Tim

Obwohl Ihre Frage "mit Javascript" lautet, können Sie das prefetch -Attribut eines Link-Tags verwenden, um ein beliebiges Asset vorab zu laden. Zum jetzigen Zeitpunkt (10. August 2016) wird es in Safari nicht unterstützt, ist aber fast überall zu finden:

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

Weitere Informationen zum Support finden Sie hier: http://caniuse.com/#search=prefetch

Beachten Sie, dass IE 9,10 nicht in der Matrix caniuse aufgeführt ist, da Microsoft die Unterstützung für sie eingestellt hat.

Wenn Sie sich also wirklich für die Verwendung von Javascript entschieden haben, können Sie jquery verwenden, um diese Elemente auch dynamisch zu Ihrer Seite hinzuzufügen ;-)

1
Brad Parks

Ich verwende eine ähnliche Technik, um Bilder zu laden, kann aber nicht anders als feststellen, dass Javascript beim ersten Laden nicht auf den Browser-Cache zugreift.

Mein Beispiel:

Ich habe auf meiner Homepage ein rotierendes Banner mit 4 Bildern. Der Schieberegler wartet 2 Sekunden, dann lädt das Javascript das nächste Bild, wartet 2 Sekunden usw.

Diese Bilder haben eindeutige URLs, die sich bei jeder Änderung ändern, sodass sie Caching-Header erhalten, die ein Jahr im Browser gecacht werden.

max-age: 31536000, public

Wenn ich nun Chrome Devtools öffne und die Option "Cache deaktivieren" nicht aktiv ist und die Seite zum ersten Mal lädt (nachdem der Cache geleert wurde), werden alle Bilder abgerufen und haben den Status 200. Nach einem vollständigen Zyklus aller Bilder im Banner werden die Netzwerkanforderungen angehalten und die zwischengespeicherten Bilder werden verwendet. 

Wenn ich jetzt eine regelmäßige Aktualisierung durchführe oder auf eine Unterseite gehe und auf "Zurück" klicke, werden die Bilder, die sich im Cache befinden, ignoriert. Ich würde erwarten, dass eine graue Meldung "from disk cache" auf der Registerkarte "Netzwerk" von Chrome devtools angezeigt wird. Stattdessen sehe ich, dass die Anforderungen alle zwei Sekunden mit einem grünen Statuskreis anstelle von grau vergehen, ich sehe, dass Daten übertragen werden, so dass ich den Eindruck bekomme, dass der Cache nicht von Javascript aus aufgerufen wird. Das Bild wird einfach jedes Mal abgerufen, wenn die Seite geladen wird.

Jede Anfrage an die Homepage löst also 4 Anfragen aus, unabhängig von der Zwischenspeicherungsrichtlinie des Bildes.

In Anbetracht des oben genannten zusammen mit dem neuen http2-Standard, den die meisten Webserver und Browser jetzt unterstützen, denke ich, dass es besser ist, das Lazyloading nicht mehr zu verwenden, da http2 alle Bilder nahezu gleichzeitig lädt.

Wenn dies ein Fehler in Chrome Devtools ist, überrascht es wirklich, dass dies noch niemand bemerkt hat. ;)

Ist dies der Fall, erhöht die Verwendung von Lazyloading nur die Bandbreitennutzung.

Bitte korrigieren Sie mich, wenn ich falsch liege. :)

1

Ich habe eine ähnliche Antwort zum asynchronen Vorladen von Bildern über JS. Dynamisches Laden entspricht dem normalen Laden. sie werden zwischenspeichern.

beim Caching können Sie den Browser nicht steuern, er kann jedoch über den Server festgelegt werden. Wenn Sie bei Bedarf eine wirklich frische Ressource laden müssen, können Sie die cache buster-Methode verwenden, um eine neue Ressource zu laden.

1
Joseph

Ich bevorzuge immer das in Konva JS: Image Events erwähnte Beispiel, um Bilder zu laden.

  1. Sie benötigen eine Liste von Bild-URLs als Objekt oder Array, zum Beispiel:

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

  2. Definieren Sie die Funktionsdefinition, in der eine Liste von Bild-URLs und eine Rückruffunktion in der Argumentliste enthalten sind. Wenn das Laden des Bildes abgeschlossen ist, können Sie auf Ihrer Webseite mit der Ausführung beginnen:

    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. Zuletzt müssen Sie die Funktion aufrufen. Sie können es zum Beispiel von aufrufen jQuery's Dokument bereit

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

0
Mahdi Alkhatib

Ja, der Browser speichert Bilder automatisch für Sie.

Sie können jedoch festlegen, dass ein Bild-Cache abläuft. Schauen Sie sich diese Stack Overflow-Fragen an und beantworten Sie:

Cache-Ablauf für statische Bilder

0
magzalez