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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With