programing

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

batch 2023. 9. 13. 22:26
반응형

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

제 친구들과 저는 미래에 더 빨리 보여주기 위해 특정 이미지를 캐시하고 싶은 웹사이트에서 일하고 있습니다.저는 크게 두 가지 질문이 있습니다.

  1. 이미지를 캐시하려면 어떻게 해야 합니까?
  2. 캐시된 이미지는 어떻게 사용합니까?(단순히 확인하기 위해 A페이지에 이미지를 캐시하면 B페이지에 이미지를 사용하기 위해 캐시에서 호출하는 것이 가능한가요?)

그리고 캐시된 이미지의 버전이 언제 만료되는지 설정 가능한가요?

예 및/또는 이에 대해 자세히 설명하는 페이지에 대한 링크가 포함되어 있다면 매우 감사할 것입니다.

저희는 raw 자바스크립트나 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"]);

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

javascript를 통해 이와 같이 이미지가 사전 로드되면 브라우저는 캐시에 이미지를 포함하고 다른 곳(웹 페이지)에 있는 일반 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);

@Pointy가 말하길 자바스크립트로 이미지를 캐싱하지 않는다고 했듯이 브라우저가 그렇게 합니다. 그래서 이것이 당신이 요구하는 것일 수도 있고 아닐 수도 있습니다.javascript를 이용해서 이미지를 미리 로드할 수 있습니다.사전 로드할 모든 이미지를 배열에 넣고 해당 배열에 있는 모든 이미지를 숨겨진 img 요소에 넣으면 이미지를 효과적으로 사전 로드(또는 캐시)할 수 있습니다.

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

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

답변의 완성도를 위해 추가하기: HTML로 사전 로딩

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

있지만 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ <link rel="preload">:

  • <link rel="prefetch">는 브라우저에서 오랫동안 지원되어 왔지만 다음 탐색/페이지 로드 시(예: 다음 페이지로 이동할 때) 사용될 리소스를 미리 불러오기 위한 것입니다.이것은 괜찮지만, 현재 페이지에는 유용하지 않습니다!또한 브라우저는 프리패치 리소스에 프리로드 리소스보다 낮은 우선순위를 부여합니다. 즉 현재 페이지가 다음 페이지보다 더 중요합니다.자세한 내용은 링크 프리페칭 FAQ를 참조하십시오.
  • <link rel="prerender">는 지정된 웹 페이지를 백그라운드로 렌더링하여 사용자가 해당 웹 페이지로 이동할 경우 로드 속도를 높입니다.Chrome은 사용자 대역폭을 낭비할 가능성이 있기 때문에 프리렌더를 대신 노스테이트 프리페치로 취급합니다.
  • <link rel="subresource">얼마 전 Chrome에서 지원되었으며, 프리로드와 동일한 문제를 해결하기 위한 것이었지만 문제가 있었습니다. 항목에 대한 우선 순위를 계산할 방법이 없었기 때문에(그 당시에는 존재하지 않았습니다), 모두 우선 순위가 상당히 낮았습니다.

스크립트 기반 리소스 로더가 많이 있지만 브라우저의 페치 우선 순위 대기열을 제어할 수 없으므로 거의 동일한 성능 문제가 발생합니다.

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

오늘날 구글은 이미지 렌더링 프로세스를 캐시하고 개선하기 위해 새로운 기술을 제안합니다.

  1. JavaScript Lazysize 파일 포함: lazysize.js
  2. 사용할 합니다. 에서 HTML 에 합니다 을 할 합니다 을 에 에서 할 <script src="lazysizes.min.js" async></script>
  3. 클래스를 이미지에 추가합니다.<img data-src="images/flower3.png" class="lazyload" alt="">

몇 가지를 살펴볼 수 있습니다.

이미지 하는 를 하는 를
file.htaccess의
이미지의 파일 크기 및 이를 인코딩하는 base64.

사전로딩: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

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

base64 인코딩에 대해서는 몇 가지 다른 생각이 있는데, http 요청이 대역폭을 축소한다고 말하는 반면, "인지된" 로딩이 더 낫다고 말하는 사람도 있습니다.이거는 그냥 놔둘게요.

당신의 질문에 "자바스크립트 사용"이라고 적혀있더라도, 당신은 사용할 수 있습니다.prefetch자산을 사전 로드할 링크 태그의 속성입니다.글을 쓰는 10일) 사파리에서는 모든 됩니다: Safari는 (2016년 8월 10일) Safari에서 지원됩니다.

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

지원에 대한 자세한 내용은 여기: http://caniuse.com/ #search=desch

9은 IE 9,10 에 .caniusematrix는 에 대한 했기 때문입니다.

그래서 jquery를 사용하여 jquery를 사용하여 이러한 요소를 페이지에 동적으로 추가할 수 있습니다 ;-)

저는 레이지로드 이미지와 비슷한 기법을 사용하지만, 자바스크립트가 첫 로딩 시 브라우저 캐시에 접근하지 못하는 것을 눈치채지 않을 수 없습니다.

예:

나는 홈페이지에 4개의 이미지가 있는 회전 배너를 가지고 있는데, 자바스크립트가 다음 이미지를 로드하고 2초를 기다리는 등 슬라이더가 2초를 기다립니다.

이 이미지들은 내가 수정할 때마다 바뀌는 고유한 URL을 가지고 있기 때문에 1년 동안 브라우저에서 캐시할 캐싱 헤더를 얻게 됩니다.

max-age: 31536000, public

이제 Chrome Devtools를 열고 de 'Disable cache' 옵션이 활성화되어 있지 않은지 확인하고 페이지를 처음 로드하면(캐시를 지운 후) 모든 이미지가 페치되어 200 상태가 됩니다.배너에 있는 모든 이미지를 전체 사이클한 후 네트워크 요청이 중지되고 캐시된 이미지가 사용됩니다.

이제 정기적으로 새로 고침을 수행하거나 하위 페이지로 이동한 후 다시 클릭하면 캐시에 있는 이미지가 무시되는 것 같습니다.Chrome devtools의 Network(네트워크) 탭에 "디스크 캐시에서"라는 회색 메시지가 표시될 것으로 예상됩니다.대신 요청이 회색이 아닌 녹색 상태 원으로 2초 간격으로 지나가는 것을 보고 데이터가 전송되는 것을 보고 자바스크립트에서 캐시가 전혀 액세스되지 않는 것을 알 수 있습니다.페이지가 로드될 때마다 이미지를 가져오기만 하면 됩니다.

따라서 홈페이지에 요청할 때마다 이미지의 캐싱 정책에 관계없이 4개의 요청을 트리거합니다.

위의 내용과 현재 대부분의 웹서버와 브라우저가 지원하는 새로운 http2 표준을 고려하면 http2는 거의 모든 이미지를 거의 동시에 로딩하기 때문에 lazy loading을 중단하는 것이 좋다고 생각합니다.

이것이 Chrome Devtools의 버그라면 아직 아무도 이것을 눈치채지 못했다는 것이 정말 놀랍습니다. ;)

이것이 사실이라면, 레이지로딩을 사용하면 사용에 따른 대역폭이 증가할 뿐입니다.

제가 틀렸다면 고쳐주세요.:)

JS를 통한 비동기 프리로딩 이미지에 대해서도 비슷한 답변을 드립니다.동적으로 로드하는 것은 정상적으로 로드하는 것과 동일합니다.그들은 현금화 할 것입니다.

캐싱은 브라우저를 제어할 수 없지만 서버를 통해 설정할 수 있습니다.필요에 따라 정말 새로운 리소스를 로드해야 하는 경우 캐시 버스터 기법을 사용하여 새 리소스를 강제로 로드할 수 있습니다.

예, 브라우저가 자동으로 이미지를 캐시합니다.

그러나 이미지 캐시가 만료되도록 설정할 수 있습니다.스택 오버플로 질문을 확인하고 다음과 같이 대답합니다.

정적 이미지의 캐시 만료

저는 항상 Konva JS: Image Events에 언급된 예를 사용하여 이미지를 로드하는 것을 선호합니다.

  1. 이미지 URL 목록을 개체 또는 배열로 사용해야 합니다. 예를 들어 다음과 같습니다.
var sources = {
    lion: '/assets/lion.png',
    monkey: '/assets/monkey.png'
};
  1. 함수 정의를 정의합니다. 함수 정의는 이미지 URL 목록과 인수 목록의 콜백 함수를 수신하므로 이미지 로드가 완료되면 웹 페이지에서 실행을 시작할 수 있습니다.

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. 마지막으로 그 기능을 호출해야 합니다.를 이용해 부를 수 있습니다.
$(document).ready(function () {
    loadImages(sources, buildStage);
});

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

반응형