bridgetownrb / bridgetown

A next-generation progressive site generator & fullstack framework, powered by Ruby
https://www.bridgetownrb.com
MIT License
1.13k stars 114 forks source link

feat: image optimization #160

Closed KonnorRogers closed 1 year ago

KonnorRogers commented 3 years ago

Summary

A feature to allow for image optimization

Motivation

To provide better optimized images to the end user and improve browser experience

Guide-level explanation

Add a Bridgetown tag to support modern image formats and optimizations.

For example:

{{ picture "/images/image.png" }}

Will output something like the following:


<picture>
  <source srcset="/images/image.webp" type="image/webp" />
  <source srcset="/images/image.jp2" type="image/jp2" />
  <img src="/images/image.jxr" type="image/vnd.ms-photo" />
</picture>

This is the most full-featured way to embrace modern image formats, however, as proposed at the end of this blog post:

https://joshwcomeau.com/performance/embracing-modern-image-formats/

There are less full-featured but will generally work with all evergreen browsers.

To support this, we would have to add either Sharp or ImageMagick for image conversion.

On top of it, we should also look into possibly copying images to Webpack for caching purposes for production.

Drawbacks

Longer build times due to hashing and image conversion.

Unresolved Questions

Do we make this a part of core or do we make it a new gem / plugin?

Do we allow users to have all their images be optimized and placed in this new image format, or do we have users use a Liquid tag like above.

julianrubisch commented 3 years ago

I think this should be a plugin, and I want it today 😀

andrewmcodes commented 3 years ago

I agree with @julianrubisch mostly based on the longer build times.

Keeping core slim and pushing "power features" into plugins will ensure that we don't garner a bad reputation that's commonly associated with Ruby for no reason and also protect people from opting into behavior that they don't understand.

Sounds super cool and I'm excited to follow progress on this one.

julianrubisch commented 3 years ago

Happy to chime in if desired

jaredcwhite commented 3 years ago

I also agree that it should be a plugin, rather than built-into the main repo. So now that that's settled, who's going to write it? 😁

julianrubisch commented 3 years ago

I don‘t wanna steal this from @ParamagicDev since he apparently already has done a lot of research. But I’m happy to help.

KonnorRogers commented 3 years ago

@julianrubisch go right ahead! I had the thought but no time to implement, I figured it could at least be a roadmap for somebody else.

julianrubisch commented 3 years ago

Did you have a particular gem in mind, then? https://github.com/chrisdwheatley/netlify-plugin-image-optim uses a JS package called imagemin.

KonnorRogers commented 3 years ago

@julianrubisch I was not planning on using a gem, i was actually planning on using Sharp which is an NPM module that uses Libvips under the hood. However I ran into a lot of issues with it with Gatsby so perhaps imagemin may be worth looking at.

julianrubisch commented 3 years ago

Gotcha. Well it produces superb results in the plugin but I don’t know if it supports next gen image formats. I‘ll put it on my todo list... 😅

andrewmcodes commented 3 years ago

@julianrubisch @ParamagicDev I would argue this should actually just be left to JS. I am currently achieving this effect on my site by just running some JS tasks after Bridgetown builds. LMK if I can say more but instead of writing this in ruby, I believe we should instead start focusing on enhancing the Webpack config to be more modular and to run different plugins during dev & production.

jaredcwhite commented 3 years ago

@andrewmcodes Well…there's "automated" image optimization and explicit optimization, and I'm not big on the former personally. I would want to be able to specify in a template the size/quality (or via a shorthand that's configured elsewhere, like "thumbnail" or "banner", etc.), and get the relevant processed image URL rather than the source URL. I don't know how we'd do that via JS, unless it's something that processes the output HTML looking for clues?

jaredcwhite commented 3 years ago

And now I'm realizing that wish isn't actually captured in the initial issue description… OK, maybe we're talking about different things. All I want is Cloudinary without the sign-up-and-use-Cloudinary part. 😝

andrewmcodes commented 3 years ago

@jaredcwhite lol thx for following up bc your comment sent me down a completely different direction.

Just to be clear: you aren't talking about a service to create social images like og-image, right?

You mean something like imagemin-mozjpeg or imageoptim?

jaredcwhite commented 3 years ago

Yeah, like if foo.jpg is a 6000w pixel 10MB monstrosity and I only need a 1600w pixel 200KB file, it'd be great to get that generated as part of the build process somehow.

jaredcwhite commented 3 years ago

(without of course overwriting the original source file)

jaredcwhite commented 3 years ago

Some prior art: https://www.npmjs.com/package/eleventy-plugin-sharp-respimg

julianrubisch commented 3 years ago

FWIW, started development here: https://github.com/julianrubisch/bridgetown-media-optimization

sandstrom commented 1 year ago

I'm doing some issue gardening 🌱🌿 🌷 and came upon this issue. I'd vote for closing it, since this likely shouldn't be in core anyway (it would be a third-party plugin, such as the one linked above).

By closing some old issues we reduce the list of open issues to a more manageable set.