Niels-IO / next-image-export-optimizer

Use Next.js advanced <Image/> component with the static export functionality. Optimizes all static images in an additional step after the Next.js static export.
MIT License
460 stars 56 forks source link

Non-webp fall back? #118

Closed Lastofthefirst closed 1 year ago

Lastofthefirst commented 1 year ago

Thanks again for this great tool.

Testing a site im working on in an old iOS safari doesnt seem to support specifically the transparent webp. Isnt it supposed to fallback to the original image if webp isnt supported? If not is there anyway to configure that?

Niels-IO commented 1 year ago

Hey @Lastofthefirst

Yes that should be the behaviour! Could you do me a favour and test how the standard Next.js image component behaves in this case?

Lastofthefirst commented 1 year ago

Do I understand right that you mean to try using the default image component from next and have a jpg or png as well as some webp in the srcset? Then test on this iphone?

Also when I examine using the version you've made I don't see any non webp in the srcset:

srcset="/nextImageExportOptimizer/old-paper.d520b480-opt-16.WEBP 16w, /nextImageExportOptimizer/old-paper.d520b480-opt-32.WEBP 32w, /nextImageExportOptimizer/old-paper.d520b480-opt-48.WEBP 48w, /nextImageExportOptimizer/old-paper.d520b480-opt-64.WEBP 64w, /nextImageExportOptimizer/old-paper.d520b480-opt-96.WEBP 96w, /nextImageExportOptimizer/old-paper.d520b480-opt-128.WEBP 128w, /nextImageExportOptimizer/old-paper.d520b480-opt-256.WEBP 256w, /nextImageExportOptimizer/old-paper.d520b480-opt-384.WEBP 384w, /nextImageExportOptimizer/old-paper.d520b480-opt-640.WEBP 640w, /nextImageExportOptimizer/old-paper.d520b480-opt-750.WEBP 750w, /nextImageExportOptimizer/old-paper.d520b480-opt-828.WEBP 828w, /nextImageExportOptimizer/old-paper.d520b480-opt-1080.WEBP 1080w, /nextImageExportOptimizer/old-paper.d520b480-opt-1200.WEBP 1200w, /nextImageExportOptimizer/old-paper.d520b480-opt-1920.WEBP 1920w, /nextImageExportOptimizer/old-paper.d520b480-opt-1920.WEBP 2048w, /nextImageExportOptimizer/old-paper.d520b480-opt-1920.WEBP 3840w"
Niels-IO commented 1 year ago

The exportedImage code has an error check that will return the original src in a case the optimized srcset image fails to load.

Regarding the testing: as I think of it, probably it cannot be tested with Next.js image component as they check the supported features of the browser dynamically and return an appropriate image format.

Lastofthefirst commented 1 year ago

The dev console/web inspector for the iOs safari doesnt seem to be working, presumably the iOS safari version is to old. the OS version is just 14.8.1 so not that old... I'm not sure.

Lastofthefirst commented 1 year ago

@Niels-IO sorry to keep bothering you! But now it seems like the behavior I'm getting is the largest version of each image being loaded instead of the smallest for the viewport. Could that be so? Maybe that also would explain the fallback not working (say if files were listed in reverse order, that would cause css to fail at least). Here are two sites I'm testing with: https://ridvan.org https://bahaisofsumtercounty.com

I tried looking at the network tab in incognito to see if I was just observing caching, but behavior seems to be the same. I don't think I changed any settings aside from upgrading to 1.4.0.

Niels-IO commented 1 year ago

Hi @Lastofthefirst Could you share how you defined the ExportedImage component for the images on https://ridvan.org/articles/brown-and-kirk so that I can look into it, please?

Lastofthefirst commented 1 year ago

Here are the images from that page:

<ExportedImage
        src={vid}
        alt="A snapshot of brownandkirk.com."
        useWebp={process.env.nextImageExportOptimizer_storePicturesInWEBP}
        placeholder="blur"
        quality={100}
      />

 <ExportedImage
        src={lighthouse}
        alt="Lighthouse audit results for the website."
        useWebp={process.env.nextImageExportOptimizer_storePicturesInWEBP}
        placeholder="blur"
        quality={100}
      />

Heres the background one as well:

 <div className='overflow-visible'>
    <ExportedImage

          src={stars}
          alt=""
          width="100vw"
          height="auto"
          className="absolute right-0 left-0 -top-10 z-0 pointer-events-none"
          useWebp={process.env.nextImageExportOptimizer_storePicturesInWEBP}
          placeholder="blur"
          loading='lazy'
          quality={75}
        />
    </div>
Niels-IO commented 1 year ago
image

The image in the header seems to be working as expected.

Niels-IO commented 1 year ago

My guess is: As you didn't specify any size behavior, next.js at export time will just produce the next largest width from the imageSizes array that matches the original image width and generates this srcset:

image
Lastofthefirst commented 1 year ago

So we cant auto optimize an image that fills a container? On my computer I think its still sourcing from the largest image for that header:

Screen Shot 2023-03-06 at 5 02 52 PM
Niels-IO commented 1 year ago

When you specify fill, you also have to specify sizes for small images. Otherwise, Next.js will use the viewport width to choose which image to load. So using fill without sizes only makes sense for large images that span the whole viewport width.

This is an example taken from https://nextjs.org/docs/api-reference/next/image:

For example, if you know your styling will cause an image to be full-width on mobile devices, in a 2-column layout on tablets, and a 3-column layout on desktop displays, you should include a sizes property such as the following:

import Image from 'next/image'
const Example = () => (
  <div className="grid-element">
    <Image
      src="/example.png"
      fill
      sizes="(max-width: 768px) 100vw,
              (max-width: 1200px) 50vw,
              33vw"
    />
  </div>
)
Lastofthefirst commented 1 year ago

Ok thanks, I guess I fundamentally misunderstood how this worked. ¯\_(ツ)_/¯

Its still very useful of course, thank you for your help.

Niels-IO commented 1 year ago

I will close this issue because I cannot test the Safari misbehavior.