Document the design decisions

This commit is contained in:
Ivan Akulov
2023-11-25 02:18:58 +01:00
parent d1a5bc75ab
commit d4484be0c3
2 changed files with 28 additions and 0 deletions
@@ -49,6 +49,11 @@ function MiniMapNodes({
return (
<>
{nodes.map((nodeId) => (
// The split of responsibilities between MiniMapNodes and
// NodeComponentWrapper may appear weird. However, its designed to
// minimize the cost of updates when individual nodes change.
//
// For more details, see a similar commit in `NodeRenderer/index.tsx`.
<NodeComponentWrapper
key={nodeId}
id={nodeId}
@@ -77,6 +77,29 @@ const NodeRenderer = (props: NodeRendererProps) => {
<div className="react-flow__nodes" style={containerStyle}>
{nodeIds.map((nodeId) => {
return (
// The split of responsibilities between NodeRenderer and
// NodeComponentWrapper may appear weird. However, its designed to
// minimize the cost of updates when individual nodes change.
//
// For example, when youre dragging a single node, that node gets
// updated multiple times per second. If `NodeRenderer` were to update
// every time, it would have to re-run the `nodes.map()` loop every
// time. This gets pricey with hundreds of nodes, especially if every
// loop cycle does more than just rendering a JSX element!
//
// As a result of this choice, we took the following implementation
// decisions:
// - NodeRenderer subscribes *only* to node IDs and therefore
// rerender *only* when visible nodes are added or removed.
// - NodeRenderer performs all operations the result of which can be
// shared between nodes (such as creating the `ResizeObserver`
// instance, or subscribing to `selector`). This means extra prop
// drilling into `NodeComponentWrapper`, but it means we need to run
// these operations only once instead of once per node.
// - Any operations that youd normally write inside `nodes.map` are
// moved into `NodeComponentWrapper`. This ensures they are
// memorized so if `NodeRenderer` *has* to rerender, it only
// needs to regenerate the list of nodes, nothing else.
<NodeComponentWrapper
key={nodeId}
id={nodeId}