Programing

자바 스크립트에서 이미지를 캐시하는 방법

crosscheck 2020. 11. 11. 08:01
반응형

자바 스크립트에서 이미지를 캐시하는 방법


내 친구와 나는 특정 이미지를 나중에 더 빨리 표시하기 위해 캐시하려는 웹 사이트에서 작업하고 있습니다. 두 가지 주요 질문이 있습니다.

  1. 이미지를 어떻게 캐시합니까?
  2. 캐시 된 이미지는 어떻게 사용합니까? (단지 확인하기 위해 이미지가 페이지 A에 캐시 된 경우 캐시에서 호출하여 페이지 B에서 사용할 수 있습니다.)

또한 이미지의 캐시 된 버전이 만료되는 시기 를 설정할 수 있습니까?

더 자세히 설명하는 페이지에 대한 예제 및 / 또는 링크가 포함되어 있으면 매우 감사하겠습니다.

원시 Javascript 또는 jQuery 버전을 사용하는 것이 좋습니다.


이미지가 어떤 방식 으로든 브라우저에로드되면 브라우저 캐시에 있으며 이미지가있는 한 현재 페이지에서 사용하든 다른 페이지에서 사용하든 다음에 사용할 때 훨씬 더 빠르게로드됩니다. 브라우저 캐시에서 만료되기 전에 사용됩니다.

따라서 이미지를 미리 캐시하려면 브라우저에 이미지를로드하기 만하면됩니다. 여러 이미지를 미리 캐시하려면 일반적으로 자바 스크립트에서 수행 할 때 페이지로드를 유지하지 않으므로 자바 스크립트로 수행하는 것이 가장 좋습니다. 다음과 같이 할 수 있습니다.

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

이 함수는 원하는만큼 호출 할 수 있으며 매번 프리 캐시에 더 많은 이미지를 추가합니다.

이미지가 자바 스크립트를 통해 이와 같이 미리로드되면 브라우저는 해당 이미지를 캐시에 저장하고 다른 위치 (웹 페이지)의 일반 URL을 참조 할 수 있으며 브라우저는 브라우저가 아닌 캐시에서 해당 URL을 가져옵니다. 회로망.

결국 시간이 지남에 따라 브라우저 캐시는 한동안 사용되지 않은 가장 오래된 것을 가득 채울 수 있습니다. 따라서 결국 이미지는 캐시에서 플러시되지만 잠시 동안 거기에 있어야합니다 (캐시 크기와 다른 검색이 수행 된 정도에 따라 다름). 이미지가 실제로 다시 미리로드되거나 웹 페이지에서 사용될 때마다 브라우저 캐시의 위치를 ​​자동으로 새로 고쳐서 캐시에서 플러시 될 가능성을 줄입니다.

브라우저 캐시는 교차 페이지이므로 브라우저에로드 된 모든 페이지에서 작동합니다. 따라서 사이트의 한 위치에서 사전 캐시 할 수 있으며 브라우저 캐시는 사이트의 다른 모든 페이지에서 작동합니다.


위와 같이 미리 캐싱하면 이미지가 비동기 적으로로드되므로 페이지로드 또는 표시를 차단하지 않습니다. 그러나 페이지에 자체 이미지가 많은 경우 이러한 사전 캐시 이미지는 페이지에 표시되는 이미지와 대역폭 또는 연결을두고 경쟁 할 수 있습니다. 일반적으로 이것은 눈에 띄는 문제는 아니지만 느린 연결에서이 사전 캐싱으로 인해 기본 페이지로드 속도가 느려질 수 있습니다. 미리로드 된 이미지가 마지막으로로드되는 것이 괜찮다면 다른 모든 페이지 리소스가 이미로드 될 때까지 미리로드를 시작하기 위해 대기하는 함수 버전을 사용할 수 있습니다.

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

as @Pointy said you don't cache images with javascript, the browser does that. so this may be what you are asking for and may not be... but you can preload images using javascript. By putting all of the images you want to preload into an array and putting all of the images in that array into hidden img elements, you effectively preload (or cache) the images.

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

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

There are a few things you can look at:

Pre-loading your images
Setting a cache time in an .htaccess file
File size of images and base64 encoding them.

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

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

There are a couple different thoughts for base64 encoding, some say that the http requests bog down bandwidth, while others say that the "perceived" loading is better. I'll leave this up in the air.


I have a similar answer for asynchronous preloading images via JS. Loading them dynamically is the same as loading them normally. they will cache.

as for caching, you can't control the browser but you can set it via server. if you need to load a really fresh resource on demand, you can use the cache buster technique to force load a fresh resource.


Even though your question says "using javascript", you can use the prefetch attribute of a link tag to preload any asset. As of this writing (Aug 10, 2016) it isn't supported in Safari, but is pretty much everywhere else:

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

More info on support here: http://caniuse.com/#search=prefetch

Note that IE 9,10 aren't listed in the caniuse matrix because Microsoft has discontinued support for them.

So if you were really stuck on using javascript, you could use jquery to dynamically add these elements to your page as well ;-)


I use a similar technique to lazyload images, but can't help but notice that Javascript doesn't access the browser cache on first loading.

My example:

I have a rotating banner on my homepage with 4 images the slider wait 2 seconds, than the javascript loads the next image, waits 2 seconds, etc.

These images have unique urls that change whenever I modify them, so they get caching headers that will cache in the browser for a year.

max-age: 31536000, public

Now when I open Chrome Devtools and make sure de 'Disable cache' option is not active and load the page for the first time (after clearing the cache) all images get fetch and have a 200 status. After a full cycle of all images in the banner the network requests stop and the cached images are used.

Now when I do a regular refresh or go to a subpage and click back, the images that are in the cache seems to be ignored. I would expect to see a grey message "from disk cache" in the Network tab of Chrome devtools. In instead I see the requests pass by every two seconds with a Green status circle instead of gray, I see data being transferred, so it I get the impression the cache is not accessed at all from javascript. It simply fetches the image each time the page gets loaded.

So each request to the homepage triggers 4 requests regardless of the caching policy of the image.

Considering the above together and the new http2 standard most webservers and browsers now support, I think it's better to stop using lazyloading since http2 will load all images nearly simultaneously.

If this is a bug in Chrome Devtools it really surprises my nobody noticed this yet. ;)

If this is true, using lazyloading only increases bandwith usage.

Please correct me if I'm wrong. :)


Yes, the browser caches images for you, automatically.

You can, however, set an image cache to expire. Check out this Stack Overflow questions and answer:

Cache Expiration On Static Images


I always prefer to use the example mentioned in Konva JS: Image Events to load images.

  1. You need to have a list of image URLs as object or array, for example:

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

  2. Define the Function definition, where it receives list of image URLs and a callback function in its arguments list, so when it finishes loading image you can start excution on your web page:

    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. Lastly, you need to call the function. You can call it for example from jQuery's Document Ready

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


Adding for completeness of the answers: preloading with HTML

<link rel="preload" href="bg-image-wide.png" as="image">

Other preloading features exist, but none are quite as fit for purpose as <link rel="preload">:

  • <link rel="prefetch"> has been supported in browsers for a long time, but it is intended for prefetching resources that will be used in the next navigation/page load (e.g. when you go to the next page). This is fine, but isn't useful for the current page! In addition, browsers will give prefetch resources a lower priority than preload ones — the current page is more important than the next. See Link prefetching FAQ for more details.
  • <link rel="prerender"> renders a specified webpage in the background, speeding up its load if the user navigates to it. Because of the potential to waste users bandwidth, Chrome treats prerender as a NoState prefetch instead.
  • <link rel="subresource"> was supported in Chrome a while ago, and was intended to tackle the same issue as preload, but it had a problem: there was no way to work out a priority for the items (as didn't exist back then), so they all got fetched with fairly low priority.

There are a number of script-based resource loaders out there, but they don't have any power over the browser's fetch prioritization queue, and are subject to much the same performance problems.

Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content

참고URL : https://stackoverflow.com/questions/10240110/how-do-you-cache-an-image-in-javascript

반응형