skip to Main Content

Some file formats like jpeg and webp allow "progressive loading" where the file is encoded in a way such that a lower resolution version of the image can be rendered before the entire file has finished loading.

However, the "onload" event will still only trigger once the image has fully loaded in its highest resolution state which begs the question of what to do if you are interested in the moment the image appear on the screen instead.

My question is if I can detect when the first lower resolution version has loaded and can be rendered?

something like:

// Hypothetical event
image.onreadytorender = () => placeholder.hide() && image.show();  

My usecase is that I want to remove and replace a LQIP (low quality image placeholder) with the real image as soon as it has loaded enough to render its low resolution version instead of having to wait for the fully loaded version which is what onload would do.

// This would not leverage the advantages of progressive loading
image.onload = () => placeholder.hide() && image.show()

Typically, all tutorials I have found on loading images says to use JS and the onload event to replace the placeholder with the real image. However, this does not make any sense considering how modern file formats like webp and avif work. One of their greatest advantages is that they can be rendered before it is fully loaded and onload is triggered. So is there a way to detect when the first paint of the image can happen? Or how do I leverage the advantages of progressive loading while also using a LQIP?

I have considered just loading the image on top of the LQIP without any JS, however, this would not work for images with transparency because the LQIP would be blurred causing it to overflow beneath the full image if it is not removed. It also would not trigger any fade in animations.

2

Answers


  1. Giving it a fixed height and width of the expected image while displaying a loading gif and then replacing with the images as they load completely work instead of the problems with LQIP. This way you also prevent a layout shift, keeping your CLS score down.

    Login or Signup to reply.
  2. Solution

    According to some online research I did, you can detect when the lower resolution version of an image has loaded and can be rendered, you can use the decode method available on the HTMLImageElement. The decode method allows you to check if the browser can decode the image data without actually rendering it.

    Example code

    // Get a reference to your image element
        const image = document.getElementById("yourImageId");
        const placeholder = document.getElementById("placeholderId");
    
    // Hide the image initially
        image.style.display = "none";
    
    // Check if the browser can decode the image data
        image.decode().then(() => {
    // This code will run when the browser can decode the image data
    
    // Hide the placeholder and show the image
        placeholder.style.display = "none";
        image.style.display = "block";
    }).catch((error) => {
    // Handle any errors that occur during decoding
        console.error("Error decoding image:", error);
    
    // Fallback: If decoding fails, show the image anyway
        placeholder.style.display = "none";
        image.style.display = "block";
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search