Hi,

I was looking for drupal plugin for responsive or plain image lazy loading, but couldn't find anything good that fits my needs. Also, it can be useful for image heavy sites to improve page load performance.
Discovering JS libraries for image lazy load I found this one https://github.com/aFarkas/lazysizes and it looks pretty good.
I'm interested in implementing such kind of responsive image lazy loading module, but doubt if it's worth to develop another separate module which would be dealing with picture element.
So, I wonder if there is an interest for integration lazysizes with picture module?

Any thoughts, suggestions and comments are welcome!

Comments

ssemashka’s picture

Issue summary: View changes
attiks’s picture

Status: Active » Needs work

Off course, feel free to upload a patch.

Ideally all javascript is plain javascript ;-)

attiks’s picture

See #2365083: Applying lazyloader in Picture, it already has a patch

ssemashka’s picture

Assigned: Unassigned » ssemashka

thanks, I'm currently looking into that. I'll keep this issue updated

ssemashka’s picture

Status: Needs work » Needs review
Issue tags: +picture
StatusFileSize
new29.15 KB

Added lazySizes.js and "Picture lazyload" checkbox to field formatter and image manage file display tab ("/admin/config/media/file-types/manage/image/file-display").
Needs review.

Adding aspect ratio support is in my roadmap. Aspect ratio helps to preserve space for picture elements that are not loaded yet and prevents layout reflows while image is lazyloading.

Status: Needs review » Needs work

The last submitted patch, 5: implement_image_lazy_load-2491101-5.patch, failed testing.

ssemashka’s picture

Assigned: ssemashka » Unassigned
Status: Needs work » Needs review
StatusFileSize
new29.16 KB

Rebased patch on latest picture module dev version

attiks’s picture

Are you still planning on adding aspect ratio support?

ssemashka’s picture

StatusFileSize
new44.09 KB

yes, was little stuck during implementation. I realized applying aspect ratio doesn't make sense when there is a fallback image style selected.
So, what I've done:

  1. Added 2 checkboxes: "Picture lazyload" and "Keep aspect ratio".
  2. When "Picture lazyload" is checked lazysizes.js is being added and srcset attribute is being replaced by data-srcset. Lazysizes.js sets srcset attributes when picture element appears in viewport .
  3. When "Keep aspect ratio" is checked aspectratio.js plugin is being added with aspectratio.css. Data-aspectratio attribute will be defined to every <source> tag based on image dimensions from srcset.
  4. Added 'Empty image' option for all "Fallback image style" selectors.
  5. Applied visibility rule to display "Keep aspect ratio" checkbox when:
    1. "Picture lazyload" is checked
    2. "Fallback image style" has "Empty image" selected

Let me know what do you think.

attiks’s picture

I had a quick look at the patch, some questions and small remarks. Will test the patch later today

  1. +++ b/picture.module
    @@ -1251,10 +1379,19 @@ function theme_picture(array $variables) {
    -        '#theme' => 'image_srcset',
    -        '#uri' => $src,
    +        '#theme' => 'image',
    +        '#path' => $src,
    
    @@ -1264,8 +1401,8 @@ function theme_picture(array $variables) {
    -        '#theme' => 'image_srcset',
    -        '#uri' => $src,
    +        '#theme' => 'image',
    +        '#path' => $src,
    

    why the change?

  2. +++ b/picture.module
    @@ -1781,7 +1925,7 @@ function picture_wysiwyg_editor_settings_alter(&$settings, $context) {
    + *drup
    

    should be removed

  3. +++ b/picture.module
    @@ -1866,9 +2010,6 @@ function picture_link_types($instance) {
    -  if (!class_exists('PictureMapping')) {
    -    module_load_include('php', 'picture', 'includes/PictureMapping');
    -  }
    

    why did you remove this?

ssemashka’s picture

StatusFileSize
new42.63 KB

@attiks, thanks for reviewing. Those changes were made by chance, sorry. Reverting them. Adding updated patch.

loparr’s picture

Hi, I manually applied the this patch. I can see checkboxes on /admin/structure/file-types/manage/image/file-display (lazyload, aspect ratio). However lazyloading is not working. I even tried to load lazysizes.js using context for every page. I get no error on console nor any system error.

Or do I need to apply the first patch and also second after? Thank you.

ssemashka’s picture

Hi loparr,
You need to apply only the patch from comment #11.
Check your picture element, if you have data-srcset attributes on <source> tags, then the issue is most likely on JS side. Please, drop me the JS error from browser console, your picture element markup and screenshots what you see, I'll try to investigate it.
If you don't see data-srcset attribute on <source> tags with lazyload checkbox checked, it means something is not configured properly.
Give me the information I mentioned above, it will give me more clarity what's happening.

loparr’s picture

Hi,

I checked all settings and found another checkbox in image field in /admin/structure/types/manage/content-type/display. Before I checked only here /admin/structure/file-types/manage/image/file-display (lazyload, aspect ratio)

Now the <source> have data-srcset attribute and picture has class "array lazyloaded"

However now I get error: Notice: Array to string conversion in theme_picture() (line 1381 of /sites/all/modules/picture/picture.module).
And no error in console. The line 1381 from module is "$attributes['class'] = !empty($attributes['class']) ? $attributes['class'] . ' lazyload' : 'lazyload';"

So images inside fields are lazyloaded however images inserted inline (wysiwyg and ckeditor + media) are not lazyloaded. The <source> tag does not have data-srcset attribute. Images inserted inline without media do not lazyload as well. Tha only place where I could find settings for image is /admin/structure/file-types/manage/image/file-display (lazyload, aspect ratio).

Thank you.

ssemashka’s picture

StatusFileSize
new46.33 KB

Hi loparr,

Thanks for pointing this out, I wasn't much aware of wysiwyg support. Try new patch from comment #15, I added lazyload support for wysiwyg.
Also, here is the list of places where you can find lazyload checkbox:

  • /admin/config/media/file-types/manage/image/file-display - file display mode
  • /admin/config/media/picture/settings - picture settings for wysiwyg editors
  • content type manage display (e.g.: /admin/structure/types/manage/[content-type]/display) -> choose picture formatter for image field -> check out picture field formatter settings
attiks’s picture

Assigned: Unassigned » jelle_s
baysaa’s picture

Thank you for the patch @sergesemashko

The patch at #15 worked well when I tested it on my website. The only issue was I had a bit of trouble getting it to run (and it's probably my own fault to begin with) the first time. I suppose this is more of a documentation thing. I'll explain what happened:

When changing the "fallback" to an empty image, my CSS wasn't set to expand img tags inside pictures to be 100% width of the parent. This caused some headscratches as the heigh on images wasn't being set, and the "addAspectRatio" method failed as the img width was less than 36 pixels (1x1 blank gif). The code below is where it fails. (ls.aspectratio.js: line 158):

if(width < 36){
  if(width && window.console){
    console.log('Define width of image, so we can calculate the height');
  }
  return;
}

All I had to do was apply the CSS below to make the ls.aspectratio.js reserve correct space/placeholder for the image:

picture img { width: 100% }

ssemashka’s picture

@Baysaa, thanks for trying patch out.
Actually, picture img { width: 100% } is in /lazysizes/plugins/aspectratio/ls.aspectratio.css. The file is loaded for me and aspectratio works fine.
Maybe you have something that prevents contrib css files from being loaded?

baysaa’s picture

@sergesemashko, I notice now that the CSS is not included when 'picture_polyfill_version' variable is set to 'dev'. The CSS is only included when the variable is set to 'min'.

baysaa’s picture

StatusFileSize
new46.64 KB

Here's a rerolled patch from #15 to also include the ls.aspectratio.css when on 'dev' mode of 'picture_polyfill_version' (See comment #19)

Edit: Bad patch. Uploading a reroll again in a few min.

Status: Needs review » Needs work

The last submitted patch, 20: implement_image_lazy_load-2491101-20.patch, failed testing.

baysaa’s picture

StatusFileSize
new46.55 KB

Trying again.

baysaa’s picture

Status: Needs work » Needs review

Trigger testbot

baysaa’s picture

Displaying latest patch only on summary.

baysaa’s picture

baysaa’s picture

StatusFileSize
new46.55 KB

I can't take credit for this patch. So uploading again with correct author. Sorry for the spam (Bit new to the workflow)

  • Jelle_S committed 157e033 on 7.x-2.x
    Issue #2491101 by sergesemashko, Baysaa: Implement image lazy load
    
jelle_s’s picture

Status: Needs review » Fixed

Fixed in latest dev. Thanks for the patch!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

titouille’s picture

Hi,

Just a little question about the lazyaspectratio... ls.aspectratio.css contains the following rule :

picture img {
  width: 100%;
}

With this rule, when aspectratio is used on at least one picture on the page, ls.aspectratio.css is loaded and apply the rule on all pictures on the page, even if it's not needed (for example pictures as thumbnail in the main content are stretched and pixelised). With this behavior, themer is obligated to add lot of rules to correct the width for any pictures that doesn't need 100% width.

Why don't use a more precise rule like this :

picture img.lazyaspectratio {
  width: 100%;
}

To apply the 100% width only to pictures that need it for the aspect-ratio calculation ? If themer want to apply 100% width to any pictures, I think it's his choice. he doesn't must be obligated to do when enabling the picture module, I'm right ??

Thanks in advance for your answer about that.

Greg Varga’s picture

I agree with titouille #30. adding the .lazyaspectratio class helps fixing this issue.

attiks’s picture

Status: Closed (fixed) » Needs work

Can somebody provide a patch?

sgdev’s picture

Status: Needs work » Needs review
StatusFileSize
new689 bytes

Patch attached.

Status: Needs review » Needs work

The last submitted patch, 33: picture-lazyload_css-2491101-33.patch, failed testing.

pawandubey’s picture

Status: Needs work » Fixed

@ron_s

There is another issue created for it related to image width
https://www.drupal.org/project/picture/issues/2720209

Please follow the same and closing this issue as the patch is already merged.

sgdev’s picture

Status: Fixed » Needs review

I responded to the module maintainer 3 years ago in providing a patch to resolve the issue.

All of a sudden deciding that you want to point to another issue where you created the same patch 40 minutes ago is not appropriate. Resetting to Needs Review.

joaogarin’s picture

I think we should include the patch here. it fixes the issue

joaogarin’s picture

Status: Needs review » Reviewed & tested by the community
thomas.frobieter’s picture

lesleyfernandes’s picture

Status: Reviewed & tested by the community » Fixed

Thanks @ron_s

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.