3

Due to a constraint, we need to display HTML content from a different service which images are just typical <img src="http://example.com/image.jpg"/>

Most of lazy loading libraries (e.g lozad.js) suggested removing src attribute and adding data-src otherwise browser will load each image immediately.

I can parse and transform the dom to conform the requirement but I feel adding extra overhead is defeating the performance purpose.

Is there any technique to achieve lazy loading without touching the HTML?

3
  • 1
    There is not. Don't worry about the overhead of a few extra bytes inside html, compared to even including 1 basic image is nothing. The problem is that images are loaded as soon as the img tag is encountered by the browser. And JavaScript will always be later so it can't intercept the image load.(some exceptions might be valid) Commented Mar 18, 2019 at 19:05
  • @René I see, thanks for the comment. I meant the server overhead of parsing string into html and changing the attribute src to data-src. For big blob of HTML, it may matter. Maybe a global substring will help. Commented Mar 18, 2019 at 20:08
  • Well, you usually don't replace it inside a big text. You just change the src to data-src where the string is created. But even if you need string replacing inside a big chunk of html, it's not that bad. And by the time the html is too big for a string replacement you should worry about other things first ;-) Commented Mar 18, 2019 at 21:23

2 Answers 2

5

There is new HTML built-in support in lazy loading if your clients are using supported browsers you better use it

<img src="https://i.picsum.photos/id/238/300/300.jpg" loading="lazy" />

It will load when you scroll to the relevant section

Sign up to request clarification or add additional context in comments.

1 Comment

thanks, but you may want to write it in a comment to @zocoi's answer
2

If you're injecting the html snippet of the image element, you could put it in a span rather and manipulate the html later.

For example:

<div id="topNav">
    <span class="unloaded">
      <noscript>
        <img src="https://www.jpl.nasa.gov/images/universe/20170802/heliophysics-16.jpg">
      </noscript>
    </span>
    <div class="heightTest">
    </div>
    <span class="unloaded">
      <noscript>
        <img src="https://www.jpl.nasa.gov/images/universe/20170802/heliophysics-16.jpg">
      </noscript>
    </span>
  </div>

Then watch it with javascript:

function isElementInViewport (el) {
      var rect = el.getBoundingClientRect();
      return (
          rect.top >= 0 &&
          rect.left >= 0 &&
          rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
          rect.right <= (window.innerWidth || document.documentElement.clientWidth)
      );
  }


  var images = document.getElementsByClassName('unloaded');
  function checkImages() {
    var clean = false;
    for(var i=0; i<images.length;i++){
      var el = images[i];
      if(isElementInViewport(el)){
        //replace the span's innerhtml with the noscript innerhtml.
        el.innerHTML = el.childNodes[1].innerHTML;
        //remove the class, since it's now loaded.
        el.classList.remove("unloaded");
        //we changed at least one element, so we'll want to get a new clean list.
        clean = true;
      }
    }

    if(clean == true){
      images = document.getElementsByClassName('unloaded');
    }
  }
  checkImages();
  window.addEventListener('scroll', checkImages, false);

This way you're waiting until the event to modify any HTML. An advantage here is if javascript isn't running, the images will load anyways. As well since it's a span you can set the size and background to a grey loading icon via css for the span class "unloaded".

11 Comments

Out of curiosity. Why are you using <noscript> tags in that example above? That is designed to render content if a browser has script execution disabled. Granted, I suppose it would prevent loading of the src. I am ultimately just curious if this is a sly/hacky use of it, or a standard use case.
I would think it's pretty standard? If the user doesn't have a script engine available to lazy load my images, just load them right away. If there is a script engine, the script takes care of loading them. I don't think it's hacky at all, but I am open to opinions.
It's a nice optional addition to the regular lazy load. I think it's rare enough that people load pages without scripting(broken scripting happens more often but noscript doesn't fix that). One big issue, your page will have a lot of size changes while you scroll because you have no sized placeholders. Also, images larger than viewport will not get loaded.
If you know image size server side you can use a padding hack or svg placeholder(and probably other techniques). svg: <img src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='{$width}'%20height='{$height}'/%3E" data-src="your/actual/image" alt="Useful alt"> (watch out for the quote styles)
The question was to show how to have lazy loading with the constraint that the html cannot change on page load. Concept is there. I think there's plenty of ways to deal with broken scripts and an in-view check that includes huge images. A script that could pre-size a placeholder without loading the image would be something indeed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.