Adam
Adam

Reputation: 1459

Using lazy loading AND webp images with JPG fallback

I am currently lazy loading 'jpg' images using the unveil.js script and it works fine.

I simply serve a placeholder image and eventually the image path is populated by the path in a data attribute. Here is my HTML...

<img class="unveil" src="blank.png" alt="Variation 2" data-src="variant2.jpg">

and I call the function...

$(".unveil").unveil();

Now the problem is, I would like to add WebP images to my website but with a jpg fallback as WebP isn't supported in previous versions of Safari.

Ideally I would use this markup...

<picture>
    <source srcset="variant2.webp" type="image/webp">
    <img class="unveil" src="blank.png" alt="Variation 2" data-src="variant2.jpg">
</picture>

Questions

  1. How would I modify the code to swap both the jpg source AND the WebP source? Is it possible to do this AND still use lazy loading?

  2. Would be easier to detect webp support upfront?

  3. Should I just not use lazy loading on webp images as they are small enough and continue using the script as is for jpgs incase webp isn't supported?

For reference, here is the code for the unveil.js script...

;(function($) {

  $.fn.unveil = function(threshold, callback) {

    var $w = $(window),
        th = threshold || 0,
        retina = window.devicePixelRatio > 1,
        attrib = retina? "data-src-retina" : "data-src",
        images = this,
        loaded;

    this.one("unveil", function() {
      var source = this.getAttribute(attrib);
      source = source || this.getAttribute("data-src");
      if (source) {
        this.setAttribute("src", source);
        if (typeof callback === "function") callback.call(this);
      }
    });

    function unveil() {
      var inview = images.filter(function() {
        var $e = $(this);
        if ($e.is(":hidden")) return;

        var wt = $w.scrollTop(),
            wb = wt + $w.height(),
            et = $e.offset().top,
            eb = et + $e.height();

        return eb >= wt - th && et <= wb + th;
      });

      loaded = inview.trigger("unveil");
      images = images.not(loaded);
    }

    $w.on("scroll.unveil resize.unveil lookup.unveil", unveil);

    unveil();

    return this;

  };

})(window.jQuery || window.Zepto);

Upvotes: 0

Views: 969

Answers (1)

manoi
manoi

Reputation: 798

I'm not sure about your first question, but here's what you could do:

<picture>
  <source type="image/webp"
    srcset=".."
    sizes="..">
  <source type="image/jpeg"
    srcset=".."
    sizes="..">
  <img src="default.jpg"
    loading="lazy"
    alt="..">
</picture>

to 2) i would do it this way, so no to 3) lazy is always a good way if you have images that a not that important and not above the fold. Also think about to set width and height attribute on that the browser can reserve the correct space.

Upvotes: 1

Related Questions