Skip to content

Commit

Permalink
[FEATURE] Add native browser lazy loading for images
Browse files Browse the repository at this point in the history
This change adds the browser-native lazy loading option "loading"
HTML attribute for images.

See https://addyosmani.com/blog/lazy-loading/ for more details.

Resolves: #90426
Releases: master
Change-Id: I5c457ed5b72ef81622e5135f182d7b10ededd4df
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63317
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Christian Eßl <indy.essl@gmail.com>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Christian Eßl <indy.essl@gmail.com>
Reviewed-by: Benni Mack <benni@typo3.org>
  • Loading branch information
bmack committed Feb 20, 2020
1 parent e89a057 commit 8c06d87
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 1 deletion.
@@ -0,0 +1,39 @@
.. include:: ../../Includes.txt

========================================================
Feature: #90426 - Browser-native lazy loading for images
========================================================

See :issue:`90426`

Description
===========

TYPO3 now supports the browser-native `loading` HTML attribute in :html:`<img>` tags.

It is set to "lazy" by default for all images within Content Elements rendered
with Fluid Styled Content. Supported browsers then choose to load these
images at a later point when the image is within the browsers' Viewport.

The configuration option is available via TypoScript constants and
can be easily adjusted via the TypoScript Constant Editor in the Template module.

Please note that not all browsers support this option yet, but adding
this property will just be skipped for unsupported browsers.


Impact
======

TYPO3 Frontend now renders images in content elements with the "loading=lazy"
attribute by default when using TYPO3's templates from Fluid Styled Content.

Using the TypoScript constant `styles.content.image.lazyLoading`,
the behavior can be modified generally to be either set to `eager`,
`auto` or to an empty value, removing the property directly.

The Fluid ImageViewHelper has the possibility to set this option
via `<f:image src="{fileObject}" treatIdAsReference="true" loading="lazy">`
to hint the browser on how the prioritization of image loading should be used.

.. index:: Frontend, ext:fluid_styled_content
1 change: 1 addition & 0 deletions typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php
Expand Up @@ -114,6 +114,7 @@ public function initializeArguments()
$this->registerTagAttribute('ismap', 'string', 'Specifies an image as a server-side image-map. Rarely used. Look at usemap instead', false);
$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->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);
Expand Down
4 changes: 4 additions & 0 deletions typo3/sysext/fluid/Classes/ViewHelpers/MediaViewHelper.php
Expand Up @@ -86,6 +86,7 @@ public function initializeArguments()
$this->registerArgument('height', 'string', 'This can be a numeric value representing the fixed height in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.');
$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.');
}

/**
Expand Down Expand Up @@ -157,6 +158,9 @@ protected function renderImage(FileInterface $image, $width, $height, ?string $f
$this->tag->addAttribute('src', $imageUri);
$this->tag->addAttribute('width', $processedImage->getProperty('width'));
$this->tag->addAttribute('height', $processedImage->getProperty('height'));
if (in_array($this->arguments['loading'] ?? '', ['lazy', 'eager', 'auto'], true)) {
$this->tag->addAttribute('loading', $this->arguments['loading']);
}

$alt = $image->getProperty('alternative');
$title = $image->getProperty('title');
Expand Down
Expand Up @@ -18,6 +18,7 @@ lib.contentElement {
settings {
defaultHeaderType = {$styles.content.defaultHeaderType}
media {
lazyLoading = {$styles.content.image.lazyLoading}
popup {
bodyTag = <body style="margin:0; background:#fff;">
wrap = <a href="javascript:close();"> | </a>
Expand Down
Expand Up @@ -17,6 +17,9 @@ styles.content {
# cat=content/parseFunc/a0; type=string; label=List of allowed HTML tags when rendering RTE content
allowTags = a, abbr, acronym, address, article, aside, b, bdo, big, blockquote, br, caption, center, cite, code, col, colgroup, dd, del, dfn, dl, div, dt, em, font, footer, header, h1, h2, h3, h4, h5, h6, hr, i, img, ins, kbd, label, li, link, meta, nav, ol, p, pre, q, s, samp, sdfield, section, small, span, strike, strong, style, sub, sup, table, thead, tbody, tfoot, td, th, tr, title, tt, u, ul, var

# 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/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
Expand Down
@@ -1,3 +1,3 @@
<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}" />
<f:media class="image-embed-item" file="{file}" width="{dimensions.width}" height="{dimensions.height}" alt="{file.alternative}" title="{file.title}" loading="{settings.media.lazyLoading}" />
</html>

0 comments on commit 8c06d87

Please sign in to comment.