ckeditor5 icon indicating copy to clipboard operation
ckeditor5 copied to clipboard

loading="lazy|eager" for images

Open heddn opened this issue 4 years ago • 11 comments

Loading="lazy|eager" for images

A somewhat recent update to the HTML spec is rapidly being adopted. This looks to add that feature into the image plugin that is part of ckeditor. We actually want this feature for use in Drupal, but are happy to see it incorporated into the upstream project for wider adoption across the CMS ecosystem.

https://html.spec.whatwg.org/multipage/urls-and-fetching.html#lazy-loading-attributes

There should be a UI toggle for enabling lazy vs eager loading. We've learned a few things since loading="lazy" has started to be heavily used. Mainly, always enabling it negatively affects the page's LCP score. See https://web.dev/lcp-lazy-loading/ for an exhaustive description of the problem.


If you'd like to see this feature implemented, add a 👍 reaction to this post.

heddn avatar Nov 02 '21 18:11 heddn

/me waves at @heddn from drupal.org 😄

Is the idea here to allow content creators to signal which images in their content are higher priority? Isn't it always going to be the first one? Or inline images, because reflows would be bad?

I guess it's the other way around actually, since eager is the default — that'd allow content creators to mark certain images as lower priority?

I'm concerned about overburdening the content creator with these decisions. Depending on the context in which they're editing, they may not even be able to make a fully informed decision.

wimleers avatar Nov 05 '21 08:11 wimleers

One suggestion proposed was to add a marker for "below the fold" so a content editor could mark where they think below will occur so ckeditor can "do the right thing" for images and iframes that are embedded.

heddn avatar Nov 05 '21 17:11 heddn

One suggestion proposed was to add a marker for "below the fold" so a content editor could mark where they think below will occur so ckeditor can "do the right thing" for images and iframes that are embedded.

I think that is a nice solution, it would also be nice if we could change default value for this toggle input. Some users might want it default off and some default on.

ghost avatar Dec 15 '22 11:12 ghost

Hi,

Does anybody have an idea how to implement this on ckeditor5 ? Something like an equivalent to what is available for Link through decorators ?

      link: {
        decorators: {
          isExternal: {
            mode: "automatic",
            callback: (url: string) =>
              !/^(https?:)?\/\/www\.whatever\.com/.test(url),
            attributes: {
              target: "_blank",
              rel: "noopener noreferrer nofollow",
            },
          },
        },
      },

If not, any docs available to create a custom plugin would be more than welcome.

Thanks.

hhsissi avatar Nov 06 '23 01:11 hhsissi

@hhsissi i have the following custom config:

const LOADING_LAZY = 'lazy';
const LOADING_EAGER = 'eager';

/**
 * For image add `loading` attribute with the correct value.
 * Default value is `lazy`.
 *
 * @see: https://ckeditor.com/old/forums/CKEditor-3.x/Modify-Existing-Plugin
 * @see: https://ckeditor.com/docs/ckeditor4/latest/guide/dev_howtos_dialog_windows.html
 * @see: https://github.com/jahilldev/ckeditor-lazy-load/blob/master/lazyload/plugin.js
 */
// eslint-disable-next-line no-undef
CKEDITOR.on('dialogDefinition', ev => {
  // Take the dialog window name and its definition from the event data.
  const dialogDefinition = ev.data.definition;

  // Only edit the image dialog.
  if ('image' !== ev.data.name) {
    return;
  }

  dialogDefinition.addContents({
    label: 'Loading lazy',
    elements: [
      {
        type: 'checkbox',
        label: 'Load the img lazy?',
        default: 'checked', // Default its checked and on `setup` its unset if we have eager loading.
        setup(type, element) {
          if (element.getAttribute('loading') === LOADING_EAGER) {
            this.getInputElement().$.click();
          }
        },
        onChange() {
          if (null === this.getDialog().getSelectedElement()) {
            return;
          }
          let loadingAttributeValue = LOADING_EAGER;
          if (this.getValue()) {
            loadingAttributeValue = LOADING_LAZY;
          }
          this.getDialog().getSelectedElement().setAttribute('loading', loadingAttributeValue);
        },
        commit(type, element) {
          let loadingAttributeValue = LOADING_EAGER;
          if (this.getValue()) {
            loadingAttributeValue = LOADING_LAZY;
          }
          element.setAttribute('loading', loadingAttributeValue);
        },
      },
    ],
  });
});

Make sure you add this as your custom config

JohJohan avatar Nov 06 '23 13:11 JohJohan

@JohJohan this looks like a config for CKEditor 4.

Witoso avatar Nov 06 '23 14:11 Witoso

@JohJohan this looks like a config for CKEditor 4.

Your right, maybe you can get some inspiration then

JohJohan avatar Nov 06 '23 14:11 JohJohan

    elements: [
      {
        type: 'checkbox',

Thanks @JohJohan, worked like a charm. I was looking exactly for that. I've seen a very similar code but it was for ckeditor 4, it used dataProcessor.htmlFilter or something like that. Do you know if there's an official doc describing such things ? i searched that for hours on ckeditor5 docs but could'nt find it.

hhsissi avatar Nov 06 '23 14:11 hhsissi

    elements: [
      {
        type: 'checkbox',

Thanks @JohJohan, worked like a charm. I was looking exactly for that. I've seen a very similar code but it was for ckeditor 4, it used dataProcessor.htmlFilter or something like that. Do you know if there's an official doc describing such things ? i searched that for hours on ckeditor5 docs but could'nt find it.

No sorry I use version 4

JohJohan avatar Nov 06 '23 14:11 JohJohan

Do you know if there's an official doc describing such things ? i searched that for hours on ckeditor5 docs but could'nt find it.

A custom plugin would need to be developed for this. We have tutorials for them, the one about simpleBlocks could help. No tutorial yet on the extending of image. I will add this to our tasks.

Witoso avatar Nov 08 '23 09:11 Witoso

There has been no activity on this issue for the past year. We've marked it as stale and will close it in 30 days. We understand it may still be relevant, so if you're interested in the solution, leave a comment or reaction under this issue.

CKEditorBot avatar Nov 18 '25 23:11 CKEditorBot