imaginary icon indicating copy to clipboard operation
imaginary copied to clipboard

type=auto yields poor transformations for Safari

Open mharen opened this issue 5 years ago • 3 comments

We're running into an issue where I think Imaginary is technically doing the correct thing, but it's not what I want. I serve lots of jpgs and occasionally some pngs. I want to serve webp images to devices that support webp, and jpgs or pngs to everyone else.

If I use type=auto I get what I want in Chrome. Chrome has this accept header: image/webp,image/apng,image/*,*/*;q=0.8. I.e. Chrome gets webp.

But in Safari (and IE, Edge), everything gets converted to a png, which increases the file size of my jpgs by 2-4x. Safari's accept header is accept: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5.

Do you have any advice for adjusting my Imaginary config to handle Safari better?

mharen avatar Jul 14 '20 15:07 mharen

Just ran into the same issue.

I think in the long term a type=compression would be nice, where imaginary would try the headers in the order of compressibility. For now you might just check for the user-agent yourself and explicitly set the type to jpeg if the user is running Safari or IE11...

zeemawn avatar Aug 04 '20 07:08 zeemawn

Or even make the parameter support multiple formats, ordered like type=webp,jpeg

zeemawn avatar Aug 04 '20 07:08 zeemawn

In the meantime, you can workaround this by using a proxy/router service in front of imaginary (such as nginx, caddy or skipper). They would peek at the accept header to match some pattern(s) or other logic to decide what format to request from imaginary explicitly (rather than relying on the auto).

You can for example check if webp exists and request that, otherwise request jpg.

If the accept header doesn't provide the format such as webp, you cannot assume the browser supports it (could be an older version of safari that hasn't been updated and lacks webp support). You could conditionally also check another header like User-Agent I guess.

Beyond that, using the <picture> element works well at providing the sources you want to support and your preference, and the browser will request what it knows it can support.


The maintainer did seem to suggest the same multi-value type parameter here though (around the same time): https://github.com/h2non/imaginary/issues/309#issuecomment-665291307

polarathene avatar Aug 21 '21 08:08 polarathene