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.
- π 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.
- PHP 8.2, 8.3, or 8.4
- TYPO3 13.4
- Intervention Image library (installed via Composer automatically)
composer require netresearch/nr-image-optimize
- Download the extension from the TYPO3 Extension Repository
- Upload to
typo3conf/ext/
- Activate the extension in the Extension Manager
The extension works out of the box with sensible defaults. Images are automatically optimized when accessed via the /processed/
path.
{namespace nr=Netresearch\NrImageOptimize\ViewHelpers}
<nr:sourceSet file="{image}"
width="1200"
height="800"
quality="85"
sizes="(max-width: 768px) 100vw, 50vw"
/>
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)
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}
}"
/>
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"
/>
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.
responsiveSrcset
- Type:
bool
- Default:
false
- Description: Enable width-based responsive
srcset
generation 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:
sizes
attribute for responsive images.
- Type:
fetchpriority
- Type:
string
- Allowed values:
high
,low
,auto
- Default:
''
(omitted) - Description: Adds the native HTML attribute
fetchpriority
to the generated<img>
tag to hint the browser about resource prioritization. Any other value will be ignored.
- Type:
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"
/>
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">
- By default,
responsiveSrcset
is set tofalse
, maintaining the existing 2x density-basedsrcset
behavior. - All existing templates will continue to work without modifications.
- To enable the new responsive
srcset
, explicitly setresponsiveSrcset="1"
in your templates.
- Both modes support lazy loading with native
loading="lazy"
attribute. - When using JS-based lazy loading (
class="lazyload"
), thedata-srcset
attribute is added automatically.
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
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
- Images are processed only once and cached
- Supports native browser lazy loading
- Automatic format negotiation based on Accept headers
- Optimized for CDN delivery
GPL-3.0-or-later. See LICENSE file for details.
For issues and feature requests, please use the GitHub issue tracker.
Developed by Netresearch DTT GmbH