Bug 1854151: Optimize the relative selector check path when no relative selector is used. r=emilio

* Lazily calculate changed states and classes when processing pending state & attribute invalidations
* Avoid constructing empty `SmallVec` invalidations when we know there is no invalidation

Differential Revision: https://phabricator.services.mozilla.com/D188733
This commit is contained in:
David Shin 2023-09-20 17:01:09 +00:00
parent 4b221aa6ec
commit 7b67eb8bae
2 changed files with 19 additions and 7 deletions

View file

@ -257,6 +257,10 @@ where
self.add_dependency(dependency, element, *scope);
}
}
fn is_empty(&self) -> bool {
self.invalidations.is_empty()
}
}
impl<'a, E> RelativeSelectorInvalidator<'a, E>
@ -267,9 +271,9 @@ where
pub fn invalidate_relative_selectors_for_this<F>(
self,
stylist: &'a Stylist,
gather_dependencies: F,
mut gather_dependencies: F,
) where
F: Fn(
F: FnMut(
&E,
&Option<E>,
&'a CascadeData,
@ -291,6 +295,9 @@ where
&mut collector,
);
});
if collector.is_empty() {
return;
}
self.invalidate_from_dependencies(collector.get());
}
@ -330,6 +337,9 @@ where
});
}
}
if collector.is_empty() {
return;
}
self.invalidate_from_dependencies(collector.get());
}

View file

@ -7496,8 +7496,8 @@ fn process_relative_selector_invalidations(
None => return,
Some(s) => s,
};
let state_changes = ElementWrapper::new(*element, snapshot_table).state_changes();
let classes_changed = classes_changed(element, snapshot_table);
let mut states = None;
let mut classes = None;
let quirks_mode: QuirksMode = data.stylist.quirks_mode();
let invalidator = RelativeSelectorInvalidator {
@ -7512,6 +7512,8 @@ fn process_relative_selector_invalidations(
&data.stylist,
|element, scope, data, quirks_mode, collector| {
let invalidation_map = data.relative_selector_invalidation_map();
let states = *states.get_or_insert_with(|| ElementWrapper::new(*element, snapshot_table).state_changes());
let classes = classes.get_or_insert_with(|| classes_changed(element, snapshot_table));
if snapshot.id_changed() {
relative_selector_dependencies_for_id(
element.id().map(|id| id.as_ptr().cast_const()).unwrap_or(ptr::null()),
@ -7523,13 +7525,13 @@ fn process_relative_selector_invalidations(
collector,
);
}
relative_selector_dependencies_for_class(&classes_changed, element, scope, quirks_mode, invalidation_map, collector);
relative_selector_dependencies_for_class(&classes, element, scope, quirks_mode, invalidation_map, collector);
snapshot.each_attr_changed(|attr| add_relative_selector_attribute_dependency(element, &scope, invalidation_map, attr, collector));
invalidation_map
.map
.state_affecting_selectors
.lookup_with_additional(*element, quirks_mode, None, &[], state_changes, |dependency| {
if !dependency.state.intersects(state_changes) {
.lookup_with_additional(*element, quirks_mode, None, &[], states, |dependency| {
if !dependency.state.intersects(states) {
return true;
}
collector.add_dependency(&dependency.dep, *element, *scope);