Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SEO][WP] Add a lazy-loading option for image fields #3659

Closed
jenlampton opened this issue Apr 10, 2019 · 40 comments · Fixed by backdrop/backdrop#3273
Closed

[SEO][WP] Add a lazy-loading option for image fields #3659

jenlampton opened this issue Apr 10, 2019 · 40 comments · Fixed by backdrop/backdrop#3273

Comments

@jenlampton
Copy link
Member

jenlampton commented Apr 10, 2019

Description of the need

Native <img> lazy-loading is coming to the web! https://bit.ly/loading-attribute<img loading=lazy> defers offscreen images until the user scrolls near them. Shipping in Chrome ~75 https://bit.ly/loading-i2s

This was one of the recommendations Google PageSpeed gave me for one of my Backdrop sites.

We should support this in Backdrop core!


References:


Advocate: @klonos


PR that adds a global setting under 'Performance': backdrop/backdrop#3256

PR that adds a setting for image fields: backdrop/backdrop#3273

@ghost
Copy link

ghost commented Apr 10, 2019

My first thought is that it'd be nice to have an option to turn this on/off (since it effectively changes how things have been working up to now, and some people don't necessarily like change), but then explaining that that option will only affect certain browsers/versions, blah blah blah could be tricky. So next thought is to include a polyfill for all other browsers, so then on/off option works for everyone. But then this sounds more like a contrib candidate than a core feature... But that's just my 2c.

@klonos
Copy link
Member

klonos commented Apr 10, 2019

I don't think that anyone will complain about this, since it sounds more like an improvement rather than an undesired change. Do we have any use case where someone has reported that this has broken things for them?

...also, what are our Drupal brethren doing about this?

Having said that, I wouldn't mind a global option for it. Under "Performance" seems proper.

@olafgrabienski
Copy link

Do we have any use case where someone has reported that this has broken things for them?

Don't know if it will actually break things, but https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/jxiJvQc-gVg and https://docs.google.com/document/d/1e8ZbVyUwgIkQMvJma3kKUDg8UUkLRRdANStqKuOIvHg mention some risks.

If we implement it site-wide, the default should be auto, leaving the decision to the browser (which seems to be the same as not setting the attribute at all).

More thoughts: In HTML loading="lazy" would be an option for every image. In my opinion, Backdrop site owners / architects, and content editors should also be able to control, if and how the attribute is used. I guess that means, in addition to a global option, loading attribute options could be useful for the CKEditor image dialog, for image field (or display) settings and for views fields.

@jenlampton
Copy link
Member Author

My first thought is that it'd be nice to have an option to turn this on/off (since it effectively changes how things have been working up to now

Well it is just an attribute, so it should be easy enough to turn on/off by adding/removing the attribute when any image is rendered. But I do think -- if not otherwise specified -- all images should lazy-load.

Backdrop site owners / architects, and content editors should also be able to control, if and how the attribute is used.

I could see this being a good candidate for contrib. My guess is that more than 80% of people would rather have have their sites load quickly than have images people can't see load first. However, it should be simple enough to integrate the option with all existing image fields so people can disable that on a per-image basis.

@klonos
Copy link
Member

klonos commented Apr 14, 2019

I think that lazy-loading by default, with a global option under "Performance" should be core; per-image field instance can be contrib.

@olafgrabienski
Copy link

I do think -- if not otherwise specified -- all images should lazy-load.

lazy-loading by default, with a global option under "Performance" should be core

I've skimmed through some of the linked information about the new attribute, and I'm still not sure if there will be unwanted side effects at the beginning, when loading=lazy is the default. What about starting with leaving the default to loading=auto, with the goal to test the lazy setting (and also eager) in real world situations? If there are no serious problems, we can iterate and change the default.

@klonos
Copy link
Member

klonos commented Apr 15, 2019

What about starting with leaving the default to loading=auto ...

That could work too. Safest also. If at a later point we are more confident that loading=lazy is safe to use, we can change that to be the default for new installations. Perhaps for existing sites we can consider using info type messages to let people know that they can switch.

@klonos klonos changed the title add loading=lazy attribute to img tags by default Support loading=lazy attribute for img tags Apr 15, 2019
@jlfranklin
Copy link
Member

Tracking pixels, hidden icons in drop down menus that may cause the menu to redraw multiple times as lazyload images come in, sprite sheets, collapsed form fields... there are a number of cases where the web developer may want them to load even though they're hidden.

When adding a new feature, the default setting should always be the previous behavior. Otherwise, Backdrop will earn a reputation for breaking sites on minor-number updates.

@jenlampton
Copy link
Member Author

jenlampton commented Apr 18, 2019

When adding a new feature, the default setting should always be the previous behavior.

If we use @klonos's recommendation of having a single site-wide on/off checkbox for this, then it would be easy to set to off for existing sites, and on for new ones.

Also, adding the [SEO] tag because making pages load faster will improve the search rankings for all Backdrop sites. I'm going to implement this on 3 of my sites and see if there is a markable change in google's rankings.

@jenlampton jenlampton changed the title Support loading=lazy attribute for img tags [SEO] Support loading=lazy attribute for img tags Apr 28, 2019
@klonos klonos changed the title [SEO] Support loading=lazy attribute for img tags [SEO][WP] Support native browser-level loading=lazy attribute for img tags Aug 17, 2020
@klonos
Copy link
Member

klonos commented Aug 17, 2020

FTR, the freshly-released WordPress v5.5 supports that feature OOTB:

Speed

Posts and pages feel faster, thanks to lazy-loaded images.

Images give your story a lot of impact, but they can sometimes make your site seem slow.

In WordPress 5.5, images wait to load until they’re just about to scroll into view. The technical term is ‘lazy loading.’

On mobile, lazy loading can also keep browsers from loading files meant for other devices. That can save your readers money on data — and help preserve battery life.

@klonos
Copy link
Member

klonos commented Aug 17, 2020

Tracking pixels, hidden icons in drop down menus that may cause the menu to redraw multiple times as lazyload images come in, sprite sheets, collapsed form fields... there are a number of cases where the web developer may want them to load even though they're hidden.

I would like us to test if these are actual problems, or assumptions.

When adding a new feature, the default setting should always be the previous behavior.

If we use @klonos's recommendation of having a single site-wide on/off checkbox for this, then it would be easy to set to off for existing sites, and on for new ones.

Yes! Let's please do this, and let's add an on/off switch under admin/config/development/performance, and have it on only for new sites.

@klonos
Copy link
Member

klonos commented Aug 17, 2020

PR up for review: backdrop/backdrop#3256

Most of the "system" images, like the admin bar icons and the hero block image, are being set in CSS (using style="background-image:url(/files/hero/...);" for example), so they are not affected by this change. Only images that are rendered via theme_image() get the loading="lazy" attribute. If a developer needs to disable that for a specific image, they can specify the loading attribute when calling theme_image():

$output = theme('image', array('attributes' => array('loading' => 'eager')));

No update hook added to the PR, so existing sites should be left intact, and will need to opt-in for the feature.

For now, I've added the checkbox that controls this under Configuration -> Development -> Performance:

image

Let me know if you think that it deserves its own dedicated fieldset, or it should live in a different section in the admin UI.

@klonos
Copy link
Member

klonos commented Aug 17, 2020

...my initial thinking was that hero blocks are usually placed at the top of the page, so they are likely to be within viewport at all times soon as the page loads, so lazy-loading does not make sense there. I then thought of @stpaultim and #4095, and realized that there are use cases where multiple hero blocks may be placed on a single page. Since hero images are large, lazy-loading those that are further down the viewport will have legit performance/loading gain, so I have actually enabled hero block images to also take advantage of this (if enabled).

@indigoxela
Copy link
Member

The PR still needs work. Many tests are currently failing.

@klonos
Copy link
Member

klonos commented Aug 18, 2020

Tests fixed.

@klonos
Copy link
Member

klonos commented Aug 30, 2020

Thanks @jenlampton 👍 ...I've closed my PR in favor of yours.

Today @quicksketch recommended that it should be a setting on image fields.

Also on text formats as a filter. If not as part of this PR, then we should file a follow-up. Furthermore, we should also make sure that this works with Views if the view format is set to show individual fields instead of "content".

@klonos
Copy link
Member

klonos commented Aug 30, 2020

...the main functionality (adding the loading attribute to images) works as expected per content type display 👍 ...once @indigoxela's comments are addressed (auto instead of normal + summary text in the formatter), this is RTBC from me.

@jenlampton
Copy link
Member Author

Also on text formats as a filter. If not as part of this PR, then we should file a follow-up

Yes, please, can you create another issue?

...once @indigoxela's comments are addressed

Done, and I added tests for lazy/eager loading!

@indigoxela
Copy link
Member

@jenlampton many thanks for updating the PR and for adding tests.

One thing still isn't addressed: hook_field_formatter_settings_summary()

There's no summary text yet, as proposed in my previous comment: "Loading: xxx"
See the screenshot for explanation.

@klonos
Copy link
Member

klonos commented Aug 31, 2020

Yes, please, can you create another issue?

Done 😉

@klonos
Copy link
Member

klonos commented Aug 31, 2020

...we should also make sure that this works with Views if the view format is set to show individual fields instead of "content".

Tested this in the current PR, and it works 🎉 :

image

@jenlampton
Copy link
Member Author

jenlampton commented Aug 31, 2020

  • summary text in the formatter

Ah, sorry. Not sure how I missed that. Pushed an updated PR!

Screen Shot 2020-08-31 at 10 51 13 AM

I'm adding the needs testing label back so someone else can review the new summary :)

@herbdool
Copy link

Looks good now - tested and reviewed the code.

@klonos klonos changed the title [SEO][WP] Support native browser-level loading=lazy attribute for img tags [SEO][WP] Add a lazy-loading option for image fields Sep 1, 2020
@quicksketch
Copy link
Member

I merged backdrop/backdrop#3273 into 1.x for 1.17.0. Thanks @jenlampton, @klonos, @indigoxela, @BWPanda, @stpaultim, @herbdool, and @olafgrabienski!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment