WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10k stars 4.02k forks source link

Tracking: Client-side media processing #61447

Open swissspidy opened 2 months ago

swissspidy commented 2 months ago

This is something that was previously mentioned in #55106 and has been heavily explored in Media Experiments already (see for example this blog post for an overview of the latter). I believe the core logic at the heart of Media Experiments is a great foundation to implement such a feature, and Gutenberg is the right place to further develop it and bring it to more people.


Overview

Current image processing in WordPress relies on server-side resources and older image libraries, leading to potential performance issues and limited support for modern image formats such as AVIF. This results in a subpar user experience, particularly with resource-intensive tasks like resizing and compressing images. Additionally, the lack of modern compression tools like MozJPEG further hinders optimization efforts.

Client-side media processing offers a solution by leveraging the browser's capabilities to handle tasks like image resizing and compression. This approach not only alleviates the strain on server resources but also enables the use of more advanced image formats and compression techniques, ultimately improving website performance and user experience. By tapping into technologies like WebAssembly, WordPress can provide a more efficient and seamless media handling process for both new and existing content.

Resources

Roadmap

Given the many possibilities client-side media processing unlocks, this project can be split into multiple phases, each with their dedicated goals and success criteria. For example:

Phase 1

Goals

Nice to have

Non-goals

Phase 2

Goals

Nice to have

Non-goals

Phase 3

Goals

Nice to have

Caveats and risks

Technical complexity

WASM-based image optimization requires SharedArrayBuffer support, which in turn requires cross-origin isolation. Implementing that in a robust way without breaking other parts of the editor is challenging. There are currently some known issues in Firefox and Safari due to these browsers not supporting credentialless iframe embeds. Embed previews in the editor currently do not work because of this, until those browsers add support for <iframe credentialless>.

Image compression by itself is rather complex due to the vast amount of different combinations of codecs and encoding options available. While the existing server-side image handling in WordPress has been proven over many years, doing everything client-side is new territory. There will be many edge cases that need to be handled.

As for overall architecture design, the existing Media Experiments project contains a very solid foundation that already solves many challenging problems and could be built upon.

Confidence level

Reception in the community so far has been extremely positive, including from WordPress leadership. There is clearly a desire for this kind of solution.

The biggest risk is about compatibility with other parts of the editor (plugins, embed previews) and certain environments because of the cross-origin isolation required for SharedArrayBuffer. Not breaking existing sites is very important. The risk can be mitigated through extensive testing, additional safeguards, and documentation. Lack of <iframe credentialless> support is not ideal as it degrades editor UX in some cases, but it does not break the authoring experience as a fallback exists.

While image optimization could theoretically be done through other means such as the canvas API, said API is extremely limited across browsers. For example, there is a lack of support for compression options (e.g. lossless or lossy) and mime types (no AVIF everywhere, no WebP in Safari).

ramonjd commented 1 month ago

Firstly, thanks so much for the detail and all the background work!

Converting HEIC images to a web-safe format

This came up in a recent discussion I was having.

What's your take on the level of effort to integrate this feature? I was browsing the media experiments repo code and was wondering if there were any further considerations, beyond what you've explored already.

It would be a fantastic feature to have - happy to have a shot at it, or try to organize someone to have a shot at it πŸ˜„ if you think it's worth it at this stage. I'll take your guidance.

Thank you!

swissspidy commented 1 month ago

I heard of similar discussions recently :)

Always great to hear interest in this kind of topic. And I am glad you already browsed the media experiments code a little bit.

If you are interested solely in HEIC conversion, it by itself could be implemented relatively easily in theory. See #61861 as a demonstration.

However, as with everything else mentioned in this ticket, there are some important aspects to consider. For instance:

And perhaps most importantly: libheif-js and the underlying libheif license is licensed under LGPL 3.0, which is incompatible with GPL v2, but is compatible with GPL v3. Given that WordPress is licensed under GPLv2 or later, it would mean that the final product would need to be distributed under GPL v3 only. IANAL, but I don't think this is gonna fly. So that means an alternative to libheif-js needs to be first evaluated and tested. There are some libraries built on libavif but I haven't had success using those in the past.

(Edit: dynamically linking via loading libheif-js from an externally hosted script might be OK, but again, not a lawyer)

➑️ Aside: Thanks to this POC PR I discovered that the current license check in this repo is broken 😬 I am fixing it in #61868

Bottom line:

I've deliberately split this project into multiple phases as it's more complex than what it might seem on the surface. I strongly suggest tackling this step by step.

Happy to discuss HEIC itself separately elsewhere.

noisysocks commented 1 month ago

Thanks for going into detail Pascal! I like your idea of a "Would you like to convert this to a web safe format?" modal that teaches the user what's going on. I've asked Automattic's legal team for some non-IANAL guidance about libheif.

I think supporting HEIC is the most important outcome here. You encounter these files more and more nowadays and it's very frustrating to users when they don't "just work" in WordPress. I'd push for starting with HEIC support and then expanding on that into other areas (compression, resizing, converting GIFs, etc.)

ramonjd commented 1 month ago

Given that WordPress is licensed under GPLv2 or later, it would mean that the final product would need to be distributed under GPL v3 only. IANAL, but I don't think this is gonna fly.

That's what I'm reading from https://www.gnu.org/licenses/gpl-faq.html#gpl-compat-matrix β€” if WordPress uses code under LGPLv3, then the "combined" work (WordPress + lib) would then fall under the terms of GPLv3

Bit of a wild suggestion, but is there a chance we could fallback to backend processing via Imagick: https://imagemagick.org/script/formats.php#supported

I say "wild" as I assume HEIC files can be pretty massive, and batching would be pricey in terms of performance.

So that means an alternative to libheif-js needs to be first evaluated and tested. There are some libraries built on libavif but I haven't had success using those in the past.

https://www.npmjs.com/package/heic2any or https://github.com/MaestroError/php-heic-to-jpg (both MIT) might also be worth a looksy 🀷🏻

I've asked Automattic's legal team for some non-IANAL guidance about libheif.

Best answer. πŸ˜„

swissspidy commented 1 month ago

Thanks for going into detail Pascal! I like your idea of a "Would you like to convert this to a web safe format?" modal that teaches the user what's going on.

Cool. I'm going to implement it in my plugin soon so we can see how well it works UX-wise.

For WCEU I plan on working on a POC for bringing parts of that plugin to Gutenberg.

I think supporting HEIC is the most important outcome here. You encounter these files more and more nowadays and it's very frustrating to users when they don't "just work" in WordPress. I'd push for starting with HEIC support and then expanding on that into other areas (compression, resizing, converting GIFs, etc.)

Not sure I agree with this one. Performance issues due to too large & heavy images are quite widespread. HEIC is mostly an iPhone thing and not everyone uses those.

As long as there are legal question marks anyway, I'd recommend focusing on server-side HEIC conversion in CORE-53645.

npmjs.com/package/heic2any or MaestroError/php-heic-to-jpg (both MIT) might also be worth a looksy 🀷🏻

heic2any uses the same libheif library under the hood and the usage would be exactly the same, so the MIT license there seems incorrect to me.

php-heic-to-jpg only works server-side and requires an executable file on the server, which is not suitable for WP. For server-side support I recommend focusing on ImageMagick support in CORE-53645.

noisysocks commented 1 month ago

As long as there are legal question marks anyway, I'd recommend focusing on server-side HEIC conversion in CORE-53645.

I agree. Thanks @swissspidy, sorry for derailing your issue here with talk of HEIC πŸ˜€