Conversation
|
Benchmark result main: |
|
PR (commit 1836c3f): |
c9b0359 to
77fc2ea
Compare
|
Comparison with #4085: Tests
Overall, #4119 needs to do more work to match #4085. BenchmarksBasically, #4085 is about 2x as fast as #4119 on Code complexity#4119 deletes a lot of code, which is good. Maybe #4085 could also delete these? Maybe we should just do a color-related refactoring PR before doing any computed style resolution work?
#4119 introduces duplicate code into many property handlers, and makes it so that anyone who writes a property handler has to know which kind of getter to use. I think this is crucial difference for correctness: by making #4119 moves several properties from truly-private ( #4119 exports many functions from #4119 overall seems to need more code to get similar results. (Or, per the tests, actually slightly worse results.) However, the code in #4119 is broken up into clearly-named functions and is pretty easy to follow. #4085 has a separate Both #4085 and #4119 bounce back and forth between Overall, #4085 matches the spec better, with a clear cascaded -> specified -> computed (-> resolved) pipeline all in Another example of where #4119's non-spec architecture makes things more complicated: Overall I think it is possible to make #4119 catch up to #4085, but it needs more work. |
Fixed.
I think it's also fully passing in #4119?
Still 2 regressions but I think it's natural that the tests would fail for
Fixed.
Reverted and made getPropertyValue() always use the metadata.
Reverted.
Changed them truly-private.
Removed some exports.
Added caching mechanism.
Renamed function. |
|
New benchmark result: |
1967566 to
c6008b3
Compare
|
I am going to extract out some pieces of this PR into separate PRs to make it easier to review. (Definitely the colors improvements, maybe the cache bug fix and new WPT.) I will take care of the rebasing. |
domenic
left a comment
There was a problem hiding this comment.
Thanks for your patience.
Test improvement
- #4119 completely fixes
inherit-initial.html. #4085 does not. - #4119 regresses
nested-color-mix-with-currentcolor.html. #4085 keeps it passing. This is because#prepareComputedValueOpts()eagerly resolvescurrentColorinto a concrete value globally, which is not correct. - #4119 partially regresses
system-color-compute.html(onbox-shadowandtext-shadow). #4085 keeps those passing. This is becauseserializeColor()only inspects the first AST node, missing colors inside multi-token values likeshadow.
My worry is that since #4119 does not follow the spec architecture, it might not have a clear path toward parity with #4085. Do you think it will be possible to fix the regressions?
Performance
Both PRs are generally faster than main.
get-computed-style: #4119 is 1.08x-1.25x slower than #4085.get-computed-style-cold: #4119 is 1.07x faster to 1.25x slower than #4085.get-computed-style-property-access: #4119 is 1.29x-1.67x slower than #4085.style-property: #4119 is 1.0x-1.18x faster than #4085.
Overall, #4119 is still a bit slower. I am not sure why, but...
Here is Claude Code's analysis
The performance difference is likely explained by:
- Property access: #4085's
_resolvedValuesis a flatMapcheck + callback. #4119'sgetPropertyValuegoes through#cachedPropertyValuescheck →#getPropertyMetadata(possibly 2 Map lookups +hasVarFunccheck) →#getComputedValue(anotherpropertyDefinitions.hascheck,#getPropertyDefinition, keyword checks) →#resolveLonghandPropertyValue→#prepareComputedValueOpts. There are simply more layers and Map lookups per property access. - Cold path: #4119's
getInheritedPropertyValuemanually walks ancestors in a loop, callingprepareComputedStyleDeclaration+getPropertyValueon each. #4085'sgetComputedValuerecurses through the spec'sgetSpecifiedValue→getComputedValue(parentElement)chain, which benefits from the_styleCache+_resolvedValuescaching at each level.
Code architecture
Overall I think #4119 is easier to understand than #4085 now. It has a clear division between helpers in computed-style.js and the main computations in CSSStyleDeclaration-impl.js.
I still like how #4085 has steps that clearly correspond to the specification. But if you believe the architecture in #4119 is better going forward, I can trust you.
The only issue is that #prepareComputedValueOpts() is quite complicated, and is still incorrect, as discussed above. Maybe more documentation would be helpful. Probably "computed value opts" is not a good name? From what I can see, they are the options fed into the CSS parser when resolving longhands? "longhand parser opts"? But it's mostly about colors, so maybe color stuff should be in the name?
Fixed regressions except box-shadow and text-shadow.
Currently, we only offer color-related options, but I plan to add options to resolve computed values such as relative length, custom properties etc. |
723a58f to
bfcfa0a
Compare
domenic
left a comment
There was a problem hiding this comment.
LGTM, but I guess since you marked it as draft you still have some more tweaks?
|
It is ready, but haven't run benchmark. |
|
If we don't need latest benchmark, please go on. |
|
Benchmark: |
|
Benchmark after updating css-color and dom-selector |
This pull request improves how jsdom resolves computed style values for DOM elements. This includes updating the style calculation logic, which will improve the accuracy and performance of handling computed CSS properties within jsdom.
Fixes #3614, fixes #3339, fixes #3563, fixes #3971, fixes #3972.
Related #3984, #4085, #3615.