Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: more aggressive feature flags #2244

Open
LGFae opened this issue May 26, 2024 · 4 comments
Open

Proposal: more aggressive feature flags #2244

LGFae opened this issue May 26, 2024 · 4 comments

Comments

@LGFae
Copy link

LGFae commented May 26, 2024

Hello. I've used image extensively in numerous projects. In most of them, I only needed to decode an image into a series of pixels. This means I only needed the decode functionality from the image crate. Everything else (most noticeably, encoding and imageops), was superfluous.

I would like to be able to select the precise functionality (decode and/or encode) I need from image. This would entail creating a lot more features flags than image currently has.

The main advantage this would bring is a decrease in dependencies, and sub-sequentially compilation times. image is often the most time-consuming crate to compile in my projects, though I can sometimes work around that by only enabling a few formats I care about.

The main disadvantage is that it would be a lot of work, and it might hurt readability/maintainability with all these #[cfg] annotations thrown everywhere.

Draft

If this is accepted, I would suggesting starting as simple as possible. Just annotating the top level image crate with encode and decode features for each image format. It would be a lot of work, but (from what I can tell) mostly simple, grunt-like stuff.

Of course, ideally, we would like to have these flags all the way upstream (so, for example, the gif crate should also have an encode and decode flag). But I believe we can do that in small steps after we've patched image itself.

Furthermore, I believe an imageops feature flags could also be created, though that may be rendered useless if #2238 is addressed.

Finally, note this would be a breaking change downstream, since anyone who's using default-features=false would have to rework their Cargo.toml. Overall, I believe it would be a simple fix, and still worth it.

@fintelia
Copy link
Contributor

fintelia commented May 26, 2024

I took a look at the build timings for this crate, and one thing that stood out was that about 3/4 of total compilation time was consumed by only a few features:

  • webp - which is fixed by Switch to quick-error image-webp#67 (and will be included in the next image-webp release)
  • avif - which actually already only enables AVIF encoding (decoding is behind an additional flag because it needs a C dependency)
  • rayon - not encode/decode specific, just enables some helper methods that use rayon
  • exr - external crate with combined encoding/decoding functionality (and no features to separate them)

@LGFae
Copy link
Author

LGFae commented May 26, 2024

Indeed, just removing avif and rayon gave me roughly 20s faster --release compile times, and reduced my dependencies in Cargo.lock by more than 400 lines.

@WorikWork
Copy link

The main advantage this would bring is a decrease in dependencies, and sub-sequentially compilation times

For me the advantage stops at "decrease in dependencies"

I am looking to create a software that I deploy on my public facing (very valuable to me) production server. I want as few dependencies as I can get.

I came here browsing crates that can help me (scaling Jpeg/PNG and or stitching Jpeg/PNG) and a very important criterion is the quantity of dependencies.

OT It is a weakness in the Rust ecosystem that it is generally so liberal with pulling in arbitrary crates. It is a nightmare from my perspective as I do not want to expand the attack surface on my server more than I absolutely have to.

Love your work - I fully understand if my requirements do not mesh with yours.

@fintelia
Copy link
Contributor

This split likely wouldn't decrease the number of dependencies by very much. The reason is that generally we use the same crate for both encoding and decoding. And even within those crates, a lot of the dependencies will be shared. Compression libraries generally provide both compression and decompression code paths, checksums are the same whether you're writing or validating, etc.

I totally understand where you're coming from in wanting to keep distinct dependencies to an absolute minimum. Given the extremely broad scope of the crate, that's something we unfortunately cannot fully cater towards. We do try to limit to reputable crates and a fair number of dependent crates are actually part of the same image-rs org (and thus don't add anyone new to trust). But that's only one factor to consider. We also care about functionality, performance, robustness, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants