/t3x-nr-image-optimize

The nr_image_optimize extension for TYPO3 optimizes images and provides ViewHelpers for responsive image handling.

Primary LanguagePHPGNU General Public License v3.0GPL-3.0

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