Open
Description
In our application we frequently have reactive graphs that contain 10,000s of nodes connected among 100,000s of edges. This means that even propagating the dirty flag eagerly can noticeably hang the CPU thread. Our implementation of Signals has the ability to mark a node as preventDirtyPropagationViaRecalculation = true
.
The implementation is fairly simple:
// in `notify` step
node.dirty = true;
if (node.preventDirtyPropagationViaRecalculation) {
preventDirtyPropagationViaRecalculationQueue.push(node);
} else {
markAllConsumersOfNodeAsDirty(node);
}
// After whatever began the `notify`
const nodes = preventDirtyPropagationViaRecalculationQueue.slice();
preventDirtyPropagationViaRecalculationQueue.length = 0;
for (const node of nodes) {
const prevValueVersion = node.version; // This is a bit over-simplified, we actually need to grab this version when we store it in the queue, I think.
producerUpdateValueVersion(node);
if (node.version !== prevValueVersion) {
markAllConsumersOfNodeAsDirty(node);
}
}
When applied judiciously, this utility can dramatically improve the performance of a graph where their are certain nodes that are frequently invalidated and read, but only infrequently actually change. When applied inappropriately it is capable of turning full reactive graphs into a push-based system, which is usually very harmful to performance.
Metadata
Metadata
Assignees
Labels
No labels