How to implement lazy load for images returned from a server in ES5?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


How to implement lazy load for images returned from a server in ES5?



On one page, I'm trying to lazy load potentially hundreds of images that are returned from my server as blobs. I've tried converting them to base64 data uris then using some lazy loading techniques, but understandably that didn't work, since the data uri is already in the html, which means the browser still needs to load the image data even if it's not going to display it right away.



Is there some way to lazy load dynamic images returned by a server as blobs? Or some way to convert them to use remote image urls then use typical lazy loading that way?



Thanks for any help.





If you have received them already, you do not have to load them again. Please add a Minimal, Complete, and Verifiable example to get more help.
– Kosh Very
yesterday





@KoshVery it's a question about the general way to do something. An example would be far too complex to be of any use, and would escape the entire purpose of the question.
– Alex Podworny
yesterday





I believe the example would illustrate the issue better than words.
– Kosh Very
yesterday





I agree no example is needed, the description is pretty clear.
– colxi
yesterday




1 Answer
1



ES5 approach : XMLHttpRequest



In this scenario you get an arraybuffer from the ajax request, that must be converted into a base64 string, before being useful. (IE10+ Compatible Method)


arraybuffer


base64




let myImg = document.getElementById('myImg');
let url = "https://placekitten.com/200/300";

let request = new XMLHttpRequest();
request.open ("GET", url, true);
request.responseType = "arraybuffer";
request.send (null);

request.onreadystatechange= function(response){
if (request.readyState === 4) {
if (request.status === 200) {
// convert received arrayBuffer into base64 encoded string
var imgBase64 = btoa(String.fromCharCode.apply(null, new Uint8Array(request.response)));
// assign base64 encoded image to image source
myImg.src= 'data:image/jpeg;base64,' + imgBase64;
}
}
}


<img id="myImg" />



Note: CORS must be taken in consideration, when retrieving images from external domains.



ES6 approach : Fetch



You can use fetch to retrieve your images, and inject them in the DOM as soon as you receive them...


fetch




let myImage = document.getElementById('myImg');
let url = "https://placekitten.com/200/300";

fetch(url)
.then( response=> {
// if response is OK, covert it into a blob
if(response.ok) return response.blob();
else throw new Error('Response not OK');
})
.then(myBlob=>{
// Assign it to the image src using createObjectURL
myImage.src = URL.createObjectURL(myBlob);
})
.catch(function(error){
// hadle errors
console.log(error.message);
});


<img id="myImg" />



You can get more details about Fetch and createObjectURL in the Mozilla Developer webpage.



Previous code can be easily converted into reusable functions, suitable for generic scenarios.





Thanks. While this might put me on the right track, is it possible to do with ajax instead? I need to support IE11, and would prefer not to use a polyfill for fetch. I've never used fetch, but it looks pretty similar to ajax
– Alex Podworny
yesterday





I updated my answer including the Ajax approach
– colxi
yesterday





Sorry for not quite understanding your solution yet, what exactly is the lazy loading portion of this answer? If I return a list of hundreds of images from my server in the one response, your answer won't really help, correct? Where exactly is the lazy loading implemented? Thanks for the help
– Alex Podworny
yesterday





This code lets you load the images, only when you need them, but you have to load each image one by one, and inject them in the DOM manually. If you recieve a list of Image Urls from your server, you have to iterate that list, and execute this code for each element.
– colxi
yesterday







"This code lets you load the images, only when you need them" - That's what I'm confused about, how does your ES5 code snippet know when we need the images? Where exactly is this functionality?
– Alex Podworny
23 hours ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

How to scale/resize CVPixelBufferRef in objective C, iOS