-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
⚡ Performance improvements when using spread in reduce #2937
Conversation
🦋 Changeset detectedLatest commit: e5ca8c3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Storybook demod7147cb7f | 81 komponenter | 182 stories |
const globalRefs = Object.entries(docs) | ||
.filter(([key]) => key.startsWith("global-")) | ||
.reduce( | ||
(acc, [, value]) => [...acc, ...value], | ||
[] as { name: string; value: string | number }[], | ||
.flatMap(([, value]) => | ||
value.map(({ name, value: _value }) => ({ name, value: String(_value) })), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some weird reason, name
becomes any
now 🙃
I found that one way of fixing it is to add type to Object.entries
. I also think we can remove the nested map()
:
const globalRefs = Object.entries<
{ name: string; value: string | number; description?: string }[]
>(docs)
.filter(([key]) => key.startsWith("global-"))
.flatMap(([, value]) => value);
This is a bit ugly though, so you probably want to extract the type.
It might be that it's actually cleaner to use map()
and flat()
separately in this case, b.c. then we don't get that type issue:
const globalRefs = Object.entries(docs)
.filter(([key]) => key.startsWith("global-"))
.map(([, value]) => value)
.flat();
But maybe you can find a better way to fix that type bug...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cound not find a better way to preserve types, but biome complains when not using flatmap, so had to "hack" it by adding the flat()
in the return
const globalRefs = Object.entries(docs)
.filter(([key]) => key.startsWith("global-"))
.map(([, value]) => value);
return (
globalRefs
.flat()
.find(
({ value, name }) =>
semanticValue === value && notBlacklistedName(name),
) ?? null
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like you forgot to push the changes, so I will do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have a changeset for Combobox? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JulianNymark @it-vegard @larseirikhansen What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we follow the semver strategy stictly this would be a patch, but for such small internal changes i often feel it could just hitch a ride on the next update we push. But if we want as a team we could force all changes to be patches in these scenarios. What does everyone think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think small refactoring should be fine to do without needing a changeset, since the changeset is mostly for external eyes, and I guess they would mostly care about features and bugfixes, (maybe performance stuff), but plain refactoring gives users nothing right? (if they inspect our code it might be more readable).
@@ -83,29 +83,27 @@ const FilteredOptionsProvider = ({ | |||
const [isMouseLastUsedInputDevice, setIsMouseLastUsedInputDevice] = | |||
useState(false); | |||
|
|||
const filteredOptionsMap = useMemo( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HalvorHaugan you mean add a changeset to combobox for this change right?
In this case it's a only a refactoring right? (pulling out initialMap
from within the reduce()
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was what I meant, yes. Mainly bc. it's a performance improvement. If it was only a plain refactor that no-one would notice, I would not have a changeset for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I'm for adding it! ⚡ (I didn't realize it was perf in that instance, but that's the whole PR's purpose 😳 )
Description
As a test im using Biome to do some linting and slowly fixing some of the errors found.
This PR is based around the rule: https://biomejs.dev/linter/rules/no-accumulating-spread/
In real applications these changes will have marginal effect for our use since we rarely handle large arrays. The only exception i see is
combobox/FilteredOptions/filteredOptionsContext.tsx
where one in theory could end up having arrays in the thousand or more. (but again the performance-issues from just having 10k+ dom nodes would probably be the real problem long before this)Made a small test-script to compare performance