# Node decorations before custom node view causes rerender

**URL:** https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924
**Category:** Uncategorized
**Created:** [July 26, 2021, 6:45pm UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924 "2021-07-26T18:45:53Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![rowanc1](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/rowanc1/32/1341_2.png) [@rowanc1](https://discuss.prosemirror.net/u/rowanc1)
#### Post date: [July 26, 2021, 6:45pm UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/1 "2021-07-26T18:45:53Z")

</div>

I am running into problems with the interaction between a node decoration and a custom nodeView. When the node decoration is before the custom nodeview, and is then removed (i.e. replaced with an `DecorationSet.empty` or a `DecorationSet` that has no decorations), the entire document rerenders (and the node view is recreated).

In this case, my decoration adds a class to empty paragraphs (a prompt for users) ([see github](https://github.com/curvenote/editor/blob/main/src/prosemirror/plugins/prompts.ts)) and my node-view is an iframe ([see github](https://github.com/curvenote/editor/blob/main/src/views/IFrameView.tsx)). The behaviour means the iframe gets rerendered on selection changes (causing flicking/loading, and other more complicated node views get recreated as well).

This seems to only happen when the prompt decoration is removed when it is before the iframe in the document, and when also involved in a selection change (it doesn’t happen when there are document changes). An example is below ([also online here](https://curvenote.github.io/editor/)):

![iframe-decoration-bug](https://discuss.prosemirror.net/uploads/secondsite/original/2X/5/5fe0503c566971c01a3de541b6e8175bac65402d.gif)

I was wondering if a quick look at the decoration code below highlights the problem? Or if maybe this is a bug? Or expected behaviour? I have also tried using the DecorationSet to `map`/`add`/`remove` the decorations. When it gets down to an empty set, that always seems to trigger a full refresh and flicker in the IFrame/custom nodeView.

I also think this may have been introduced in the last four or so weeks, (this code did work before, but I am having trouble reproducing that and getting back to the right versions; our deployed app doesn’t do this). I can get a minimal example together to demonstrate this if it is helpful/worth it.

## Decoration code

```javascript
const promptPlugin = new Plugin({
  key,
  state: {
    init: () => DecorationSet.empty,
    apply(tr, value, oldState, newState) {
      if (!isEditable(newState)) return DecorationSet.empty;
      const paragraph = getParentIfParagraph(newState.selection);
      const emptyParagraph = paragraph && paragraph.node.nodeSize === 2;
      if (tr.selection.empty && emptyParagraph) {
        const deco = Decoration.node(tr.selection.from - 1, tr.selection.to + 1, {
          class: 'prompt',
        });
        return DecorationSet.create(tr.doc, [deco]);
      }
      return DecorationSet.empty;
    },
  },
  props: {
    decorations(state) {
      return this.getState(state);
    },
  },
});

```

---

<div class="post-metadata">

### Author: ![bhl](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/bhl/32/4074_2.png) [@bhl](https://discuss.prosemirror.net/u/bhl)
#### Post date: [July 26, 2021, 7:29pm UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/2 "2021-07-26T19:29:03Z")

</div>

> [@rowanc1](#):
>
> This seems to only happen when the prompt decoration is removed when it is before the iframe in the document, and when also involved in a selection change (it doesn’t happen when there are document changes). An example is below ([also online here](https://curvenote.github.io/editor/)):

I would try putting a `console.log` statement in the [`NodeView.update`](https://prosemirror.net/docs/ref/#view.NodeView.update) method for the iframe and seeing if update is called when that nearby prompt decoration is changed, just to double check whether its the decoration causing an update.

---

<div class="post-metadata">

### Author: ![rowanc1](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/rowanc1/32/1341_2.png) [@rowanc1](https://discuss.prosemirror.net/u/rowanc1)
#### Post date: [July 26, 2021, 9:25pm UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/3 "2021-07-26T21:25:09Z")

</div>

Thanks! Tried adding that: the update method is _not_ called when the decoration is removed.

Removing the decoration plugin completely means the node-view is rendered as expected (only when the node-properties change). This also doesn’t happen if I leave the decorations in place and do not remove them.

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [August 12, 2021, 9:18am UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/4 "2021-08-12T09:18:40Z")

</div>

Hi, your example link points to what appears to be a project page. Could you distill this problem down to a minimal script so I can debug it?

---

<div class="post-metadata">

### Author: ![rowanc1](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/rowanc1/32/1341_2.png) [@rowanc1](https://discuss.prosemirror.net/u/rowanc1)
#### Post date: [August 12, 2021, 2:38pm UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/5 "2021-08-12T14:38:51Z")

</div>

Thank you! I will get a simple example one together over this weekend.

---

<div class="post-metadata">

### Author: ![rowanc1](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/rowanc1/32/1341_2.png) [@rowanc1](https://discuss.prosemirror.net/u/rowanc1)
#### Post date: [October 28, 2021, 5:43am UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/6 "2021-10-28T05:43:31Z")

</div>

I am no longer seeing this issue in updated versions!

---

<div class="post-metadata">

### Author: ![nkeynes](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/nkeynes/32/2409_2.png) [@nkeynes](https://discuss.prosemirror.net/u/nkeynes)
#### Post date: [November 3, 2021, 2:07am UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/7 "2021-11-03T02:07:23Z")

</div>

We hit a similar issue, although I’m not sure if it’s the exact same one or not - what we found is that if we have two blocks that are identical other than for a decoration on the first block, removing that decoration will cause all NodeViews after that point to be rebuilt, ie.

Block “A” | Decoration(foo) Block “B” … Block “A”

=\>

Block “A” Block “B” … Block “A”

The reason appears to be that after the state change, the view reconciliation logic first looks for a block that is an exact match for both content + decorations - in this case the former NodeView for the second Block “A” is now a match for the first Block “A”, so it is selected as the replacement, and the preceding NodeViews are destroyed (to be subsequently regenerated).

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [November 3, 2021, 8:13am UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/8 "2021-11-03T08:13:12Z")

</div>

Do your node views have an `update` method? I can’t reproduce this issue in a simple setup that follows the situation you describe.

---

<div class="post-metadata">

### Author: ![nkeynes](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/nkeynes/32/2409_2.png) [@nkeynes](https://discuss.prosemirror.net/u/nkeynes)
#### Post date: [November 4, 2021, 12:35am UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/9 "2021-11-04T00:35:47Z")

</div>

I have a test case at [Glitch :･ﾟ✧](https://glitch.com/edit/#!/unmarred-plume-nitrogen) - reproduces by clicking in the first (empty paragraph), and then click in the second paragraph block while watching the console logs - you should see that destroy() is called on 3 NodeViews with no preceding attempt at update()

(In this test case the regeneration is harmless of course, it’s more of a concern when the NodeView contents are expensive to rebuild (or do so asynchronously))

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [November 4, 2021, 7:45am UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/10 "2021-11-04T07:45:54Z")

</div>

Thanks, I hadn’t entirely gleamed the structure of the case from your earlier description, but that script helped reproduce this. I think [this patch](https://github.com/ProseMirror/prosemirror-view/commit/31e7cdf8880ff777ea724bd0c8c2e9950cf484e4) should help here.

---

<div class="post-metadata">

### Author: ![nkeynes](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/nkeynes/32/2409_2.png) [@nkeynes](https://discuss.prosemirror.net/u/nkeynes)
#### Post date: [November 4, 2021, 9:52pm UTC](https://discuss.prosemirror.net/t/node-decorations-before-custom-node-view-causes-rerender/3924/11 "2021-11-04T21:52:08Z")

</div>

Yep that fixes it, thanks!
