fix: [#1882] Fix caching in querySelector and avoid sort #1883
+22
−15
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.
Fixes #1882
This pull request optimizes the
querySelectormethod by fixing caching and avoiding an unnecessary sort step.Caching Bug Fix
The Bug:
The previous implementation of
querySelectordid not update the cache with the result of the query. It would read from the cache, but it would never write the result back to the cache. This meant that for repeated calls with the same selector, the query would be re-executed every time, negating the benefits of caching.The Fix:
The new implementation correctly updates the cache with the result of the query. If an element is found, a
WeakRefto it is stored in the cache. If no element is found,nullis stored.Cache Invalidation:
happy-dominvalidates the cache for all selectors that were affected by the change. The existing unit test coverage confirms that stale values are not returned from the cache.Sorting Algorithm Improvement
In this analysis:
nis the total number of nodes in the DOM (or the relevant subtree).gis the number of selector groups in the query (e.g.,div, phasg=2).Old Algorithm:
gselector groups, the algorithm would traverse the DOM to find the first matching element. In the worst case, this traversal could visit allnnodes. This step is repeated for each group, so the complexity isO(g * n).gmatched elements were then sorted to determine the first one in document order. The complexity of this sort isO(g log g).The total complexity of the old algorithm was O(g * n + g log g).
New Algorithm:
gselector groups. However, instead of collecting all matches and sorting them at the end, it maintains a running "best candidate". When a new match is found, it's compared to the current best, which is a constant timeO(1)operation.The total complexity of the new algorithm is O(g * n), making it more efficient for selectors with multiple selector groups.