Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some nodes are not removed correctly after reactivity, wrong references #686

Open
AlbertSabate opened this issue Dec 17, 2024 · 9 comments
Assignees
Labels

Comments

@AlbertSabate
Copy link
Collaborator

Describe the bug
This seems a regression from this bug: #361

PHOTO-2024-12-17-09-42-49
PHOTO-2024-12-17-09-42-48

To Reproduce
Complicated. It is a non consistent break.
It sometimes happens when navigating between pages. Very rare.

Expected behavior
Page should load all content it is supposed to load

@AlbertSabate AlbertSabate added bug Something isn't working regression labels Dec 17, 2024
@aralroca
Copy link
Collaborator

@AlbertSabate From which version of Brisa does it happen? to know where the regression has occurred

@AlbertSabate
Copy link
Collaborator Author

AlbertSabate commented Dec 17, 2024

Happened on 0.2.1-canary.2. I just bumped to canary.3 and I didn't see it for now.
I didn't see this on previous versions, it happens very very rarely. However still with us.

@aralroca
Copy link
Collaborator

aralroca commented Dec 17, 2024

After this PR of diff-dom-streaming brisa-build/diff-dom-streaming#14 there have been no further changes to the algorithm. It is likely to be improved, but some cases of chunks are still escaping.

Happened on 0.2.1-canary.2. I just bumped to canary.3 and I didn't see it for now. I didn't see this on previous versions, it happens very very rarely. However still with us.

After reproducing it, it happens for a long time

@aralroca aralroca self-assigned this Dec 17, 2024
aralroca added a commit that referenced this issue Dec 19, 2024
@aralroca
Copy link
Collaborator

aralroca commented Dec 19, 2024

Nothing to do with diffing algorithm, is a render problem.

I think the problem is in this line

for (const node of lastNodes) node?.remove();

that when it is a document.createTextNode it does not delete well. This leaves visible elements that should have been cleaned up.

@aralroca
Copy link
Collaborator

aralroca commented Dec 19, 2024

There is nothing to do with the textContent and remove, but try to delete a node that has been modified and isConnected is false while the new version has not been saved, which is the one that should be deleted at this time... I am still investigating...

@aralroca
Copy link
Collaborator

It seems that the state change modifies the textNode without noting the new version.

Then the change of the signal of the prop, makes it to be deleted, but it has the old reference that is already disconnected from the DOM and it is not deleted while the new one that has no reference is kept alive without being able to delete it.

@aralroca aralroca changed the title Navigating with SPA sometimes loses content Some nodes are not removed correctly after reactivity, wrong references Dec 19, 2024
@aralroca
Copy link
Collaborator

aralroca commented Dec 20, 2024

To understand the bug of these non-referenced nodes that cannot be deleted, it is necessary to understand that to control reactivity, each part responsible for maintaining its piece of DOM with reactivity saves the old nodes. The reason for keeping the old nodes is that after reactivity, the old ones are replaced by the new ones, and we need to know these references.

The problem comes when several responsible for controlling the DOM share a node, if one updates it, the reference that the other responsible had saved is not updated. Then, it is converted to a disconnected Node without having the new reference...

This happens when:

  • A reactivity Responsible A has the containers where another Responsible B has any of its child nodes.
  • The Responsible B deletes the nodes and new ones are added, the Responsible A does not update the reference of the child node, and instead of removing it, keeps this node (origin of this issue)...
Screenshot 2024-12-20 at 16 10 06

@aralroca
Copy link
Collaborator

aralroca commented Dec 20, 2024

by the way @AlbertSabate, as a workaround meanwhile we not find a solution, you can change the fragment <> by some node like <div>, the problem happens when there is a fragment and different signals control different parts of this fragment

aralroca added a commit that referenced this issue Dec 20, 2024
aralroca added a commit that referenced this issue Dec 22, 2024
@aralroca
Copy link
Collaborator

aralroca commented Dec 22, 2024

To understand a little more about the origin of the problem: each reactivity part should be responsible for its nodes, and there SHOULD BE NO SHARED nodes between reactivity parts. For example, this failing test:

{level2 ? (
<>
<span>Level 2 - Active</span>
<button onClick={() => (showInner.value = !showInner.value)}>
Toggle Inner
</button>
{showInner.value ? (
<p>Inner Content Visible</p>
) : (
<p>Inner Content Hidden</p>
)}
</>
) : (
<span>Level 2 - Inactive</span>
)}
</div>
</>

branch aralroca/issue-render.

The reactivity part of level2 prop, currently is controlling these nodes:

1)

 <span>Level 2 - Active</span> 

2)

<button onClick={() => (showInner.value = !showInner.value)}>
  Toggle Inner
</button>

3)

 // SHOULD NOT BE RESPONSIBLE OF THS, BUT IT IS
 <p>Inner Content Visible</p>

or

 // SHOULD NOT BE RESPONSIBLE OF THS, BUT IT IS
<p>Inner Content Hidden</p> 

The reactivity part of showInner state, currently is controlling these nodes:

1)

 <p>Inner Content Visible</p>

or

<p>Inner Content Hidden</p> 

If there are 2 responsible parties of a node, this bug can originate, since the reference of only 1 responsible party is updated.

The solution is not to synchronize the internal references, this is only a wrong workaround... The simplest solution would be to ensure that each responsible for reactivity has only its nodes. If there is another function with effect, it would passes to the next responsible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants