Skip to content

perf: node memoization#209

Merged
JeanKaddour merged 1 commit intomainfrom
perf/manyNodesv2
Mar 13, 2025
Merged

perf: node memoization#209
JeanKaddour merged 1 commit intomainfrom
perf/manyNodesv2

Conversation

@JeanKaddour
Copy link
Contributor

@JeanKaddour JeanKaddour commented Mar 13, 2025

This pull request focuses on optimizing performance and improving the efficiency of various components and utilities in the codebase. The changes include memoization, the use of lodash's isEqual for deep comparisons, and adjustments to throttling intervals.

Performance improvements:

  • frontend/src/components/nodes/BaseNode.tsx: Simplified deep comparison of finalPredecessors and predecessorNodes using lodash's isEqual, and memoized the BaseNode component with React.memo and a custom comparator ([[1]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-c098027ac12b228afb2f8c876d40858b3b6ba365fbe2556574906ac1b3f7bcdfL473-R479), [[2]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-c098027ac12b228afb2f8c876d40858b3b6ba365fbe2556574906ac1b3f7bcdfL688-R684)).
  • frontend/src/components/nodes/DynamicNode.tsx: Added a custom comparator for memoization, memoized the rendering of output handles, and created a memoized version of the DynamicNode component ([[1]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-9319ee5346cc7086a25e5b34b731977f0e408914f038ee01ce8423f1b63c8b61L3-R23), [[2]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-9319ee5346cc7086a25e5b34b731977f0e408914f038ee01ce8423f1b63c8b61L46-R73), [[3]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-9319ee5346cc7086a25e5b34b731977f0e408914f038ee01ce8423f1b63c8b61L83-R111)).

Memoization and callback optimization:

  • frontend/src/utils/flowUtils.tsx: Introduced a memoized style calculation function for edges, optimized the onNodesChange callback for better performance with a large number of nodes, and adjusted the throttling interval for position updates to improve responsiveness ([[1]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-6cb9d08f4dc140fae1fbf3a657aad6db8b8ff759a5a68045eb0509c32525702eR366-R414), [[2]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-6cb9d08f4dc140fae1fbf3a657aad6db8b8ff759a5a68045eb0509c32525702eL469-R509), [[3]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-6cb9d08f4dc140fae1fbf3a657aad6db8b8ff759a5a68045eb0509c32525702eL585-R592), [[4]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-6cb9d08f4dc140fae1fbf3a657aad6db8b8ff759a5a68045eb0509c32525702eL604-R632), [[5]](https://github.com/PySpur-Dev/pyspur/pull/209/files#diff-6cb9d08f4dc140fae1fbf3a657aad6db8b8ff759a5a68045eb0509c32525702eL637-R667)).

Important

Optimizes performance by memoizing components and utilities, using isEqual for deep comparisons, and adjusting throttling intervals.

  • Components:
    • BaseNode.tsx: Memoized BaseNode with React.memo and custom comparator. Simplified deep comparison of finalPredecessors and predecessorNodes using isEqual.
    • DynamicNode.tsx: Added custom comparator for memoization, memoized rendering of output handles, and created memoized DynamicNode component.
  • Utilities:
    • flowUtils.tsx: Introduced memoized style calculation function for edges. Optimized onNodesChange callback for better performance with many nodes. Adjusted throttling interval for position updates to 32ms.

This description was created by Ellipsis for 5186ad6. It will automatically update as commits are pushed.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Reviewed everything up to 5186ad6 in 1 minute and 38 seconds

More details
  • Looked at 328 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 13 drafted comments based on config settings.
1. frontend/src/components/nodes/BaseNode.tsx:473
  • Draft comment:
    Good refactor: using isEqual simplifies deep comparison. Verify that this change doesn't miss any edge cases from the previous manual comparison.
  • Reason this comment was not posted:
    Confidence changes required: 20% <= threshold 50%
    None
2. frontend/src/components/nodes/DynamicNode.tsx:11
  • Draft comment:
    Ensure that dynamicNodeComparator covers all props that affect rendering. Currently, only a subset of props is compared. Confirm this is sufficient.
  • Reason this comment was not posted:
    Confidence changes required: 40% <= threshold 50%
    None
3. frontend/src/components/nodes/DynamicNode.tsx:63
  • Draft comment:
    Memoizing the output handles as a component is clever. Confirm that dependencies (id, nodeData?.title, isCollapsed) fully capture changes affecting the output.
  • Reason this comment was not posted:
    Confidence changes required: 20% <= threshold 50%
    None
4. frontend/src/utils/flowUtils.tsx:592
  • Draft comment:
    Throttle interval increased to 32ms. Make sure this adjustment meets the desired balance between responsiveness and performance.
  • Reason this comment was not posted:
    Confidence changes required: 20% <= threshold 50%
    None
5. frontend/src/utils/flowUtils.tsx:608
  • Draft comment:
    Combining optimized position changes with non-position changes is a neat improvement. Verify that the deduplication logic in latestPositions works as expected under burst updates.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 50%
    None
6. frontend/src/components/nodes/BaseNode.tsx:473
  • Draft comment:
    Good use of lodash's isEqual for comparing finalPredecessors and predecessorNodes. This simplifies the earlier iterative check and clearly expresses intent.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None
7. frontend/src/components/nodes/BaseNode.tsx:684
  • Draft comment:
    Wrapping BaseNode with React.memo and a custom comparator is a smart optimization to reduce unnecessary re-renders.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None
8. frontend/src/components/nodes/DynamicNode.tsx:11
  • Draft comment:
    The custom comparator in dynamicNodeComparator correctly compares key props (id, selected, zIndex, positions, and data via isEqual), which should help reduce redundant renders.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None
9. frontend/src/components/nodes/DynamicNode.tsx:63
  • Draft comment:
    Memoizing the output handles rendering component using useMemo is a neat optimization. Ensure the dependency list covers all variables that affect the output.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None
10. frontend/src/utils/flowUtils.tsx:367
  • Draft comment:
    Extracting edge style computation into a memoized getEdgeStyle function improves both readability and performance by avoiding redundant inline style calculations.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None
11. frontend/src/utils/flowUtils.tsx:469
  • Draft comment:
    Introducing a conditional helper lines update based on node count is a smart performance improvement. Consider making the threshold configurable if different graph sizes are expected.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None
12. frontend/src/utils/flowUtils.tsx:592
  • Draft comment:
    The throttle interval for position updates was increased to 32ms, trading off some responsiveness for better performance. Ensure this aligns with UX requirements.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50%
    None
13. frontend/src/utils/flowUtils.tsx:597
  • Draft comment:
    Efficiently batching position changes and combining them with non-position updates minimizes dispatch calls. The logic for flushing pending changes is well implemented.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50%
    None

Workflow ID: wflow_uBIFzflx7oD0E7ud


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@JeanKaddour JeanKaddour merged commit c6266eb into main Mar 13, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant