Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
9 posts Page 1 of 1
Lazy loading images and other large files is a great way to get a big boost to page speed, while saving yourself and site visitors on unnecessary bandwidth usage. Lazy loading works by initially showing a 1-pixel image while hiding the real image source in a 'data-src' attribute. A script then loads the real source into the 'src' attribute only when it's needed by the viewport.
Code: Select all
<img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' data-src='<cms:show my_image />' class='lazyload' alt='' />

It's a neat trick, but the non-standard markup makes it a hassle to write and manage the html code. That's where the <cms:lazy_load> tag steps in. This tag is a pre-processor that looks through your ordinary, standard markup and modifies image, iframe, audio, and video tags with the necessary changes.

lazysizes.js
I have chosen to use lazysizes.js (https://github.com/aFarkas/lazysizes) with this module. It's a script that's free from dependencies like jQuery, and it has worked well for my own purposes. The necessary lazysizes scripts are bundled together with this tag, but will have to be added by you to the javascript on the page.

All lazy-load scripts work on the same principle, so this pre-processor can be made to work with other scripts. For images and iframes, the only difference should be the class name that triggers lazy loading (audio and video may be more complicated). This module uses "lazyload" as the trigger. You can configure the trigger class in your lazy-load script, or change the trigger definition in lazyload.php.
Code: Select all
define(LAZYLOAD_TRIGGER, 'lazyload');

Usage
Include the lazy load script(s) on the web page. The ls.unveilhooks.min.js script is a plugin for <audio> or <video> tags. It's not needed unless you're using it for those tags.
Code: Select all
<script src="ls.unveilhooks.min.js"></script>
<script src="lazysizes.min.js"></script>

Wrap any portion of your Couch code with the <cms:lazy_load> tag to pre-process tags for lazy loading. If you don't want a particular asset to be lazy-loaded, give it a class of 'eager' to skip over it.

By default, the tag processes all resource types. You can specify the types of content to target by adding parameters to the tag.
Code: Select all
<cms:lazy_load> //lazyloads images, iframes, audio/video
---
<cms:lazy_load 'image'> //only images
---
<cms:lazy_load 'iframe' 'video'> //only iframes and audio/video

Images
Big galleries of images are the ideal use case for lazy loading.

Lazy loading works best when the <img> tag or css provides explicit sizes, so the screen can be blocked out correctly on loading. Otherwise, resizing and reflowing of the page content as new images load can give a janky experience. This issue can be challenging because it constrains your design choices.

With lazysizes.js, this module will also lazy-load responsive images.

Iframes
This is my favorite use for lazy-loading. I consider it best practice to lazy load any embedded content like YouTube or Google Maps. They are always the biggest drag on page speed, both in analytics and user experience. Lazy loading embedded content makes a huge impact on the snappiness of a page, and this module makes it plug-and-play easy.

I've found that browsers can misbehave if an iframe's 'src' attribute isn't a url. This module uses an empty file named iframe-dummy.html in your site's root - the equivalent of a 1-pixel image. The <cms:lazy_load> tag will create the file in the site's root if it doesn't already exist.

Video and Audio Tags
The ls.unveilhooks plugin handles video and audio. It doesn't mess with a video or audio tag's sources. Instead, the pre-processor simply sets preload='none' to prevent downloading the audio or video file. The script changes the attribute to preload='auto' when it enters the viewport. It lazy loads the poster image just like other images.

CSS Hooks
The lazysizes script provides the class names 'lazyload,' 'lazyloading,' and 'lazyloaded' for you to hook styles to. The following CSS creates a fade-in effect for images and adds a loading gif to iframes and video.
Code: Select all
    /* Lazy Loading */
    .lazyload, .lazyloading {
        opacity: 0;
        }
    .lazyloaded {
        opacity: 1;
        -webkit-transition: opacity 600ms;
        transition: opacity 600ms;
        }
    iframe.lazyload, iframe.lazyloading, video.lazyload, video.lazyloading {
        opacity: 1;
        background: url('icons/loading.gif') no-repeat 50% 50%;
        }

There is much more detailed information about using lazysizes.js at https://github.com/aFarkas/lazysizes.

Installation:
To use the tag, unzip the attached folder into couch/addons/ and enable it in your couch/addons/kfunctions.php file:
Code: Select all
require_once( K_COUCH_DIR.'addons/lazyload/lazyload.php' );

https://github.com/fallingsprings/couch ... r/lazyload

Attachments

Great job, Tim :)
Thanks for this plugin. I was already using lazysizes, so it slipped in easily and works wonderfully.

I'm not having any problems with the plugin, but with an additions i've made and was wondering if you might be able to help.

I've modified the script slightly to add responsive bumf to image and am using getimagesize() for getting the information.
Code: Select all
//set up lazy load
//img src
if ( $node->getAttribute('src') ) {
    // GWIL -- get & set image size & create --aspect-ratio style
    $gwil_size = getimagesize($node->getAttribute('src'));

Has all been working fine, but have run into an issue when accessing a http protected site.
Now the getimagesize line is giving the following error:

Warning: getimagesize(http://dev.elf.magmachamber.co.uk/dev1/ ... 0x180.jpeg): failed to open stream: HTTP request failed! HTTP/1.1 401 Unauthorized in /homepages/37/d766678654/htdocs/dev/elfyn/dev1/c/addons/lazyload/lazyload.php on line 92

I've tried using a fixed url with the credentials baked in and that works, but just wondering if i'm missing something obvious.
Code: Select all
 
$gwil_size = getimagesize('http://user:password@dev.elf.magmachamber.co.uk/dev1/c/uploads/image/blog-images/modesty-1920x1080-progressive-180x180.jpeg');

I can figure out a hack using the above, and it's only the dev server that is password protected, but I would like to get it working eitherway.

I know next to nothing of php so would really appreciate any pointers.

cheers,
gwil

ps sorry if i've posted in wrong palce
-deleted-
So here's something to try. Instead of using the url, use the file path when using getimagesize. That should work around the issue of needing http credentials.

Hope it helps!
Code: Select all
$gwil_url = $node->getAttribute('src');
$gwil_dir = str_replace(K_SITE_DIR, K_SITE_URL, $gwil_url);
$gwil_size = getimagesize($gwil_dir);

P.S. I'm glad the addon has been useful to you. If you have a useful mod or application for the script, I'd encourage you to share it here, so someone else may benefit.
Should be the other way around ;)
Code: Select all
$gwil_dir = str_replace( K_SITE_URL, K_SITE_DIR, $gwil_url);
active topics, google
Free support is never free.. Donate!
@tim Thankyou so much, that works a treat; used mod by @trendoman
@trendoman Thankyou as well; didn't try wothout your mod, but it works perfectly with

thankyou both. the more i use couch the more i love it & the community is wonderfully supportive.

if anyone is interested the mod to lazyload.php does the following:
for
Code: Select all
<img src={img src}  />

and
Code: Select all
<img data-src={img src}  />

auto inserts
style="height: 0; padding-top: {ratio}%; max-width: {image width};" height="{image height}" width="{image width}"

where {ratio} is ({image height}/{image width})*100m which creates image sized placeholder which maintains aspect ratio.

when lazyloaded class applied; uses the following css
Code: Select all
img.lazyloaded {
  height: auto!important;
  padding-top: 0!important;
}

to overwrite inline styles.
for
Code: Select all
<img src={img src}  />

it adds
class="lazyload"

this means i can use differnet lazyloading for things like carousels which may have there own lazyloading. I'm currently using tinyslider which handles the lazyloading, so i just set up the placeholders with lazyload.php.
Means anything between <cms:lazy_load></cms:lazy_load> is responsive, and no page jumps.
cheers,
gwil

[edit] forgot to show what {ratio} was & the code
Code: Select all
// GWIL - set aspect ratios for otherwise lazyloading (eg tns)
if ( $node->getAttribute('data-src') ) {
    // GWIL -- get image size & create responsive sr styles
    $gwil_url = $node->getAttribute('data-src');
    // GWIL - get relative path from url
    $gwil_dir = str_replace(K_SITE_URL, K_SITE_DIR, $gwil_url);
    $gwil_size = getimagesize($gwil_dir);
    $gwil_size_w = $gwil_size[0];
    $gwil_size_h = $gwil_size[1];

    // GWIL - get any existing inline styles
    $gwil_node_style =  $node->getAttribute('style');
    $gwil_node_styles = explode(";", $gwil_node_style);
    if ($gwil_node_styles != '') {
        foreach ($gwil_node_styles as $gwil_item) {
            $gwil_lazy_style = $gwil_lazy_style.$gwil_item;
        }
    }

    // GWIL - old method using --aspect-ratio
    //$gwil_lazy_style = $gwil_node_style.'--aspect-ratio:'.$gwil_size_w.'/'.$gwil_size_h;

    // GWIL - append responsive ar styles & height & width
    $gwil_lazy_style = $gwil_lazy_style.'; height: 0; padding-top: '.$gwil_pad_top . ';max-width:'.$gwil_size_w.'px;';
    $node->setAttribute('height', $gwil_size_h);
    $node->setAttribute('width', $gwil_size_w);
    $node->setAttribute('style', $gwil_lazy_style);

    // GWIL - set ar only flag (no LAZYLOAD_TRIGGER class will be applied)
    $gwil_aspect_only = 1;

    // GWIL - Do not copy src to data-src, leave it to other
    //$node->setAttribute('data-src', $node->getAttribute('src'));
    // GWIL - Do not set blankImage
    // $node->setAttribute('src', $blankImage);
}

//set up lazy load
//img src
if ( $node->getAttribute('src') ) {
    // GWIL -- get image size & create responsive ar styles
    $gwil_url = $node->getAttribute('src');
    // GWIL - get relative path from url
    $gwil_dir = str_replace(K_SITE_URL, K_SITE_DIR, $gwil_url);
    $gwil_size = getimagesize($gwil_dir);
    $gwil_size_w = $gwil_size[0];
    $gwil_size_h = $gwil_size[1];
    $gwil_ratio = $gwil_size_h / $gwil_size_w;
    $gwil_pad_top = ($gwil_ratio * 100) . '%';

    // GWIL - get any existing inline styles
    $gwil_node_style =  $node->getAttribute('style');
    $gwil_node_styles = explode(";", $gwil_node_style);
    if ($gwil_node_styles != '') {
        foreach ($gwil_node_styles as $gwil_item) {
            $gwil_lazy_style = $gwil_lazy_style.$gwil_item;
        }
    }

    // GWIL - append responsive ar styles & height & width
    $gwil_lazy_style = $gwil_lazy_style.'; height: 0; padding-top: '.$gwil_pad_top . ';max-width:'.$gwil_size_w.'px;';
    $node->setAttribute('height', $gwil_size_h);
    $node->setAttribute('width', $gwil_size_w);
    $node->setAttribute('style', $gwil_lazy_style);

    // GWIL - copy src to data-src
    $node->setAttribute('data-src', $node->getAttribute('src'));
    // GWIL - Removed following line to allow responsive place holder with indicator
    // $node->setAttribute('src', $blankImage);
    // GWIL - replaced with
    $node->setAttribute('src', '');
}

// GWIL - TODO check how this works in practice
//responsive images
if ( $node->getAttribute('srcset') ) {
    $node->setAttribute('data-srcset', $node->getAttribute('srcset'));
    $node->removeAttribute('srcset');
    //autosizes
    if ( $node->getAttribute('sizes') == 'auto') {
        $node->setAttribute('data-sizes', 'auto');
        $node->removeAttribute('sizes');
    }
}

// GWIL - if !$gwil_aspect_only add LAZYLOAD_TRIGGER class
if ($gwil_aspect_only != '1') {
    $node->setAttribute('class', trim($node->getAttribute('class') . ' ' . LAZYLOAD_TRIGGER));
}
Interesting, thanks!
@MiB your welcome.
i've nearly got a more complete version that takes care of placeholder images (converts them into base64 and inlines them) as well.
I'll post it when i'm happy with it
9 posts Page 1 of 1

Who is online

In total there are 2 users online :: 0 registered, 0 hidden and 2 guests
(based on users active over the past 5 minutes)

Users browsing this forum: No registered users and 2 guests