I currently have an imageslider function in JavaScript which switches out one image for another when the user clicks on media arrows .. it works fine, BUT there is a lag the first time it loads each image. My question is this... is there a more efficient way to load multiple images at the same time then hide/make visible instead of loading each image one at a time (using div background-image)? Here is the JavaScript function I am currently using...
let imageNames = [];
function slideImage(offset = 0) {
var pc = document.querySelector(".slider");
var imageLocation = "/image/profile/";
let maxCount = imageNames.length - 1;
if (typeof index === "undefined") {
index = 0;
} else {
index += offset;
if (index > maxCount) {
index = 0;
} else if (index < 0) {
index = maxCount;
}
}
pc.style.backgroundImage = "URL('" + imageLocation + imageNames[index] + ".webp')";
}
Here is one example of asynchronously loading all your images, using fetch().
If you run the code snippet, you'll see there is a short delay before you can start displaying images. But then the rest of the images are loaded in the background, so on subsequent clicks there will be more (if not all) images ready to display.
See lines marked with EDIT for details on specific changes and (mostly) additions to your code.
// EDIT Added as it was being used in the original code
let index
let imageNames = [
// EDIT image paths are now added here by preLoadImages( )
]
// EDIT added list of image urls to be preloaded by preLoadImages( )
let remoteImageNames = [
"https://picsum.photos/1200/1300",
"https://picsum.photos/1200/1310",
"https://picsum.photos/1200/1320",
"https://picsum.photos/1200/1330",
"https://picsum.photos/1210/1300",
"https://picsum.photos/1220/1310",
"https://picsum.photos/1230/1320",
"https://picsum.photos/1240/1330",
];
// EDIT added call to new function
preLoadImages( )
// EDIT added function
function preLoadImages( ) {
for( let image of remoteImageNames ) {
getImageDataURL( image, imgUrl => {
imageNames.push( imgUrl )
document.querySelector(".slider").innerText = "CLICK FOR NEXT IMAGE"
} )
}
}
function slideImage(offset = 0) {
var pc = document.querySelector(".slider");
// EDIT for demo
// var imageLocation = "/image/profile/";
var imageLocation = "";
let maxCount = imageNames.length - 1;
if (typeof index === "undefined") {
index = 0;
} else {
index += offset;
if (index > maxCount) {
index = 0;
} else if (index < 0) {
index = maxCount;
}
}
// EDIT for demo
// pc.style.backgroundImage = "URL('" + imageLocation + imageNames[index] + ".webp')";
pc.style.backgroundImage = "URL('" + imageLocation + imageNames[index] + "')";
}
// EDIT added function
//
// fetch()'s image specified in the url
function getImageDataURL( url, callback=null ) {
fetch( url )
.then( result => result.blob() )
.then( blob => {
let fileReader = new FileReader( );
fileReader.onload = event => { // loadend event happens successfull or not. load event happens only for success
if( callback ) callback( fileReader.result );
};
fileReader.readAsDataURL( blob ); // Trigger file read
} )
}
.slider {
width: 400px;
height: 400px;
border: 1px solid gray;
box-shadow: 2px 2px 4px black;
border-radius: 10px;
margin: 20px;
background-size: contain;
background-repeat: no-repeat;
}
<div class="slider" onclick="slideImage(1)">
PLEASE WAIT...
</div>