How to Add a Skeleton Loader for ion-img in Ionic
what’s the problem?
the built in <ion-img> component uses Intersection Observer internally to lazy load images, which is good for performance. But its lacking a finished loading event that makes it difficult to implement skeleton loaders.
the event we’re interested in, (ionImgDidLoad) fires way earlier than the image shows on screen. So even if you did hook a skeleton loader up to this event, the skeleton would show, then it would collapse completely and then the image would start loading from top to bottom.
the alternate is to use the html <img> component and use its onload event. But then you give up the lazy loading built in to <ion-img>.
what’s the fix?
first, we need to keep track of the images that have been loaded.
const imagesLoaded = {};
we need a function that updates the state of loaded Images.
loadImage(uniqueId) {
this.imagesLoaded[uniqueId] = true;
}
We need to build the loaded state on data fetch as below. This is important because if the image has already been loaded, we don’t want to reset its state. This comes in handy if you have a load more functionality.
Our html uses the background property to show a loader in place of an image and switches to transparent when it is loaded.
bringing it all together
we have our state in imagesLoaded. as new data is fetched, this object remembers our previous state and adds new state.
when your posts come into view, the image begins loading while your skeleton shows in its place. As soon as the IonImageDidLoad event fires, it changes the background to transparent. having tried a lot of different things to achieve this outcome, this is a good balance between UX and performance. all without adding extra dependencies.