How do I make an image load synchronously?

There is a non-evil way to load images in Javascript synchronously.

loadImage = async img => {
    return new Promise((resolve, reject) => {
        img.onload = async () => {
            console.log("Image Loaded");
            resolve(true);
        };
    });
};

Call it with await anywhere. like this

for(let i=0;i<photos.length;i++){
    await loadImage(photos[i]);
}

It will load all images one by one.

Note: Calling function must be async to use await


It is possible, but only with the ancient art of Base64 and Data-URL.

GIF image converted to Base64.

rune.b64

R0lGODlhIwAjAIAAAP///wAAACwAAAAAIwAjAAACf4SPqcsb3R40ocpJK7YaA35FnPdZGxg647kyqId2SQzHqdlCdgdmqcvbHXKi4AthYiGPvp9KVuoNocWLMOpUtHaS5CS54mZntiWNRWymn14tU7c2t6ukOJlKR5OiNTzQ7wb41LdnJ1coeNg3pojGqFZniPU4lTi0d4mpucmpUAAAOw==

JavaScript which loads the converted image form the same server via blocking AJAX.

loader.js

var request = new XMLHttpRequest();
var image = document.createElement('img');

request.open('GET', 'rune.b64', false);
request.send(null);

if (request.status === 200) {
  image.src= 'data:image/gif;base64,' + request.responseText.trim();

  document.getElementsByTagName("body")[0].appendChild(image); 
}

Problems

  • Some older browsers don't like (big) Data-URLs
  • Base64 encoding makes images about 37% bigger
  • The whole UI is blocked till the image is loaded

This is a very-evil way