Skip to content

Convert images to optimized formats#50

Merged
rkoopmans merged 139 commits into
tinify:masterfrom
wcreateweb:task/format-conversion
Jul 9, 2025
Merged

Convert images to optimized formats#50
rkoopmans merged 139 commits into
tinify:masterfrom
wcreateweb:task/format-conversion

Conversation

@tijmenbruggeman

@tijmenbruggeman tijmenbruggeman commented Apr 17, 2025

Copy link
Copy Markdown
Collaborator

With file conversion enabled customers can choose to generate an additional image in a modern format. WebP and AVIF are known to produce a better quality and performance image. Unfortunately, not all browsers support it 100% so therefor we choose to supply it as an addition instead of replacing the image.

  • We will convert using Tinify API/SDK after the image has been compressed.
  • The converted image is set in a picture element when it exists.

Changes

  • Added a setting to enable/disable conversion. When enabled, the user can choose between:
    • Lowest amount of kb. Our recommendation. This will send both the avif and webp parameter to the Tinify API. Tinify will decide wether to return AVIF or WebP.
    • AVIF
    • Webp
  • Changed the API request to Tinify (both through SDK and the API). If conversion is enabled, it will do an additional request to Tinify to retrieve the converted images. Thus it wil cost an additional "compression" and more disk space.
    • We've added a hint that the disk space will also increase when enabling this feature.
  • Added a new class Tiny_Picture. If conversion is enabled, this class will be instantiated and hooked into template_redirect (https://developer.wordpress.org/reference/hooks/template_redirect/). This will parse the page and read all images from the page. For each image, it will check if the disk contains a WebP or AVIF on the same location. If any, it will create a picture element and add the WebP/AVIF sources as a source attribute.
  • Split up statistics to show compression only. Currently conversion is new so the amount saved is still based on compression vs original.
  • Renamed some statistics variables to be more explicit on what is optimized.
  • Added a check to see if width / height was actually a value of resize_options in class-tiny-compress.php:195. This would cause warnings in the customers' UI. This went unnoticed because we previously uploaded files and didn't need the ID of the recently uploaded file.
  • Improved stability and speed of integration tests by clearing the media library through an AJAX/PHP request instead of going through the UI. This was done by adding a AJAX hook in our fixture and calling that before each test.

Screenshots

The settings screen will show the options for conversion
The settings screen will show the options for conversion.

The media library list view ill show compression and conversions. Conversions are hidden if the conversion setting is disabled
The media library list view ill show compression and conversions. Conversions are hidden if the conversion setting is disabled

Show image statistics for conversion.
Show image statistics for conversion..

Image statistics when conversion is disabled
Image statistics when conversion is disabled.

The image source is replaced by a picture element with the sources as attribute
The image source is replaced by a picture element with the sources as attribute

Further Improvements

Below are further improvements we can make on this feature. Discussion is open to see if these are all could haves or if some of them are must haves.

  • Bulk generate optimized formats for all ungenerated images
  • Add htaccess rules in addition to picture elements
  • Generate webp/avif for theme provided images.
  • Add option to replace original image
  • CDN/WP Offload support

- Add support for output format selection (smallest, webp, avif)
- Remove force: true from checkbox interactions for more reliable tests
- Improve setConversionSettings function to handle different conversion formats
- Add switch statement to handle output format radio button selection
- Add output: 'smallest' parameter to setConversionSettings call
- Ensures test uses the smallest file format conversion option
- Improves test clarity by being explicit about conversion settings
- Fix bulk optimization logic to include already compressed images that need conversion
- Update available-for-optimization array to consider both compression and conversion needs
- Enhance bulk optimization JavaScript to properly display compression and conversion results
- Add comprehensive test for conversion-only optimization scenario

This ensures that when conversion is enabled, bulk optimization will process:
1. Uncompressed images (compression + conversion)
2. Already compressed images that need conversion (conversion only)

Previously, already compressed images were excluded from bulk optimization
even when they needed conversion, causing incomplete optimization runs.
…ompression

- Change 'activated for compression' to 'activated for optimization'
- Change 'is compressed' to 'is optimized' in size count messages
- Better reflects that bulk optimization now handles both compression and conversion
- Improves user understanding of the feature scope
- Fix available-for-optimization condition to check both uncompressed and unconverted sizes
- Separate uncompressed and unconverted size filtering when conversion is enabled
- Ensure compressed images can still be converted when conversion feature is toggled on
- Update test to properly verify optimization statistics with conversion scenarios
- Add test coverage for compressed images being eligible for conversion

This resolves issues where already compressed images weren't being converted
when users enabled the conversion feature after initial compression.
Rename 'usage' parameter to 'compressions_used' in estimate_cost method
to better reflect its purpose and improve code readability.
- Move Tiny_Picture initialization to init() method for better lifecycle management
- Extract get_estimated_bulk_cost() method from render_bulk_optimization_page()
  to improve code organization and testability
- Add comprehensive unit tests for bulk cost estimation scenarios:
  - Basic cost calculation without conversion
  - Cost calculation with format conversion enabled
- Improve code readability and maintainability
- Add tests for plugin initialization and configuration
- Improve test structure and assertions
- Expand test cases to cover more functionality
- Add estimated_credit_use statistic to track compression credits needed
- Update cost calculation to use accurate credit estimates instead of simple multiplication
- Handle conversion scenarios properly:
  * Uncompressed images needing compression + conversion = 2 credits each
  * Compressed images needing only conversion = 1 credit each
- Fix null handling for tiny_meta_value in bulk optimization statistics
- Update tests to reflect accurate credit calculations and expectations

This change provides more precise cost estimates for bulk optimization by
tracking actual credit usage based on image compression and conversion states.
@rkoopmans
rkoopmans merged commit 4b36224 into tinify:master Jul 9, 2025
9 checks passed
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

Successfully merging this pull request may close these issues.

3 participants