So, I read a bunch of articles and Google docs about lazy loading images in a proper way nowadays, and found this solution:
loading="lazy"
in <img />
tags where it's supportedSo far so good, but when I am delivering my web app with server-side rendering (in my case an Angular 8 app with ANgular Universal enabled), and I can't verify which browser my client uses when rendering, just when the app is rendered and then the lazy loading doesn't work.
I am using this great approach from Natanel: Link
import { Directive, ElementRef } from '@angular/core';
@Directive({ selector: 'img' })
export class LazyImgDirective {
constructor({ nativeElement }: ElementRef<HTMLImageElement>) {
const supports = 'loading' in HTMLImageElement.prototype;
if (supports) {
nativeElement.setAttribute('loading', 'lazy');
}
}
}
The problem is that this if is always falsy in server.
images will still be downloaded as a separate http calls, so logic on the server won't work as you probably expect. what to do really depends on how do you handle the "unsupported" case.
case 1: you want to just leave the image as non lazy. If so - just add the attribute when this logic is used on the server environment. for newer browsers - these images will be lazy. for older browsers - your images will be loaded just as simple images, just the same as you directive logic.
case 2: you want to fallback to IntersectionObserver
. In this case just skip the logic in this directive when running on server. it will be handled on client.