Reuse StylesheetContent for inline style sheets with identical content (#38540)

For duplicate style sheets with identical content, `StylesheetContents`
can be reused to avoid redundant parsing of the inline style sheets.
Since duplicate stylesheets is a common case with web components, this
change will significantly improve performance. Additionally, the cache
hit rate of stylo's `CascadeDataCache` can now be significantly
improved.

When shared `StylesheetContents` is modified, copy-on-write will occur
to avoid affecting other sharers. And then updates the references to
`CssRule` or `PropertyDeclarationBlock` stored in the CSSOMs to ensure
that modifications are made only on the new copy.

Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This commit is contained in:
JoeDow 2025-08-20 20:31:49 +08:00 committed by GitHub
parent f6b77f94e2
commit 6e6ef513a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 711 additions and 125 deletions

View file

@ -214,6 +214,9 @@ impl FetchResponseListener for StylesheetContext {
.is_none_or(|generation| generation == link.get_request_generation_id());
if is_stylesheet_load_applicable {
let shared_lock = document.style_shared_lock().clone();
#[cfg(feature = "tracing")]
let _span = tracing::trace_span!("ParseStylesheet", servo_profiling = true)
.entered();
let sheet = Arc::new(Stylesheet::from_bytes(
&data,
UrlExtraData(final_url.get_arc()),
@ -235,6 +238,9 @@ impl FetchResponseListener for StylesheetContext {
}
},
StylesheetContextSource::Import(ref stylesheet) => {
#[cfg(feature = "tracing")]
let _span =
tracing::trace_span!("ParseStylesheet", servo_profiling = true).entered();
Stylesheet::update_from_bytes(
stylesheet,
&data,