ladybird/Userland/Libraries/LibWeb/CSS/StyleSheetList.h
Andreas Kling 646b37d1a9 LibWeb: Cache CSS rules in buckets to reduce number of rules checked
This patch introduces the StyleComputer::RuleCache, which divides all of
our (author) CSS rules into buckets.

Currently, there are two buckets:
- Rules where a specific class must be present.
- All other rules.

This allows us to check a significantly smaller set of rules for each
element, since we can skip over any rule that requires a class attribute
not present on the element.

This takes the typical numer of rules tested per element on Discord from
~16000 to ~550. :^)

We can definitely improve the cache invalidation. It currently happens
too often due to media queries. And we also need to make sure we
invalidate when mutating style through CSSOM APIs.
2022-02-10 20:52:11 +01:00

63 lines
1.5 KiB
C++

/*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/NonnullRefPtrVector.h>
#include <AK/RefCounted.h>
#include <LibWeb/Bindings/Wrappable.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/Forward.h>
namespace Web::CSS {
class StyleSheetList
: public RefCounted<StyleSheetList>
, public Bindings::Wrappable {
public:
using WrapperType = Bindings::StyleSheetListWrapper;
static NonnullRefPtr<StyleSheetList> create(DOM::Document& document)
{
return adopt_ref(*new StyleSheetList(document));
}
void add_sheet(NonnullRefPtr<CSSStyleSheet>);
void remove_sheet(CSSStyleSheet&);
NonnullRefPtrVector<CSSStyleSheet> const& sheets() const { return m_sheets; }
NonnullRefPtrVector<CSSStyleSheet>& sheets() { return m_sheets; }
RefPtr<CSSStyleSheet> item(size_t index) const
{
if (index >= m_sheets.size())
return {};
return m_sheets[index];
}
size_t length() const { return m_sheets.size(); }
bool is_supported_property_index(u32) const;
int generation() const { return m_generation; }
void bump_generation() { ++m_generation; }
private:
explicit StyleSheetList(DOM::Document&);
DOM::Document& m_document;
NonnullRefPtrVector<CSSStyleSheet> m_sheets;
int m_generation { 0 };
};
}
namespace Web::Bindings {
StyleSheetListWrapper* wrap(JS::GlobalObject&, CSS::StyleSheetList&);
}