Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with image lazy loading when you have a SSR web app?

So, I read a bunch of articles and Google docs about lazy loading images in a proper way nowadays, and found this solution:

  • Use the newer loading="lazy" in <img /> tags where it's supported
  • Fallback to the Intersection Observer where it is not

So 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.

like image 235
rogerdossantos Avatar asked Sep 16 '25 18:09

rogerdossantos


1 Answers

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.

like image 175
Andrei Avatar answered Sep 19 '25 11:09

Andrei