Bug 1758974 - Reuse inherited custom properties if they didn't change after resolution. r=jwatt

This should be cheap and gives us a lot of memory savings for the page
on the bug, by deduplicating the inherited properties between parent and
children.

WebKit implements a similar optimization.

Differential Revision: https://phabricator.services.mozilla.com/D140826
This commit is contained in:
Emilio Cobos Álvarez 2022-03-11 18:12:56 +00:00
Родитель 93e19dc4dd
Коммит 9399d71846
1 изменённых файлов: 26 добавлений и 0 удалений

Просмотреть файл

@ -714,6 +714,22 @@ impl<'a> CustomPropertiesBuilder<'a> {
true
}
fn inherited_properties_match(&self, map: &CustomPropertiesMap) -> bool {
let inherited = match self.inherited {
Some(inherited) => inherited,
None => return false,
};
if inherited.len() != map.len() {
return false;
}
for name in self.seen.iter() {
if inherited.get(*name) != map.get(*name) {
return false;
}
}
true
}
/// Returns the final map of applicable custom properties.
///
/// If there was any specified property, we've created a new map and now we
@ -725,9 +741,19 @@ impl<'a> CustomPropertiesBuilder<'a> {
Some(m) => m,
None => return self.inherited.cloned(),
};
if self.may_have_cycles {
substitute_all(&mut map, &self.seen, self.device);
}
// Some pages apply a lot of redundant custom properties, see e.g.
// bug 1758974 comment 5. Try to detect the case where the values
// haven't really changed, and save some memory by reusing the inherited
// map in that case.
if self.inherited_properties_match(&map) {
return self.inherited.cloned();
}
map.shrink_to_fit();
Some(Arc::new(map))
}