1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:37:43 +00:00

LibWeb: Let Element cache its list of classes

Instead of string splitting every time you call Element::has_class(),
we now split the "class" attribute value when it changes, and cache
the individual classes as FlyStrings in Element::m_classes.

This makes has_class() significantly faster and moves the pain point
of selector matching somewhere else.
This commit is contained in:
Andreas Kling 2020-05-26 23:07:19 +02:00
parent 16accb71a3
commit 5069d380a8
2 changed files with 15 additions and 9 deletions

View file

@ -97,14 +97,10 @@ void Element::set_attributes(Vector<Attribute>&& attributes)
parse_attribute(attribute.name(), attribute.value()); parse_attribute(attribute.name(), attribute.value());
} }
bool Element::has_class(const StringView& class_name) const bool Element::has_class(const FlyString& class_name) const
{ {
auto value = attribute("class"); for (auto& class_ : m_classes) {
if (value.is_empty()) if (class_ == class_name)
return false;
auto parts = value.split_view(' ');
for (auto& part : parts) {
if (part == class_name)
return true; return true;
} }
return false; return false;
@ -140,8 +136,16 @@ RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_sty
return adopt(*new LayoutInline(*this, move(style))); return adopt(*new LayoutInline(*this, move(style)));
} }
void Element::parse_attribute(const FlyString&, const String&) void Element::parse_attribute(const FlyString& name, const String& value)
{ {
if (name == "class") {
auto new_classes = value.split_view(' ');
m_classes.clear();
m_classes.ensure_capacity(new_classes.size());
for (auto& new_class : new_classes) {
m_classes.unchecked_append(new_class);
}
}
} }
enum class StyleDifference { enum class StyleDifference {

View file

@ -58,7 +58,7 @@ public:
callback(attribute.name(), attribute.value()); callback(attribute.name(), attribute.value());
} }
bool has_class(const StringView&) const; bool has_class(const FlyString&) const;
virtual void apply_presentational_hints(StyleProperties&) const { } virtual void apply_presentational_hints(StyleProperties&) const { }
virtual void parse_attribute(const FlyString& name, const String& value); virtual void parse_attribute(const FlyString& name, const String& value);
@ -86,6 +86,8 @@ private:
Vector<Attribute> m_attributes; Vector<Attribute> m_attributes;
RefPtr<StyleProperties> m_resolved_style; RefPtr<StyleProperties> m_resolved_style;
Vector<FlyString> m_classes;
}; };
template<> template<>