Skip to content

Release 1.0.1 - #219

Open
FlorianRappl wants to merge 7 commits into
mainfrom
devel
Open

Release 1.0.1#219
FlorianRappl wants to merge 7 commits into
mainfrom
devel

Conversation

@FlorianRappl

Copy link
Copy Markdown
Contributor

Types of Changes

Prerequisites

Please make sure you can check the following two boxes:

  • I have read the CONTRIBUTING document
  • My code follows the code style of this project

Contribution Type

What types of changes does your code introduce? Put an x in all the boxes that apply:

  • Bug fix (non-breaking change which fixes an issue, please reference the issue id)
  • New feature (non-breaking change which adds functionality, make sure to open an associated issue first)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Description

CSM 101 (Rest as in the CHANGELOG)

@FlorianRappl FlorianRappl added this to the v1.0.1 milestone Jul 30, 2026
FlorianRappl and others added 4 commits July 31, 2026 09:03
Profiling getComputedStyle over a realistic document (ultra/ETW, 8190 Hz)
showed the cascade path dominated by work that was repeated per element:

- StyleCollection held a lazy sheet sequence, so every enumeration re-walked
  the whole DOM looking for style/link elements. The collection is enumerated
  once per element AND once per ancestor, making StyleExtensions.GetStyleSheets
  48% of the profile on its own. The sequence is now walked once and the
  flattened matching rules cached for the lifetime of the collection, which
  spans a single cascade or render pass.

- CssStyleRule.TryMatch sorted its selector list by descending specificity on
  every match attempt (29% of its own subtree). The list only changes when the
  selector is assigned, so it is sorted there instead. OrderByDescending is
  stable, so equal-specificity ordering is unchanged.

- SortBySpecificity built Tuple objects through SelectMany/OrderBy. Under
  shared generics LINQ's internal ToArray spent 16.6% of the whole profile in
  array covariance checks (CastHelpers.StelemRef). Replaced with a list of
  structs plus an index tie-break that reproduces OrderBy's stability exactly.

- TryMatch re-read DocumentElement per rule per element because scope was
  always passed as null; it is now resolved once per element.

Also drops a per-call filtered list and LINQ closures from TryCreateShorthand
on the parsing path.

Measured with BenchmarkDotNet (MediumRun, idle machine), baseline = devel:

  ComputedStyle   23,169 us -> 5,100 us   (4.5x)   25.19 MB -> 1.41 MB
  RenderTree      29,828 us -> 7,288 us   (4.1x)   56.25 MB -> 5.25 MB

Stylesheet parsing throughput is unchanged (all deltas within error bars);
its allocations drop 2-15% across the eight real-world sample sheets.

Adds CssCascadeBenchmarks to cover the styling side, which had no benchmark.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Speed up cascade resolution by ~4.5x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants