For lazy-loading visualization, I'm attempting to apply a fade-in animation style class only to images that have not been cached in the browser.
To determine if an image was previously loaded and cached in the browser, we can employ the HTMLImageElement.complete property in a function like this:
const isImageCached = (imageSource) => {
let image = new Image();
image.src = imageSource;
const isCached = image.complete;
image.src = "";
image = null;
return isCached;
};
However, in Chrome, HTTP Cache items are either located in memory cache or disk cache. The above function only works if the image is in memory cache and will always return false if the image is in disk cache. I assume this is because memory is accessed immediately at 0 milliseconds while the disk cache can take up to several milliseconds to be retrieved.
When you first open and run the above script the image fades in since it hasn't yet been cached in the browser. When you re-run the script by pressing the "Run" button, the image doesn't fade in because it is now cached in Chrome's memory cache. The problem occurs if the memory cache has been cleared. The image has already been cached but now it may be located in the disk cache so the image will fade in.
Below is a screen capture of Chrome Developer Tools detailing the output when the page is refreshed (disk cache) and then the script is re-run without a page refresh (memory cache):
Is it possible to determine in JavaScript if an image is located in the HTTP Cache, either memory cache or disk cache, before displaying the image?
const image = document.querySelector("img");
const marioSrc = "https://www.pinclipart.com/picdir/big/361-3619269_mario-16-bit-mario-bros-super-mario-world.png";
const isImageCached = (imageSource) => {
let image = new Image();
image.src = imageSource;
const result = image.complete;
image.src = "";
image = null;
return result;
};
if (!isImageCached(marioSrc)) {
image.classList.add("image-fade-in");
}
image.setAttribute("src", marioSrc);
:root {
margin: 0;
padding: 0;
}
body {
background-color: #444444;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow-y: hidden;
}
@keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
.image-fade-in {
animation: fade-in 1s ease-in-out;
}
<img />
