Repository navigation
Conversation
A component whose type sets dashChildrenUpdate (dcc.Tabs, several DMC types) walks all of layoutHashes on every store update, and isFirstLevelPropsChild split both paths for each entry. With many such components mounted, this was the top of the CPU profile. Check the path prefix with startsWith before allocating anything, and walk the keys instead of building an entry pair for each one. The result of the selector does not change. Add a benchmark scenario for this case and unit tests for the selector.
|
4 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Addresses #4032 (it makes this much cheaper, but it's still a scan, so I'm leaving the issue open for you to decide).
Components whose type sets
dashChildrenUpdate(dcc.Tabs, and several DMC types) walk all oflayoutHasheson every store update, andisFirstLevelPropsChildsplit both paths for each entry. As the issue says, the cost is flagged components x changed paths x store updates.This keeps the scan and makes it cheap:
isFirstLevelPropsChildrejects unrelated paths withstartsWithbefore splitting anything, and returns a shared constant for them.determineChangedPropswalksObject.keysinstead of building an entry pair for each path.The selector returns the same thing as before.
Numbers
I added a benchmark scenario,
callback_fanout_children_update: one Input driving N Outputs with Tdcc.Tabsmounted. Median of 3 runs ofpython -m benchmarks.run, production bundle, headless Chrome on an Apple Silicon Mac:devFor reference,
callback_fanout(300 outputs, no Tabs) is about 30 ms on both. So with 300 outputs and 200 Tabs, the extra cost of the Tabs goes from about 216 ms to about 29 ms. The 1000 x 1 row comes from 4 rounds alternating the two builds, because my first pass randevfirst and showed a 4% difference that turned out to be run order.In the profile of the new scenario,
isFirstLevelPropsChild+determineChangedPropsgo from 51% of CPU to 9%. The rest of the suite stays within thresholds. I didn't touchbaseline.json: it comes from CI hardware, so I'd rather not mix my laptop's numbers into it. Happy to change that if you prefer.Why not an index
The issue suggests indexing
layoutHashesby parent, so I tried it in a micro benchmark. One store update, with 1000 entries:layoutHasheschangesA rebuilt index wins with many flagged components, but it's about twice as slow as today with a single
dcc.Tabs, which I'd guess is the most common case. The prefix check is never slower and adds no state. An index kept up to date in the reducer could get the best of both, if the remaining cost still matters for apps like the one in the issue. I noted this in.ai/PERFORMANCE.md.Testing
tests/selectors.test.js: 5 tests throughselectDashProps. They also pass on the old code, since behavior shouldn't change. The sibling case (...,4vs...,40) fails if the segment boundary check is removed.determineChangedPropsside by side over 3000 random store histories, with nested flagged paths and removed entries. Identical on 284160 calls.test_descendant_listening,test_redraw,test_render_typeand the dcctabtests pass.tests/integration/renderer: 88 passed, 3 failed.test_rdps015,016and017fail the same way ondevon my machine (the input isn't cleared before typing, so the text becomesinitialedited), so they aren't related to this.Contributor Checklist
isFirstLevelPropsChildoptionals
CHANGELOG.md