1. ホーム
  2. javascript

[解決済み] Javascriptで画像をキャッシュする方法

2023-03-10 11:51:47

質問

私の友人と私は、将来より速く表示するために特定の画像をキャッシュしたいと思い、ウェブサイトを制作しています。 私は 2 つの主要な質問があります。

  1. どのように画像をキャッシュするのですか?
  2. 一度キャッシュされた画像はどのように使うのですか? (一応確認しておきますが、Aページで画像がキャッシュされた場合、キャッシュから呼び出してBページで使用することは可能ですよね?)

また を設定することはできますか? を設定することはできますか?

例および/またはこれをさらに説明するページへのリンクが含まれていれば、非常に感謝されます。

生のJavascriptまたはjQueryバージョンのどちらを使用しても問題ありません。

どのように解決するのですか?

ブラウザに何らかの方法で画像が読み込まれると、その画像はブラウザのキャッシュに保存され、現在のページでも他のページでも、ブラウザのキャッシュからその画像が消去される前に使用されれば、次に使用するときの読み込み速度がはるかに速くなります。

つまり、画像をプリキャッシュするには、ブラウザに画像を読み込むだけでよいのです。 多くの画像をプリキャシュしたい場合は、javascript で行うのが最善でしょう。javascript で行うと、一般にページの読み込みが滞ることはありません。 このようにすることができます。

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

この関数は何度でも呼び出すことができ、そのたびにプリキャッシュに画像が追加されるだけです。

いったん画像がjavascriptによってこのようにプリロードされると、ブラウザはそれらをキャッシュに保持し、他の場所(ウェブページ内)で通常のURLを参照するだけで、ブラウザはネットワーク経由ではなくキャッシュからそのURLを取得します。

結局、時間が経つにつれて、ブラウザのキャッシュはいっぱいになり、しばらく使われていない古いものは捨てられてしまうかもしれません。 そのため、最終的に画像はキャッシュからフラッシュされますが、しばらくはそこにとどまるはずです (キャッシュの大きさと、他のブラウジングの量に依存します)。 画像が実際に再びプリロードされたり、Web ページで使用されたりするたびに、ブラウザのキャッシュ内の位置が自動的にリフレッシュされるので、キャッシュから洗い流される可能性は低くなります。

ブラウザ キャッシュはページをまたぐので、ブラウザに読み込まれたどのページに対しても機能します。 そのため、サイトの 1 か所で事前キャッシュを行い、ブラウザ キャッシュはサイト上の他のすべてのページで機能します。


上記のようにプリキャッシングする場合、画像は非同期に読み込まれるため、ページの読み込みや表示を妨げることはありません。 しかし、ページにそれ自身の画像が多数ある場合、これらのプリキャッシュ画像は、ページに表示されている画像と帯域幅や接続を競合させる可能性があります。 通常、これは目立った問題ではありませんが、遅い接続では、このプリキャッシュがメインページの読み込みを遅くする可能性があります。 プリロード画像が最後に読み込まれることが問題ない場合は、他のすべてのページ リソースがすでに読み込まれた後までプリロードの開始を待機する関数のバージョンを使用することができます。

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