Skip to content

Lazy loading images #300

Description

@muriIo

Feature Request: Add lazyLoading config option to defer image fetching

Description

The @editorjs/image plugin currently loads all images eagerly at editor initialization time, regardless of their position in the document. There is no built-in way to defer image loading for off-screen blocks.

This becomes a significant problem when using a custom uploader backed by a private/authenticated endpoint — every image URL in the document triggers an immediate network request the moment the editor renders, even for images far below the fold that the user may never reach.


Problem

When an Editor.js document contains many image blocks (e.g. a long article or report), all images are fetched simultaneously on load. The current implementation unconditionally assigns src at render time:

// src/ui.ts (current behavior)
const attributes: { [key: string]: string | boolean } = {
  src: url, // always set immediately
};

Impact

  • Unnecessary backend requests — private image endpoints are called for every image in the document, even those never seen by the user.
  • Performance degradation — large documents with many images cause a burst of parallel requests on load, slowing down the initial render.
  • Increased server costs — authenticated or CDN-backed image servers are hit unnecessarily.
  • Poor UX on slow connections — bandwidth is consumed by off-screen images instead of prioritizing visible content.

Steps to Reproduce

  1. Configure @editorjs/image with a custom uploader pointing to a private backend.
  2. Load a document with 10+ image blocks.
  3. Open the Network tab in DevTools.
  4. Observe that all image requests fire simultaneously on editor load, including images far below the viewport.

Proposed Solution

Add an optional lazyLoading boolean to the plugin config. When enabled, the src attribute should be withheld until the image container approaches the viewport, using an IntersectionObserver.

Config API

// ImageConfig (types.ts)
interface ImageConfig {
  // ...existing options

  /**
   * Enables lazy loading for images.
   * When true, images are only fetched when they approach the viewport.
   * @default false
   */
  lazyLoading?: boolean;
}

Usage

const editor = new EditorJS({
  tools: {
    image: {
      class: ImageTool,
      config: {
        uploader: { /* your custom uploader */ },
        lazyLoading: true, // 👈
      },
    },
  },
});

Alternatives Considered

  • Native loading="lazy" attribute — simpler, but the image's load event is never triggered because we have the preloader container.

Additional Context


Are you willing to contribute a PR?

Yes, a working implementation has been prototyped and validated locally. Happy to submit a pull request if the maintainers are open to this feature.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions