netresearch / nr-image-optimize
On-demand image optimization for TYPO3 with processed delivery, WebP and AVIF variants, and responsive srcset ViewHelpers.
Package info
github.com/netresearch/t3x-nr-image-optimize
Type:typo3-cms-extension
pkg:composer/netresearch/nr-image-optimize
Requires
- intervention/image: ^3.11
- typo3/cms-core: ^13.4
- typo3/cms-fluid: ^13.4
Requires (Dev)
- a9f/typo3-fractor: ^0.5
- friendsofphp/php-cs-fixer: ^3.88
- overtrue/phplint: ^9.6
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- saschaegerer/phpstan-typo3: ^2.0
- ssch/typo3-rector: ^3.6
- typo3/testing-framework: ^9.0
Suggests
- christophlehmann/imageoptimizer: Optimize uploaded/processed images with binaries of your choice
This package is auto-updated.
Last update: 2026-03-02 20:15:54 UTC
README
๐ TYPO3 Extension: nr_image_optimize
The nr_image_optimize extension is an advanced TYPO3 extension for image optimization. It provides lazy image processing, modern formats, responsive images, and performance optimizations.
๐จ Features
- ๐ Lazy Image Processing: Images are processed only when requested.
- ๐จ Modern Format Support: WebP and AVIF with automatic fallback.
- ๐ฑ Responsive Images: Built-in ViewHelper for srcset generation.
- โก Performance Optimized: Middleware-based processing for efficiency.
- ๐ง Intervention Image: Powered by the Intervention Image library.
- ๐ Core Web Vitals: Improves LCP and overall page performance.
- ๐งน Backend Cleanup: Remove generated variants via "Remove Temporary Assets" in the TYPO3 Maintenance module.
๐ ๏ธ Requirements
- PHP 8.2, 8.3, or 8.4
- TYPO3 13.4
- Intervention Image library (installed via Composer automatically)
๐ Recommended Extensions
๐พ Installation
Via Composer (recommended)
composer require netresearch/nr-image-optimize
Manual Installation
- Download the extension from the TYPO3 Extension Repository
- Upload to
typo3conf/ext/ - Activate the extension in the Extension Manager
โ๏ธ Configuration
The extension works out of the box with sensible defaults. Images are automatically optimized when accessed via the /processed/ path.
ViewHelper Usage
{namespace nr=Netresearch\NrImageOptimize\ViewHelpers}
<nr:sourceSet file="{image}"
width="1200"
height="800"
quality="85"
sizes="(max-width: 768px) 100vw, 50vw"
/>
Supported Parameters
file: Image file resourcewidth: Target width in pixelsheight: Target height in pixelsquality: JPEG/WebP quality (1-100)sizes: Responsive sizes attributeformat: Output format (auto, webp, avif, jpg, png)
๐ Source Set Configuration
Different source sets can be defined for each media breakpoint via the set attribute:
<nr:sourceSet path="{f:uri.image(image: image, width: '960', height: '690', cropVariant: 'default')}" set="{ 480:{width: 160, height: 90}, 800:{width: 400, height: 300} }" />
๐ผ๏ธ Render Modes
Two render modes are available for the SourceSetViewHelper:
- cover: Default mode, resizes images to fully cover the provided width and height.
- fit: Resizes images so they fit within the provided width and height.
<nr:sourceSet path="{f:uri.image(image: image, width: '960', height: '690', cropVariant: 'default')}" width="960" height="690" mode="fit" />
๐ท Responsive width-based srcset
The extension provides a responsive, width-based srcset generation with a sizes attribute
for improved responsive image handling. This feature is optional and can be enabled per usage.
New Parameters
responsiveSrcset- Type:
bool - Default:
false - Description: Enable width-based responsive
srcsetgeneration instead of density-based (x2)srcset.
- Type:
widthVariants- Type:
string|array - Default:
'480, 576, 640, 768, 992, 1200, 1800' - Description: Width variants for responsive
srcset(comma-separated string or array).
- Type:
sizes- Type:
string - Default:
(max-width: 576px) 100vw, (max-width: 768px) 50vw, (max-width: 992px) 33vw, (max-width: 1200px) 25vw, 1250px - Description:
sizesattribute for responsive images.
- Type:
fetchpriority- Type:
string - Allowed values:
high,low,auto - Default:
''(omitted) - Description: Adds the native HTML attribute
fetchpriorityto the generated<img>tag to hint the browser about resource prioritization. Any other value will be ignored.
- Type:
Usage Examples
Enable responsive srcset with default values:
<nrio:sourceSet path="{f:uri.image(image: image, maxWidth: size, cropVariant: 'default')}" width="{size}" height="{size * ratio}" alt="{image.properties.alternative}" lazyload="1" mode="fit" responsiveSrcset="1" />
Custom width variants:
<nrio:sourceSet path="{f:uri.image(image: image, maxWidth: size, cropVariant: 'default')}" width="{size}" height="{size * ratio}" alt="{image.properties.alternative}" lazyload="1" mode="fit" responsiveSrcset="1" widthVariants="320,640,1024,1920,2560" />
Custom sizes attribute:
<nrio:sourceSet path="{f:uri.image(image: image, maxWidth: size, cropVariant: 'default')}" width="{size}" height="{size * ratio}" alt="{image.properties.alternative}" lazyload="1" mode="fit" responsiveSrcset="1" sizes="(max-width: 640px) 100vw, (max-width: 1024px) 75vw, 50vw" />
Output Comparison
Legacy mode (responsiveSrcset=false or not set):
<img src="/processed/fileadmin/image.w625h250m1q100.jpg" srcset="/processed/fileadmin/image.w1250h500m1q100.jpg x2" width="625" height="250" loading="lazy">
Responsive mode (responsiveSrcset=true):
<img src="/processed/fileadmin/image.w1250h1250m1q100.png" srcset="/processed/fileadmin/image.w480h480m1q100.png 480w, /processed/fileadmin/image.w576h576m1q100.png 576w, /processed/fileadmin/image.w640h640m1q100.png 640w, /processed/fileadmin/image.w768h768m1q100.png 768w, /processed/fileadmin/image.w992h992m1q100.png 992w, /processed/fileadmin/image.w1200h1200m1q100.png 1200w" /processed/fileadmin/image.w1800h1800m1q100.png 1800w" sizes="auto, (min-width: 992px) 991px, 100vw" width="991" loading="lazy" alt="Image">
Backward Compatibility
- By default,
responsiveSrcsetis set tofalse, maintaining the existing 2x density-basedsrcsetbehavior. - All existing templates will continue to work without modifications.
- To enable the new responsive
srcset, explicitly setresponsiveSrcset="1"in your templates.
Lazy Loading
- Both modes support lazy loading with native
loading="lazy"attribute. - When using JS-based lazy loading (
class="lazyload"), thedata-srcsetattribute is added automatically.
๐งช Development & Testing
Unit tests ensure functionality and code quality.
# Run all tests composer ci:test # Run specific tests composer ci:test:php:cgl # Code style composer ci:test:php:lint # PHP syntax composer ci:test:php:phpstan # Static analysis composer ci:test:php:unit # PHPUnit tests composer ci:test:php:rector # Code quality
๐๏ธ Architecture
The extension uses a middleware approach for image processing:
- ProcessingMiddleware: Intercepts requests to
/processed/paths - Processor: Handles image optimization and format conversion
- SourceSetViewHelper: Generates responsive image markup
โก Performance Considerations
- Images are processed only once and cached
- Supports native browser lazy loading
- Automatic format negotiation based on Accept headers
- Optimized for CDN delivery
๐ License
GPL-3.0-or-later. See LICENSE file for details.
๐ Support
For issues and feature requests, please use the GitHub issue tracker.
๐ Credits
Developed by Netresearch DTT GmbH
๐ง Maintenance
Backend Module
The extension provides a backend module for maintenance tasks accessible via Admin Tools โ Processed Images Maintenance.
Features:
- Overview: View statistics about processed images (file count, total size, directory count, largest files, file types distribution)
- System Requirements: Check all technical prerequisites and tool availability:
- PHP version and extensions (Imagick, GD)
- ImageMagick/GraphicsMagick capabilities (WebP, AVIF support)
- Composer dependencies (Intervention Image)
- TYPO3 version compatibility
- CLI tools (magick, convert, identify, gm - optional)
- Clear Processed Images: Remove all on-demand generated images. Images will be regenerated automatically when first accessed again.
Note
After clearing processed images, expect temporarily increased loading times on the frontend until images are regenerated on-demand.