Use the HTML picture tag with 3 image formats .jpg .webp .jpf for best mobile performance

Hi all,
In order to improve the permormance of my site I would like help and have your opinion on the integration of images.
I want to modify Hugo’s Layouts in order to
be able to use the picture tag instead of the img tag.
Here is an example of code:

<picture>
    <source
      srcset="images/image-01.webp"
      type="image/webp">
    <source
      srcset="images/image-01.jp2"
      type="image/jp2">
    <source
      srcset="images/image-01.jxr"
      type="image/vnd.ms-photo">
    <img
      src="images/image-01.png"
      width="278"
      height="383"
      alt="Rebel">
</picture>

I do not know where to start.
This will allow the browser to choose the appropriate image.

Here is an example of the front matter in archetypes/blog.md

---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: no
# page title background image
bg_image: ["images/blog/image-01.jpg","images/blog/image-01.webp"]
# meta description
description : "This is meta description"
# post thumbnail
image: ["images/blog/image-01.jpg","images/blog/image-01.webp"]
# post author
author: "John Doe"
# taxonomy
categories: ["Category"]
tags: ["Tag1", "Tag2"]
# type
type: "post"
---

I do not know if this subject has already been treated but this is important for the optimization of the site.
thank you in advance

If you want to set image in front matter, then you reference those images in the templates where you want to show the image, for instance in the single.html template where a “feathered image” would appear.

Alternatively, you can use a shortcode to render the images inline. Search the docs for the “figure shortcode”, it will show you that method.

I would just use a single entry for the image file in the front matter since they are all the same except the extension then make a shortcode with this:

<picture>
    <source
      srcset="{{.Params.image}}.webp"
      type="image/webp">
    <source
      srcset="{{.Params.image}}.jp2"
      type="image/jp2">
    <source
      srcset="{{.Params.image}}.jxr"
      type="image/vnd.ms-photo">
    <img
      src="{{.Params.image}}.png"
      width="278"
      height="383"
      alt="Rebel">
</picture>

Then change your front matter image entry to this: images/blog/image-01 hopefully that gets you on the right path, good luck.

1 Like

Thank you very much, I’ll try it

But what if I only put one .jpg image

Hugo cannot convert to the other formats -if that is your question-. You need to provide all formats because otherwise there will be an error that will prevent your project from building.

Thank you
Benmarte’s solution is easy to set up. I was thinking of something more dynamic.
A condition so that we don’t have to worry about the number of images to provide.

But I will start by doing what Benmarte offers

Using Benmarte’s solution, it works well.

You can see the result on the home page of my website.

All images are distributed in WebP format on browsers that support it.

Here is the “shortcode” that I use for the posts

{{/*  Picture  */}}
{{ $_src := .Get "src" }}
{{ $_title := .Get "title" }}
<figure class="py-4">
    <picture>
        <source
            srcset="{{ $_src  | absURL }}.webp"
            type="image/webp">
        <source
            srcset="{{ $_src  | absURL }}.jpf"
            type="image/jp2">
        <img
            class="img-fluid"
            src="{{ $_src | absURL }}.jpg"
            alt="{{ $_title }}">
        </picture>
    <figcaption>{{ $_title }}</figcaption>
</figure>

{{< picture src="images/portfolio/your-business" title="Exemple de page statique responsive" >}}

Indeed, this requires providing the 3 image formats well, it is not necessarily easy to manage.
I don’t know if there is a method to convert the images dynamically

What do you think ?

1 Like