Skip to content
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

cache visibility check results for reuse within a single operation #24

Merged
merged 1 commit into from
May 10, 2021
Merged

cache visibility check results for reuse within a single operation #24

merged 1 commit into from
May 10, 2021

Conversation

just-boris
Copy link
Contributor

@just-boris just-boris commented May 8, 2021

My naive attempt to fix: theKashey/react-focus-lock#151

I confirmed this in my real application case, it prevents Jest test from getting timed out.

@theKashey
Copy link
Owner

size-limit is failing the build. Is configured a bit tight.

Thank you for making this change and proving that it is a fix. However, before we proceed I need to do one more little thing - I want to track the existing "complexity" to understand the difference.

PS: technically speaking there is a slightly better way to manage this use case - wrap the single memoization target - isVisible with kashe, and switch universes at the top (visibilityCache) to throw-away ones using inboxed helper.
Unfortunately, that is +1kb of the code, which is +30% to the total size of this library.

@theKashey
Copy link
Owner

Complexity check has been merged - #25 - and everything is VERY BAD

Please merge with a master and lets see much much crap will be gone.

src/utils/is.ts Outdated
return false;
}
const cached = visibilityCache.get(node)
if(cached) {
Copy link
Owner

Choose a reason for hiding this comment

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

that is working only for "true" cases, while false is legit as well

Suggested change
if(cached) {
if (cached!==undefined) {

src/utils/is.ts Outdated
return cached;
}
// @ts-ignore
const result = node === document ||
Copy link
Owner

Choose a reason for hiding this comment

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

can we extract the actual check to the separate function?
Technically you can just rename "the old one" and then build a cached version next to it.

Copy link
Owner

@theKashey theKashey left a comment

Choose a reason for hiding this comment

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

  • one suggestion
  • and one new test to pass

@codecov
Copy link

codecov bot commented May 10, 2021

Codecov Report

Merging #24 (1dfd4dc) into master (a74297b) will increase coverage by 0.17%.
The diff coverage is 88.88%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #24      +/-   ##
==========================================
+ Coverage   82.69%   82.86%   +0.17%     
==========================================
  Files          20       20              
  Lines         312      321       +9     
  Branches       68       69       +1     
==========================================
+ Hits          258      266       +8     
- Misses         49       50       +1     
  Partials        5        5              
Impacted Files Coverage Δ
src/focusables.ts 35.71% <0.00%> (-2.75%) ⬇️
src/focusMerge.ts 88.57% <100.00%> (+0.33%) ⬆️
src/sibling.ts 91.30% <100.00%> (ø)
src/utils/DOMutils.ts 100.00% <100.00%> (ø)
src/utils/is.ts 90.47% <100.00%> (+4.76%) ⬆️
src/utils/parenting.ts 96.77% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a74297b...1dfd4dc. Read the comment docs.

@just-boris
Copy link
Contributor Author

Applied the suggestions, thanks!

Regarding an extra test, I think the footprint one you added will cover it well. It shows how much the number of calls reduced

@theKashey
Copy link
Owner

Yes! And shows how much.
Probably I should have used a more complicated scenario to make the change more dramatic. But still - it's a win :)

@theKashey theKashey merged commit 66bf0d0 into theKashey:master May 10, 2021
@just-boris
Copy link
Contributor Author

ok, so the fix got merged, but to benefit from it we need to have a release

Is there anything blocking this?

@theKashey
Copy link
Owner

I was just not satisfied with the result numbers and added a few more tests.
As a result I've found that with the very last commit you broke nested memoization - it was caching result only for the very first noded. Not everything.

The result numbers are WAY better, and (again) that's all thanks to you 🎉

@@ -7,7 +7,7 @@ const isElementHidden = (computedStyle: CSSStyleDeclaration): boolean => {
);
};

export const isVisible = (node: HTMLElement | undefined): boolean =>
const isVisible = (node: HTMLElement | undefined): boolean =>
!node ||
// @ts-ignore
node === document ||
Copy link
Owner

Choose a reason for hiding this comment

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

oh no. Nested call is to the same "uncached" isVisible

@theKashey
Copy link
Owner

Published as focus-lock@0.9.1

@just-boris
Copy link
Contributor Author

Very nice! Thanks for doing proper quality assurance of my code :)

jesstelford added a commit to jesstelford/chakra-ui that referenced this pull request Nov 5, 2021
`react-focus-lock@2.5.1` includes a dependency update of `focus-lock` from `0.8.1` -> `0.9.1`. The change in `focus-lock` includes a fix for performance in JSDOM: theKashey/focus-lock#24

JSDOM is used when testing react components in jest and other unit testing frameworks. In particular, when used with `@testing-library/react` for simulating real user input.

Locally tested on an Apple M1 Air using a moderately complex `<Modal>` component (which contained inputs, `react-hook-form` usage, etc).
Before this change: 20,149ms
After this change: 2,347ms

Approx. 10x performance increase.
jesstelford added a commit to jesstelford/chakra-ui that referenced this pull request Nov 5, 2021
`react-focus-lock@2.5.1` includes a dependency update of `focus-lock` from `0.8.1` -> `0.9.1`.
The change in `focus-lock` includes a fix for performance in JSDOM:
theKashey/focus-lock#24
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.

Slow performance in JSDOM
2 participants