Closed starsolaris closed 6 years ago
Thanks for the report. While trying to reduce this, I ended up with another weird issue:
const root = document.body
const cmp = {view({children}){return m('div', [children])}}
m.render(root, m(cmp, [
[m('div', 1)],
[m('div', 2)],
[m('div', 3)]
]))
m.render(root, m(cmp, [
[],
[m('div', 4)]]
))
m.render(root, m(cmp, [
[m('div', 5)]
]))
m.render(root, m(cmp, [
[], []
]))
leaves the DOM as <div>4</div><div>5</div>
.
Something is amiss in the land of nested fragments.
Making some progress.
Edit: Even using #1675 with the #1992 fix doesn't solve the issue if you set vnode.reuse
to true
. If you set it to false
in oncreate
, you end up with 5 3
instead of 5 4
.
vnode.reuse
doesn't do anyting in current Mithril, this is a feature of that PR that allows one to set a vnode marked as non-recyclable by the engine as recyclable (that occurs just before a hook that can access the DOM fires, the hooks that don't fire have no impact).
Edit again: Here's a version where reuse
can be toggled on a per vnode basis.
Making some more progress on my sample case: replacing recycling
with shouldRecycle && pool != null
in the condition before insertNode
makes the 4
disappear. IIUC, the only nodes that must be inserted are those that come from the pool when shouldUpdate
is true...
Still that doesn't get us rid of the 5, nor does it solve @starsolaris' crash.
Edit: my bad, good news, I had not picked the right Flems to test @starsolaris' sample. replacing recycling
with shouldRecycle && pool != null
(the first occurrence) does solve the problem.
@pygy I seriously look forward to seeing this PR...
@pygy I checked your example with fix in my workflow. I cannot reproduce exception. But i still has another problem (I thought it was because of exception): Example
Mithril does not remove some nodes (green rectangle on screen)
@starsolaris Thanks for verifying.
The rectangle remaining on screen probably has the same cause as the 5
not being removed in my reduction. Needs more digging (maybe this evening CET) :-)
I cannot make example for now, but in next branch with fix i get new exception:
TypeError: node is null
removeNodeFromDOM@mithril.js:833:7
continuation@mithril.js:820:8
removeNode@mithril.js:810:3
removeNodes@mithril.js:789:10
updateNodes@mithril.js:623:4
updateFragment@mithril.js:668:3
updateNode@mithril.js:643:16
updateNodes@mithril.js:553:12
updateElement@mithril.js:702:4
updateNode@mithril.js:644:15
updateComponent@mithril.js:716:9
updateNode@mithril.js:647:9
updateNodes@mithril.js:553:12
render@mithril.js:1023:3
_16/</run0@mithril.js:1086:4
sync@mithril.js:1066:52
throttle/</pending<@mithril.js:1041:5
@starsolaris Could you try with this version that disables the pool altogether?
@pygy i checked this version: no exceptions, no not removed nodes. Also, I don't fully checked it mithril or not, but no longer leak memory in my app.
@pygy For context, Inferno has the option to disable pooling, which avoids certain glitches with custom elements. We may want to investigate this option, too (if for anything, just testing).
@isiahmeadows #1675 sets vnode.reuse
to false
for custom elements, and lets users opt in/out of the pool with conservative defaults: vnode.reuse
is set to false
b a before ook that can touch vnode.dom
fires. This assumes that you wont touch a parent or a child node from a hook.
@starsolaris you had memory leaks otherwise?
@pygy Oh okay. I forgot about that. (I've literally never used it outside Mithril core.)
@pyty with the version that disables the pool, i had no memory leak for now.
@pygy is there any progress on this issue?
@starsolaris No progress last week, sorry. Hopefully I'll finish this in the coming days.
Mithril throw error to console
Current Behavior
TypeError: Argument 1 of Node.appendChild is not an object.
Steps to Reproduce (for bugs)
Example
Your Environment
On FF 52.4.0 and Edge 15 reproduced on every run, on Chrome 61 not every run. Windows 10