ladybird/Userland/Libraries/LibWeb/Layout
Andreas Kling afe6abfc09 LibWeb: Use an ancestor filter to quickly reject many CSS selectors
Given a selector like `.foo .bar #baz`, we know that elements with
the class names `foo` and `bar` must be present in the ancestor chain of
the candidate element, or the selector cannot match.

By keeping track of the current ancestor chain during style computation,
and which strings are used in tag names and attribute names, we can do
a quick check before evaluating the selector itself, to see if all the
required ancestors are present.

The way this works:

1. CSS::Selector now has a cache of up to 8 strings that must be present
   in the ancestor chain of a matching element. Note that we actually
   store string *hashes*, not the strings themselves.

2. When Document performs a recursive style update, we now push and pop
   elements to the ancestor chain stack as they are entered and exited.

3. When entering/exiting an ancestor, StyleComputer collects all the
   relevant string hashes from that ancestor element and updates a
   counting bloom filter.

4. Before evaluating a selector, we first check if any of the hashes
   required by the selector are definitely missing from the ancestor
   filter. If so, it cannot be a match, and we reject it immediately.

5. Otherwise, we carry on and evaluate the selector as usual.

I originally tried doing this with a HashMap, but we ended up losing
a huge chunk of the time saved to HashMap instead. As it turns out,
a simple counting bloom filter is way better at handling this.
The cost is a flat 8KB per StyleComputer, and since it's a bloom filter,
false positives are a thing.

This is extremely efficient, and allows us to quickly reject the
majority of selectors on many huge websites.

Some example rejection rates:
- https://amazon.com: 77%
- https://github.com/SerenityOS/serenity: 61%
- https://nytimes.com: 57%
- https://store.steampowered.com: 55%
- https://en.wikipedia.org: 45%
- https://youtube.com: 32%
- https://shopify.com: 25%

This also yields a chunky 37% speedup on StyleBench. :^)
2024-03-22 18:27:32 +01:00
..
AudioBox.cpp
AudioBox.h
AvailableSpace.cpp LibWeb: Port AvailableSpace from DeprecatedString to String 2023-11-28 17:15:27 -05:00
AvailableSpace.h LibWeb: Port AvailableSpace from DeprecatedString to String 2023-11-28 17:15:27 -05:00
BlockContainer.cpp LibWeb: Allocate CSS::ComputedValues objects on the heap 2024-01-27 12:27:44 +01:00
BlockContainer.h LibWeb: Allocate CSS::ComputedValues objects on the heap 2024-01-27 12:27:44 +01:00
BlockFormattingContext.cpp LibWeb: Log a FIXME when encountering an unexpected block-level box 2024-03-22 06:43:57 +01:00
BlockFormattingContext.h LibWeb: Account for absolutely positioned table wrappers 2024-03-07 08:09:04 +01:00
Box.cpp LibWeb: Allocate CSS::ComputedValues objects on the heap 2024-01-27 12:27:44 +01:00
Box.h LibWeb: Allocate CSS::ComputedValues objects on the heap 2024-01-27 12:27:44 +01:00
BoxModelMetrics.cpp
BoxModelMetrics.h
BreakNode.cpp
BreakNode.h LibWeb: Don't generate ::before/::after for BR elements 2023-09-14 21:46:28 +02:00
ButtonBox.cpp LibGfx+LibWeb: Produce font cascade list in CSS font matching algorithm 2023-12-10 17:32:04 +01:00
ButtonBox.h
CanvasBox.cpp LibWeb: Introduce RecordingPainter to serialize painting commands 2023-10-18 10:58:42 +02:00
CanvasBox.h
CheckBox.cpp
CheckBox.h
FlexFormattingContext.cpp LibWeb: Account for margin and padding of justified abspos flex items 2024-03-09 16:02:17 +01:00
FlexFormattingContext.h LibWeb: Make flexbox special definite size cases explicit 2024-02-21 17:54:05 +01:00
FormAssociatedLabelableNode.h
FormattingContext.cpp LibWeb: Skip cells layout in table box width calculation 2024-03-19 11:51:49 +01:00
FormattingContext.h LibWeb: Account for absolutely positioned table wrappers 2024-03-07 08:09:04 +01:00
FrameBox.cpp LibWeb: Stop assuming navigable's existance in FrameBox 2024-01-20 20:34:30 +00:00
FrameBox.h
GridFormattingContext.cpp LibWeb: Use resolve_grid_position for abspos boxes layout in GFC 2024-03-11 15:20:58 +01:00
GridFormattingContext.h LibWeb: Add record_grid_placement() helper in GFC 2024-03-07 08:26:37 +01:00
ImageBox.cpp LibWeb: Visit ImageProvider from Layout::ImageBox 2024-02-27 16:53:13 +01:00
ImageBox.h LibWeb: Visit ImageProvider from Layout::ImageBox 2024-02-27 16:53:13 +01:00
ImageProvider.cpp LibWeb: Generalize ImageBox and ImagePaintable for any ImageProvider 2024-02-19 11:07:30 +01:00
ImageProvider.h LibWeb: Visit ImageProvider from Layout::ImageBox 2024-02-27 16:53:13 +01:00
InlineFormattingContext.cpp LibWeb: Use cached UsedValues pointer in IFC and its helper classes 2024-03-16 14:27:59 +01:00
InlineFormattingContext.h LibWeb: Use cached UsedValues pointer in IFC and its helper classes 2024-03-16 14:27:59 +01:00
InlineLevelIterator.cpp LibWeb: Use cached UsedValues pointer in IFC and its helper classes 2024-03-16 14:27:59 +01:00
InlineLevelIterator.h LibWeb: Use cached UsedValues pointer in IFC and its helper classes 2024-03-16 14:27:59 +01:00
InlineNode.cpp
InlineNode.h
Label.cpp LibWeb: Use cached element name and id where possible 2024-01-13 12:05:36 +01:00
Label.h
LabelableNode.cpp
LabelableNode.h
LayoutState.cpp LibWeb: Detach paintables from *all* DOM nodes before committing layout 2024-03-18 13:42:16 +01:00
LayoutState.h LibWeb: Use the parent container's y offset when finding static position 2024-03-10 18:10:01 +01:00
LineBox.cpp LibWeb: Remove unused LineBoxFragment member 2024-03-18 13:42:16 +01:00
LineBox.h LibWeb: Remove unused LineBox::absolute_rect() and related things 2024-01-20 18:26:14 +01:00
LineBoxFragment.cpp LibWeb: Use separate structure to represent fragments in paintable tree 2024-01-13 10:53:38 +01:00
LineBoxFragment.h LibWeb: Remove unused LineBoxFragment member 2024-03-18 13:42:16 +01:00
LineBuilder.cpp LibWeb: Use cached UsedValues pointer in IFC and its helper classes 2024-03-16 14:27:59 +01:00
LineBuilder.h LibWeb: Use cached UsedValues pointer in IFC and its helper classes 2024-03-16 14:27:59 +01:00
ListItemBox.cpp
ListItemBox.h
ListItemMarkerBox.cpp Everywhere: Rename {Deprecated => Byte}String 2023-12-17 18:25:10 +03:30
ListItemMarkerBox.h Everywhere: Rename {Deprecated => Byte}String 2023-12-17 18:25:10 +03:30
Node.cpp LibWeb: Setup computed values for SVG geometry properties 2024-03-04 10:50:32 +01:00
Node.h LibWeb: Move selection state from layout tree to paint tree 2024-03-18 13:42:16 +01:00
RadioButton.cpp
RadioButton.h
ReplacedBox.cpp
ReplacedBox.h
SVGBox.cpp
SVGBox.h
SVGFormattingContext.cpp LibWeb: Special case SVG masks during layout 2024-03-12 08:51:50 +01:00
SVGFormattingContext.h LibWeb: Add initial support for nesting SVG viewports 2024-01-27 18:12:13 +01:00
SVGGeometryBox.cpp LibWeb: Support transforms, stroking, gradients, etc for SVG <text> 2023-11-05 02:46:46 +01:00
SVGGeometryBox.h LibWeb: Store computed SVG path data/transforms in LayoutState 2023-10-30 19:44:54 +01:00
SVGGraphicsBox.cpp
SVGGraphicsBox.h
SVGMaskBox.cpp LibWeb: Special case SVG masks during layout 2024-03-12 08:51:50 +01:00
SVGMaskBox.h LibWeb: Special case SVG masks during layout 2024-03-12 08:51:50 +01:00
SVGSVGBox.cpp LibWeb: Avoid duplicating SVG viewbox height calculation 2024-03-20 09:09:35 +01:00
SVGSVGBox.h LibWeb: Use CSSPixelFraction to represent aspect ratios 2023-09-04 12:40:17 +02:00
SVGTextBox.cpp LibWeb: Support transforms, stroking, gradients, etc for SVG <text> 2023-11-05 02:46:46 +01:00
SVGTextBox.h LibWeb: Layout SVG <text> elements during layout (not while painting) 2023-10-30 19:44:54 +01:00
SVGTextPathBox.cpp LibWeb: Add initial support for SVG <textPath> 2023-12-19 21:29:03 +01:00
SVGTextPathBox.h LibWeb: Add initial support for SVG <textPath> 2023-12-19 21:29:03 +01:00
TableFormattingContext.cpp LibWeb: Skip cells layout in table box width calculation 2024-03-19 11:51:49 +01:00
TableFormattingContext.h LibWeb: Skip cells layout in table box width calculation 2024-03-19 11:51:49 +01:00
TableGrid.cpp LibWeb: Consider colgroups while calculating table grid size 2023-11-04 17:37:38 +01:00
TableGrid.h AK: Rename GenericTraits to DefaultTraits 2023-11-09 10:05:51 -05:00
TableWrapper.cpp LibWeb: Allocate CSS::ComputedValues objects on the heap 2024-01-27 12:27:44 +01:00
TableWrapper.h LibWeb: Allocate CSS::ComputedValues objects on the heap 2024-01-27 12:27:44 +01:00
TextNode.cpp LibWeb: Store "text for rendering" in TextPaintable 2024-03-18 13:42:16 +01:00
TextNode.h LibWeb: Port Layout::TextNode from DeprecatedString 2023-11-28 17:15:27 -05:00
TreeBuilder.cpp LibWeb: Use an ancestor filter to quickly reject many CSS selectors 2024-03-22 18:27:32 +01:00
TreeBuilder.h LibWeb: Special case SVG masks during layout 2024-03-12 08:51:50 +01:00
VideoBox.cpp LibWeb: Use CSSPixelFraction to represent aspect ratios 2023-09-04 12:40:17 +02:00
VideoBox.h LibWeb: Move viewport subscriptions from BrowsingContext to Document 2023-08-23 20:14:20 +02:00
Viewport.cpp LibWeb: Move selection state from layout tree to paint tree 2024-03-18 13:42:16 +01:00
Viewport.h LibWeb: Move selection state from layout tree to paint tree 2024-03-18 13:42:16 +01:00