Skip to content

[vue] one change re-renders every renderer in the form #2633

Description

@KiaraGrouwstra

Describe the bug

Each change of the JSON Forms state makes every Vue renderer in the form render again, including the renderers whose bindings did not change. useControl (packages/vue/src/jsonFormsCompositions.ts) computes control as computed(() => ({ ...props, ...stateMap(...), id })), and useJsonFormsRenderer computes renderer as a rest spread of rawProps. Both getters return a new object on each recompute. Vue compares a computed value by identity, so it triggers all dependents: the render function of each control, and the DispatchRenderer props below each renderer.

On a form with a few hundred controls, each keystroke causes a delay of hundreds of milliseconds. When thousands of component updates are in the queue, the Vue scheduler also scans the queue for each insert, so the cost increases approximately as the square of the form size.

Expected behavior

A change re-renders only the renderers whose bindings changed.

Steps to reproduce the issue

  1. Make a Vue form with two string controls, first and second, and a control renderer that counts its renders.
  2. Change first.
  3. The renderer of second renders again, although its bindings are equal.

Screenshots

No response

Which Version of JSON Forms are you using?

v3.7.0 (and master at 47f7768)

Package

Vue Bindings

Additional context

Since Vue 3.4, a computed getter receives its previous value. The getter can return the previous object when the new object is equal, and then Vue triggers no dependents. The Vue package requires vue ^3.5.0, so this is available. I have a PR for this.

Assisted-by: claude-code-opus-5-5

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions