Commit c0e99719 authored by Chris Müller's avatar Chris Müller Committed by Benni Mack
Browse files

[FEATURE] Add decoding attribute to images

This change adds the decoding attribute to images. For better rendering
performance the default value is set to "async" (which decodes images
in content elements asynchronously from the main rendering thread).

See also: https://html.spec.whatwg.org/multipage/images.html#decoding-images

Resolves: #93908
Releases: master
Change-Id: I6e8f3985b9ab60de5cf203c36295be29eb6e876c
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68764


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: default avatarGuido Schmechel <guido.schmechel@brandung.de>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: default avatarGuido Schmechel <guido.schmechel@brandung.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 10bcd26c
.. include:: ../../Includes.txt
==================================================
Feature: #93908 - Add decoding attribute to images
==================================================
See :issue:`93908`
Description
===========
TYPO3 now supports the `decoding` HTML attribute in :html:`<img>`
tags.
Supported browsers then choose to decode these images asynchronously to not
prevent presentation of other content. This has an effect of presenting
non-image content faster. However, the image content is missing on screen until
the decode finishes. Once the decode is finished, the screen is updated with the
image.
The configuration option is available via TypoScript constants and
can be easily adjusted via the TypoScript Constant Editor in the Template
module. The default value is "".
Impact
======
TYPO3 Frontend now decodes images in content elements asynchronously by default
when using TYPO3's templates from Fluid Styled Content.
Using the TypoScript constant `styles.content.image.imageDecoding`,
the behavior can be modified generally to be either set to `sync`, `async`
`auto` or to an empty value which removes the property.
The Fluid ImageViewHelper and MediaViewHelper have the possibility to set this
attribute via :html:`<f:image src="{fileObject}" treatIdAsReference="true" decoding="async">`
and :html:`<f:media file="{fileObject}" decoding="async">`.
.. index:: Frontend, ext:fluid_styled_content
......@@ -120,6 +120,7 @@ class ImageViewHelper extends AbstractTagBasedViewHelper
$this->registerTagAttribute('longdesc', 'string', 'Specifies the URL to a document that contains a long description of an image', false);
$this->registerTagAttribute('usemap', 'string', 'Specifies an image as a client-side image-map', false);
$this->registerTagAttribute('loading', 'string', 'Native lazy-loading for images property. Can be "lazy", "eager" or "auto"', false);
$this->registerTagAttribute('decoding', 'string', 'Provides an image decoding hint to the browser. Can be "sync", "async" or "auto"', false);
$this->registerArgument('src', 'string', 'a path to a file, a combined FAL identifier or an uid (int). If $treatIdAsReference is set, the integer is considered the uid of the sys_file_reference record. If you already got a FAL object, consider using the $image parameter instead', false, '');
$this->registerArgument('treatIdAsReference', 'bool', 'given src argument is a sys_file_reference record', false, false);
......
......@@ -88,6 +88,7 @@ class MediaViewHelper extends AbstractTagBasedViewHelper
$this->registerArgument('cropVariant', 'string', 'select a cropping variant, in case multiple croppings have been specified or stored in FileReference', false, 'default');
$this->registerArgument('fileExtension', 'string', 'Custom file extension to use for images');
$this->registerArgument('loading', 'string', 'Native lazy-loading for images property. Can be "lazy", "eager" or "auto". Used on image files only.');
$this->registerArgument('decoding', 'string', 'Provides an image decoding hint to the browser. Can be "sync", "async" or "auto"', false);
}
/**
......@@ -166,6 +167,9 @@ class MediaViewHelper extends AbstractTagBasedViewHelper
if (in_array($this->arguments['loading'] ?? '', ['lazy', 'eager', 'auto'], true)) {
$this->tag->addAttribute('loading', $this->arguments['loading']);
}
if (in_array($this->arguments['decoding'] ?? '', ['sync', 'async', 'auto'], true)) {
$this->tag->addAttribute('decoding', $this->arguments['decoding']);
}
$alt = $image->getProperty('alternative');
$title = $image->getProperty('title');
......
......@@ -19,6 +19,7 @@ lib.contentElement {
defaultHeaderType = {$styles.content.defaultHeaderType}
media {
lazyLoading = {$styles.content.image.lazyLoading}
imageDecoding = {$styles.content.image.imageDecoding}
popup {
bodyTag = <body style="margin:0; background:#fff;">
wrap = <a href="javascript:close();"> | </a>
......
......@@ -20,7 +20,10 @@ styles.content {
# cat=content/cImage/a0; type=options[lazy,eager,auto,]; label=Default settings for browser-native image lazy loading: Can be "lazy" (browsers could choose to load images later), "eager" (load images right away) or "auto" (browser will determine whether the image should be lazy loaded or not)
image.lazyLoading = lazy
textmedia {
# cat=content/cImage/a1; type=options[sync,async,auto,]; label=Default settings for an image decoding hint to the browser: Can be "sync" (synchronously for atomic presentation with other content), "async" (asynchronously to avoid delaying presentation of other content), "auto" (no preference in decoding mode) or an empty value to omit the usage of the decoding attribute (same as "auto")
image.imageDecoding =
textmedia {
# cat=content/cTextmedia/b1; type=int+; label= Max Image/Media Width: This indicates that maximum number of pixels (width) a block of media elements inserted as content is allowed to consume
maxW = 600
# cat=content/cTextmedia/b2; type=int+; label= Max Image/Media Width (Text): Same as above, but this is the maximum width when text is wrapped around an block of media elements. Default is 50% of the normal Max Media Item Width
......
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:media class="image-embed-item" file="{file}" width="{dimensions.width}" height="{dimensions.height}" alt="{file.alternative}" title="{file.title}" loading="{settings.media.lazyLoading}" />
<f:media class="image-embed-item" file="{file}" width="{dimensions.width}" height="{dimensions.height}" alt="{file.alternative}" title="{file.title}" loading="{settings.media.lazyLoading}" decoding="{settings.media.imageDecoding}" />
</html>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment