netresearch/nr-image-optimize

Add capability to optimize the delivered images to benefit from better compression and smaller image size. This extension also add the ability to process images only if it is really requested.

Installs: 59

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 1

Type:typo3-cms-extension

2.1.0 2025-09-18 10:58 UTC

README

php typo3 license ci release

๐Ÿš€ 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.

๐Ÿ› ๏ธ 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

  1. Download the extension from the TYPO3 Extension Repository
  2. Upload to typo3conf/ext/
  3. 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 resource
  • width: Target width in pixels
  • height: Target height in pixels
  • quality: JPEG/WebP quality (1-100)
  • sizes: Responsive sizes attribute
  • format: 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 srcset generation instead of density-based (x2) srcset.
widthVariants
  • Type: string|array
  • Default: '480, 576, 640, 768, 992, 1200, 1800'
  • Description: Width variants for responsive srcset (comma-separated string or array).
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.
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.

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, responsiveSrcset is set to false, maintaining the existing 2x density-based srcset behavior.
  • All existing templates will continue to work without modifications.
  • To enable the new responsive srcset, explicitly set responsiveSrcset="1" in your templates.

Lazy Loading

  • Both modes support lazy loading with native loading="lazy" attribute.
  • When using JS-based lazy loading (class="lazyload"), the data-srcset attribute 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:

  1. ProcessingMiddleware: Intercepts requests to /processed/ paths
  2. Processor: Handles image optimization and format conversion
  3. 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