Skip to content

BUG: mj-image flickers / reloads on every non-src attribute or style edit #431

Description

@geonsang-jo

GrapesJS version

  • I confirm to use the latest version of GrapesJS

GrapesJS MJML version

  • I confirm to use the latest version of GrapesJS MJML

What browser are you using?

Chrome (latest) — the root cause is at the DOM level, so it isn't browser-specific.

Reproducible demo link

https://stackblitz.com/github/geonsang-jo/grapesjs-mjml-image-reconcile-demo/tree/fix/canvas-height-and-visible-flicker?file=src%2Fmain.ts&startScript=dev&view=preview

Describe the bug

How to reproduce the bug?

  1. Add an mj-image to the canvas.
  2. Edit any of its non-src attributes or styles — alt, title, padding, width, alignment — in the Trait/Style Manager.
  3. Watch the rendered image.

The StackBlitz demo above is a side-by-side Baseline vs. Patched repro (use Toggle width once / Start auto toggle); the page reports whether the rendered <img> DOM object was replaced.

What is the expected behavior?
Editing a non-src attribute or style updates the image in place; the already-loaded image stays visible and does not reload.

What is the current behavior?
The <img> visibly flickers on every edit — it briefly disappears, then reloads and repaints.

Root cause: the MJML view re-renders a component by rebuilding its entire subtree on every change:attributes / change:src event:

// src/components/index.ts — coreMjmlView.render()
this.el.innerHTML = this.getTemplateFromMjml();

Because the whole subtree is replaced, the existing <img> node is destroyed and recreated each time, so the browser drops the decoded image and refetches and repaints it — even when src did not change.

Confirmed on grapesjs-mjml@1.0.8.

I searched the existing issues: the closest are #385 (wrapper losing its children on a property edit) and #389 (redo not restoring an image), which share the same "an edit triggers a destructive full re-render" mechanism, but neither reports the mj-image flicker/reload specifically. I have an mj-image-scoped DOM-reconciliation fix ready and will open a PR.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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