Skip to content

Commit 32f7b62

Browse files
committed
component.Base: resolveVdomUpdate() => add a smarter way to merge scheduled child updates #6244
1 parent a5b454c commit 32f7b62

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

src/component/Base.mjs

+38-22
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,12 @@ class Component extends Base {
402402
}
403403

404404
/**
405-
* @member {String[]} childUpdateCache=[]
405+
* If an update() gets called while a parent is updating, we store the id & distance of the
406+
* requesting component inside the childUpdateCache of the parent, to get resolved once the update is done.
407+
* e.g. childUpdateCache = {'neo-grid-view-1': {distance: 1, resolve: fn}}
408+
* @member {Object} childUpdateCache={}
406409
*/
407-
childUpdateCache = []
410+
childUpdateCache = {}
408411
/**
409412
* Stores the updateDepth while an update is running to enable checks for parent update collisions
410413
* @member {Number|null} currentUpdateDepth=null
@@ -1954,18 +1957,7 @@ class Component extends Base {
19541957
console.warn('vdom parent update conflict with:', parent, 'for:', me)
19551958
}
19561959

1957-
// If our update gets prevented, ensure that the next parent updateDepth
1958-
// includes our own updateDepth
1959-
if (parent.updateDepth !== -1) {
1960-
if (me.updateDepth === -1) {
1961-
parent.updateDepth = -1
1962-
} else {
1963-
// Since updateDepth is 1-based, we need to subtract 1 level
1964-
parent.updateDepth = parent.updateDepth + distance + me.updateDepth -1
1965-
}
1966-
}
1967-
1968-
NeoArray.add(parent.childUpdateCache, me.id);
1960+
parent.childUpdateCache[me.id] = {distance, resolve};
19691961

19701962
// Adding the resolve fn to its own cache, since the parent will trigger
19711963
// a new update() directly on this cmp
@@ -2346,22 +2338,46 @@ class Component extends Base {
23462338
* @protected
23472339
*/
23482340
resolveVdomUpdate(resolve) {
2349-
let me = this;
2341+
let me = this,
2342+
hasChildUpdateCache = !Neo.isEmpty(me.childUpdateCache),
2343+
component;
23502344

23512345
me.doResolveUpdateCache();
23522346

23532347
resolve?.();
23542348

23552349
if (me.needsVdomUpdate) {
2356-
// if a new update is scheduled, we can clear the cache => these updates are included
2357-
me.childUpdateCache = [];
2350+
if (hasChildUpdateCache) {
2351+
Object.entries(me.childUpdateCache).forEach(([key, value]) => {
2352+
component = Neo.getComponent(key);
2353+
2354+
// The component might already got destroyed
2355+
if (component) {
2356+
// Pass callbacks to the resolver cache => getting executed once the following update is done
2357+
value.resolve && NeoArray.add(me.resolveUpdateCache, value.resolve);
2358+
2359+
// Adjust the updateDepth to include the depth of all merged child updates
2360+
if (me.updateDepth !== -1) {
2361+
if (component.updateDepth === -1) {
2362+
me.updateDepth = -1
2363+
} else {
2364+
// Since updateDepth is 1-based, we need to subtract 1 level
2365+
me.updateDepth = me.updateDepth + value.distance + component.updateDepth - 1
2366+
}
2367+
}
2368+
}
2369+
});
2370+
2371+
me.childUpdateCache = {}
2372+
}
23582373

23592374
me.update()
2360-
} else if (me.childUpdateCache) {
2361-
[...me.childUpdateCache].forEach(id => {
2362-
Neo.getComponent(id)?.update();
2363-
NeoArray.remove(me.childUpdateCache, id)
2364-
})
2375+
} else if (hasChildUpdateCache) {
2376+
Object.keys(me.childUpdateCache).forEach(key => {
2377+
Neo.getComponent(key)?.update()
2378+
});
2379+
2380+
me.childUpdateCache = {}
23652381
}
23662382
}
23672383

0 commit comments

Comments
 (0)