Optimize featured images

What is the best solution to optimize dynamically written images, for example image previews ( featured images ) ? to have a fast site

1 Like

Don’t? Seriously, pages load much faster without loading multiple images, even if they are all relatively small. If you are convinced the images will lead to more users visiting the site, or visiting more pages on your site, I would recommend testing this theory with some A/B testing and analytics.

Having said that, if you insist on having a e.g., a list of articles with thumbnails or previews or some such, the best solution for optimizing your images depends on your hosting, preferred workflow, and whether you can/are willing to use Git LFS.

If you don’t want images stored in your Git repository (with Git LFS), then using optimized images will be more complicated than if you use Git LFS and page bundles. With Git LFS and page bundles, Hugo’s image processing (to resize and convert to a more effective format such as webp, for example) is likely what will give you the best results for the time you spend.

Otherwise, @bwintx has written an [article on using Cloudinary’s image processing with Hugo[(Using Hugo Pipes with Cloudinary: a follow-up | BryceWray.com), and others have guides for other image processing/hosting services (IIRC).

1 Like

How to convert all images of my hugo project in webp

knowing that i use this code to show featured images of posts:

 <figure class="image-f">
        {{ with .Params.images }}
        <a href="{{ $permalink }}"><img loading="lazy" src="{{ index . 0 }}" alt=""></a>
        {{ end }}
    </figure>

With an image render hook, perhaps?

1 Like

In case you are having trouble finding info on render hooks, it is here:

Markdown render hooks | Hugo (gohugo.io)

Joe Mooring has also written an excellent article on the topic everyone should read:

My approach to featured images is to optimise full size image first before putting it through Hugo rendering hooks.

If its PNG or JPG, I always optimize it using these two websites:

  1. https://compressor.io
  2. https://imagecompressor.com

I am using 1st or 2nd, or both, where 1st for compression and 2nd through further optimisation, especially on PNG files when I want to drop down number of colours.

Then I am leaving it for Hugo to do the rest. Convert to WebP and serve in few sizes depend on the user resolution and device.

Here is my example of my article-featured.html (in my /partials/ folder called in article.html using {{ partial "article-featured.html" . }}

{{ if .Params.featuredImage }}  
{{ $ftimgsrc := resources.Get .Params.featuredImage }}

    <div class="featured-media">
    <picture>

        {{ $isJPG := eq (path.Ext .Params.featuredImage) ".jpg" }}
        {{ $isJPEG := eq (path.Ext .Params.featuredImage) ".jpeg" }}
        {{ $isPNG := eq (path.Ext .Params.featuredImage) ".png" }}

        {{ if or ($isJPG) ($isJPEG) ($isPNG) }}

            {{ $smallw := "480x webp" }}
            {{ $mediumw := "960x webp" }}
            {{ $largew := "1920x webp" }}
            {{ $originw := (printf "%dx webp" $ftimgsrc.Width) }}
        
            {{ $data := newScratch }}
            {{ if ge $ftimgsrc.Width 480 }}
                {{ $data.Set "small" ($ftimgsrc.Resize $smallw) }}
            {{ else }}
                {{ $data.Set "small" ($ftimgsrc.Resize $originw) }}
            {{ end }}
            {{ if ge $ftimgsrc.Width 960 }}
                {{ $data.Set "medium" ($ftimgsrc.Resize $mediumw) }}
            {{ else }}
                {{ $data.Set "medium" ($ftimgsrc.Resize $originw) }}
            {{ end }}
            {{ if ge $ftimgsrc.Width 1920 }}
                {{ $data.Set "large" ($ftimgsrc.Resize $largew) }}
            {{ else }}
                {{ $data.Set "large" ($ftimgsrc.Resize $originw) }}
            {{ end }}
        
            {{ $small := $data.Get "small" }}
            {{ $medium := $data.Get "medium" }}
            {{ $large := $data.Get "large" }}

        <source media="(max-width: 480px)" 
                srcset="{{with $medium.RelPermalink }}{{.}}{{ end }} 2x,
                        {{with $small.RelPermalink }}{{.}}{{ end }}"
                type="image/webp">

        <source media="(max-width: 834px)" 
                srcset="{{with $large.RelPermalink }}{{.}}{{ end }} 2x,
                        {{with $medium.RelPermalink }}{{.}}{{ end }}"
                type="image/webp">

        <source media="(min-width: 835px)" 
                srcset="{{with $large.RelPermalink }}{{.}}{{ end }} 2x,
                        {{with $medium.RelPermalink }}{{.}}{{ end }}"
                type="image/webp">

        {{ end }}

        <img
        src="{{ $ftimgsrc.Permalink | safeURL }}"
        alt="{{ .Title }}"
        decoding="async"
        {{ if or ($isJPG) ($isJPEG) ($isPNG) }}width="{{ $ftimgsrc.Width }}"
        height="{{ $ftimgsrc.Height }}"{{ end }}
        loading="eager" 
        fetchpriority="high">
    </picture>
    </div>
{{ end }}

It work great across few of my sites that you can find here.

2 Likes