Image Lazyloading
To reduce server load and speed up page requests, LUYA is shipped with a built in luya\lazyload\LazyLoad widget. You can use the Lazyload widget in 3 different ways:
Basic usage
This just displays a grey area instead of the image while loading.
The basic usage already provides a no-script fallback.
<?= LazyLoad::widget([
'src' => $this->publicHtml . '/path/to/image',
'width' => 'the-image-width-in-px',
'height' => 'the-image-height-in-px',
'extraClass' => 'custom-classes'
]);
?>
With smaller preview
Display a smaller preview of the image while loading the bigger version.
The plugin doesn't need any width or height informations in this mode, but the smaller image should have the same dimension.
For example: The original file has a resolution of 100x100 pixel, the smaller version should have 10x10, 20x20 or 30x30 pixel.
Based on what styles you apply to your image (custom-classes
) this might work or not. You can try to update the placeholder image styles by using its class and your custom class: .custom-classes .lazyimage-placeholder-image
Includes a noscript fallback. Make sure to implement a
nojs
orno-js
class into youbody
orhtml
tag.
<?= LazyLoad::widget([
'src' => $this->publicHtml . '/path/to/image',
'placeholderSrc' => $this->publicHtml . '/path/to/image_very_small',
'extraClass' => 'custom-classes'
]);
?>
Tip: If you use LUYA Admin you can let the LUYA Filters do the work for you.
Base64 encode
To enable base64 encoding of your placeholder image, you have to make sure that your placeholderSrc is an absolute URL and then set placeholderAsBase64
to true
.
<?= LazyLoad::widget([
'src' => $this->publicHtml . '/path/to/image',
'placeholderSrc' => $this->publicHtml . '/path/to/image_very_small',
'placeholderAsBase64' => true,
'extraClass' => 'custom-classes'
]);
?>
As background image
To use the lazyloader with a background image, e.g. on a <div class="lazy-image"></div>
, you just have to set the attributesOnly
parameter to true
.
Remember to use a noscript tag to show the image if no JavaScript is present. The plugin doesn't need any width or height information in this mode, make sure to define these yourself.
<div <?= LazyLoad::widget([
'attributesOnly' => true,
'src' => $this->publicHtml . '/path/to/image',
'extraClass' => 'custom-classes'
]); ?> >
</div>
<!-- Fallback for no-js -->
<noscript><div class="custom-classes" style="background-image: url(<?= $extras['image']->source ?>);"></div></noscript>
Using lazy loader with storage component
Using the lazy loader with a storage component luya\admin\image\Item is easier because you can automatically get the width and height from the storage component:
$image = Yii::$app->storage->getImage(123);
<?= LazyLoad::widget([
'src' => $image->source,
'width' => $image->resolutionWidth,
'height' => $image->resolutionHeight,
]); ?>
Event
Each image which is fully loaded will trigger the events lazyimage-loading
and lazyimage-loaded
on the document
. The lazyimage-loaded
event provides an object with the imageObject used and the type of the event (success
or error
).
$(document).on("lazyimage-loaded", function(e, image) {
console.log(image)
});
Legacy support
If you don't need older browser (mainly IE) support, you can disable the legacy support (https://caniuse.com/#feat=intersectionobserver).
<?= LazyLoad::widget([
'legacySupport' => false
]); ?>
JS Options
To set custom JS options you will have to first disable the automatic init of the lazyload function.
<?= LazyLoad::widget([
'initJs' => false
]); ?>
Then before the closing body tag you can init lazyLoad:
$.lazyLoad({
// Show console logs
debug: false,
// The loader HTML, customize according to your needs
loaderHtml: '<div class="loader"></div>',
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options
observerOptions: {
root: document,
rootMargin: '200px 0px 200px',
threshold: 0.01
},
})
There are more options than the ones shown here, but you probably won't need them. If you do, check the
lazyload.src.js
for all the options.
Collect new images
If you add images dynamically (with the correct lazyload markup provided by the widget), you can call $.lazyLoad('collectImages')
. This will collect all images that aren't already existing and start to observe them.