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
- Configure
@editorjs/image with a custom uploader pointing to a private backend.
- Load a document with 10+ image blocks.
- Open the Network tab in DevTools.
- 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.
Feature Request: Add
lazyLoadingconfig option to defer image fetchingDescription
The
@editorjs/imageplugin 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
srcat render time:Impact
Steps to Reproduce
@editorjs/imagewith a custom uploader pointing to a private backend.Proposed Solution
Add an optional
lazyLoadingboolean to the plugin config. When enabled, thesrcattribute should be withheld until the image container approaches the viewport, using anIntersectionObserver.Config API
Usage
Alternatives Considered
loading="lazy"attribute — simpler, but the image's load event is never triggered because we have the preloader container.Additional Context
IntersectionObserveris [supported in all modern browsers](https://caniuse.com/intersectionobserver).lazyLoadingdefaults tofalse.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.