Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/maithemewp/mai-performance-images/archive/refs/heads/develop.zipA WordPress plugin that adds dynamic image loading to the block editor, optimizing image delivery through automatic resizing and WebP conversion.
Description
Mai Performance Images handles image optimization in WordPress by:
- Dynamically resizing images based on viewport size
- Converting images to WebP format
- Processing images in the background
- Supporting lazy loading configuration in the block editor
Installation
- Upload the plugin files to
/wp-content/plugins/mai-performance-images - Activate the plugin through the WordPress admin interface
- Images will automatically be processed when loaded through supported blocks
Requirements
- WordPress 6.7+
- PHP 8.2+
Development
Namespace Prefixing with Strauss
This plugin uses Strauss to prefix the deliciousbrains/wp-background-processing library to avoid namespace conflicts. The prefixed code is stored in the vendor-prefixed/ directory.
After running composer update, you need to regenerate the prefixed dependencies:
composer prefix-namespaces
This command will:
- Download the Strauss PHAR if needed
- Run Strauss to prefix the configured packages
- Regenerate the Composer autoloader
Note: The prefix-namespaces script is automatically run after composer install and composer update when running in development mode (when dev dependencies are installed). If you're running composer update --no-dev, you'll need to manually run composer prefix-namespaces afterwards.
Extending the Plugin
Creating a Custom Image Handler
You can extend the base Images class to add support for custom blocks or modify existing image handling. Here's an example:
<?php
namespace YourNamespace;
use Mai\PerformanceImages\Images;
class CustomImages extends Images {
/**
* Add hooks.
*
* @since 1.0.0
*
* @return void
*/
protected function hooks(): void {
// Add your custom block filters
add_filter( 'render_block_acf/gallery', [ $this, 'render_acf_gallery_block' ], 99, 2 );
add_filter( 'render_block_custom/image', [ $this, 'render_custom_image_block' ], 99, 2 );
}
/**
* Process an ACF gallery block.
*
* @param string $block_content The block content.
* @param array $block The block data.
*
* @return string
*/
public function render_acf_gallery_block( string $block_content, array $block ): string {
// Bail if no content
if ( ! $block_content ) {
return $block_content;
}
// Get alignment args from parent method
$args = $this->get_alignment_args( $block['attrs']['align'] ?? '' );
// Add custom sizes for gallery
$args['sizes'] = [
'mobile' => '(max-width: 599px) 100vw',
'tablet' => '(max-width: 1199px) 50vw',
'desktop' => 'calc(33.333% - 20px)',
];
// Process each image in gallery
return $this->handle_image( $block_content, $args );
}
/**
* Process a custom image block.
*
* @param string $block_content The block content.
* @param array $block The block data.
*
* @return string
*/
public function render_custom_image_block( string $block_content, array $block ): string {
// Bail if no content
if ( ! $block_content ) {
return $block_content;
}
// Get custom image ID from block attributes
$image_id = $block['attrs']['imageId'] ?? null;
// Get alignment args from parent method
$args = $this->get_alignment_args( $block['attrs']['align'] ?? '' );
// Add image ID to args
$args['image_id'] = $image_id;
// Add custom sizes
$args['sizes'] = [
'mobile' => '90vw',
'tablet' => '80vw',
'desktop' => '1200px',
];
// Process the image
return $this->handle_image( $block_content, $args );
}
}
Registering Your Custom Handler
Add your custom image handler in your theme's functions.php or plugin file:
add_action( 'init', function() {
new \YourNamespace\CustomImages();
}, 20 );
Available Methods
When extending the Images class, you have access to these protected methods:
-
get_alignment_args( string $align ): array- Gets default responsive sizes based on alignment
- Parameters:
$align: Block alignment ('full', 'wide', or default)
- Returns array with
max_widthandsizes
-
handle_image( string $html, array $args ): string- Processes an image tag for responsive loading
- Parameters:
$html: The HTML containing the image tag$args: Configuration array with:max_width: Maximum image widthsrc_width: Width for src attributeimage_id: WordPress attachment IDsizes: Responsive sizes configuration
Built-in Block Support
The plugin automatically handles these core blocks:
core/covercore/imagecore/post-featured-imagecore/media-textcore/site-logo
Advanced Configuration
Available Filters
-
mai_performance_images_image_attributes- Modifies image attributes before processing
- Parameters:
array $attr: Image attributes array containing:src: Source URLsrcset: Responsive image srcsetsizes: Responsive sizes string
array $args: Processing arguments
-
mai_performance_images_quality- Customizes WebP image quality
- Default: 80
add_filter( 'mai_performance_images_quality', function( $quality ) { return 85; // Adjust quality (0-100) });
-
mai_performance_images_max_retries- Controls how many times to retry failed image processing
- Default: 3
add_filter( 'mai_performance_images_max_retries', function( $retries ) { return 5; // Adjust retry attempts });
Debugging
The plugin includes a Logger class that helps with debugging. Enable WordPress debug mode to see logs:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
Basic Auth Configuration
If your site is protected by Basic Auth (e.g., on a staging environment), you'll need to configure the plugin to work with your existing Basic Auth credentials. Add these constants to your wp-config.php:
// Basic Auth credentials for background processing
define( 'MAI_BASIC_AUTH_USERNAME', 'your_existing_username' );
define( 'MAI_BASIC_AUTH_PASSWORD', 'your_existing_password' );
These credentials should match your site's existing Basic Auth configuration. The plugin will use these credentials to authenticate background processing requests.
License
GPL-2.0-or-later