mirror of
https://github.com/servo/servo.git
synced 2025-09-27 15:20:09 +01:00
script: Make stylesheets loaded via <link>
elements block the rendering (#39536)
Stylesheets loaded via the `<link>` element should block the rendering of the page according to the HTML specification [1]. This change makes it so that they do this and, in addition, we do not take reftest screenshots until all no element is blocking the rendering. This change does not add support for the `blocking` attribute of `<link>`, but that can be added in a follow change. In addition to fixing a few tests, this change likely makes other tests no longer intermittent. We will need to watch CI runs after this lands in order to verify that though. Testing: This change fixes at least two WPT tests. Fixes: #26424. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
6aa82309c3
commit
55d094a871
5 changed files with 46 additions and 7 deletions
|
@ -350,6 +350,9 @@ pub(crate) struct Document {
|
||||||
pending_parsing_blocking_script: DomRefCell<Option<PendingScript>>,
|
pending_parsing_blocking_script: DomRefCell<Option<PendingScript>>,
|
||||||
/// Number of stylesheets that block executing the next parser-inserted script
|
/// Number of stylesheets that block executing the next parser-inserted script
|
||||||
script_blocking_stylesheets_count: Cell<u32>,
|
script_blocking_stylesheets_count: Cell<u32>,
|
||||||
|
/// Number of elements that block the rendering of the page.
|
||||||
|
/// <https://html.spec.whatwg.org/multipage/#implicitly-potentially-render-blocking>
|
||||||
|
render_blocking_element_count: Cell<u32>,
|
||||||
/// <https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing>
|
/// <https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing>
|
||||||
deferred_scripts: PendingInOrderScriptVec,
|
deferred_scripts: PendingInOrderScriptVec,
|
||||||
/// <https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible>
|
/// <https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible>
|
||||||
|
@ -1728,6 +1731,21 @@ impl Document {
|
||||||
count_cell.set(count_cell.get() - 1);
|
count_cell.set(count_cell.get() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn render_blocking_element_count(&self) -> u32 {
|
||||||
|
self.render_blocking_element_count.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn increment_render_blocking_element_count(&self) {
|
||||||
|
let count_cell = &self.render_blocking_element_count;
|
||||||
|
count_cell.set(count_cell.get() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn decrement_render_blocking_element_count(&self) {
|
||||||
|
let count_cell = &self.render_blocking_element_count;
|
||||||
|
assert!(count_cell.get() > 0);
|
||||||
|
count_cell.set(count_cell.get() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn invalidate_stylesheets(&self) {
|
pub(crate) fn invalidate_stylesheets(&self) {
|
||||||
self.stylesheets.borrow_mut().force_dirty(OriginSet::all());
|
self.stylesheets.borrow_mut().force_dirty(OriginSet::all());
|
||||||
|
|
||||||
|
@ -2705,6 +2723,10 @@ impl Document {
|
||||||
//
|
//
|
||||||
// Returns the set of reflow phases run as a [`ReflowPhasesRun`].
|
// Returns the set of reflow phases run as a [`ReflowPhasesRun`].
|
||||||
pub(crate) fn update_the_rendering(&self) -> ReflowPhasesRun {
|
pub(crate) fn update_the_rendering(&self) -> ReflowPhasesRun {
|
||||||
|
if self.render_blocking_element_count() > 0 {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
|
||||||
if self.has_pending_animated_image_update.get() {
|
if self.has_pending_animated_image_update.get() {
|
||||||
self.image_animation_manager
|
self.image_animation_manager
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -3389,7 +3411,8 @@ impl Document {
|
||||||
has_focus: Cell::new(has_focus),
|
has_focus: Cell::new(has_focus),
|
||||||
current_script: Default::default(),
|
current_script: Default::default(),
|
||||||
pending_parsing_blocking_script: Default::default(),
|
pending_parsing_blocking_script: Default::default(),
|
||||||
script_blocking_stylesheets_count: Cell::new(0u32),
|
script_blocking_stylesheets_count: Default::default(),
|
||||||
|
render_blocking_element_count: Default::default(),
|
||||||
deferred_scripts: Default::default(),
|
deferred_scripts: Default::default(),
|
||||||
asap_in_order_scripts_list: Default::default(),
|
asap_in_order_scripts_list: Default::default(),
|
||||||
asap_scripts_set: Default::default(),
|
asap_scripts_set: Default::default(),
|
||||||
|
|
|
@ -2347,6 +2347,10 @@ impl Window {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if document.render_blocking_element_count() > 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Checks if the html element has reftest-wait attribute present.
|
// Checks if the html element has reftest-wait attribute present.
|
||||||
// See http://testthewebforward.org/docs/reftests.html
|
// See http://testthewebforward.org/docs/reftests.html
|
||||||
// and https://web-platform-tests.org/writing-tests/crashtest.html
|
// and https://web-platform-tests.org/writing-tests/crashtest.html
|
||||||
|
|
|
@ -277,6 +277,15 @@ impl FetchResponseListener for StylesheetContext {
|
||||||
document.decrement_script_blocking_stylesheet_count();
|
document.decrement_script_blocking_stylesheet_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From <https://html.spec.whatwg.org/multipage/#link-type-stylesheet>:
|
||||||
|
// > A link element of this type is implicitly potentially render-blocking if the element
|
||||||
|
// > was created by its node document's parser.
|
||||||
|
if matches!(self.source, StylesheetContextSource::LinkElement { .. }) &&
|
||||||
|
owner.parser_inserted()
|
||||||
|
{
|
||||||
|
document.decrement_render_blocking_element_count();
|
||||||
|
}
|
||||||
|
|
||||||
document.finish_load(LoadType::Stylesheet(self.url.clone()), CanGc::note());
|
document.finish_load(LoadType::Stylesheet(self.url.clone()), CanGc::note());
|
||||||
|
|
||||||
if let Some(any_failed) = owner.load_finished(successful) {
|
if let Some(any_failed) = owner.load_finished(successful) {
|
||||||
|
@ -377,6 +386,15 @@ impl ElementStylesheetLoader<'_> {
|
||||||
document.increment_script_blocking_stylesheet_count();
|
document.increment_script_blocking_stylesheet_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From <https://html.spec.whatwg.org/multipage/#link-type-stylesheet>:
|
||||||
|
// > A link element of this type is implicitly potentially render-blocking if the element
|
||||||
|
// > was created by its node document's parser.
|
||||||
|
if matches!(context.source, StylesheetContextSource::LinkElement { .. }) &&
|
||||||
|
owner.parser_inserted()
|
||||||
|
{
|
||||||
|
document.increment_render_blocking_element_count();
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#default-fetch-and-process-the-linked-resource
|
// https://html.spec.whatwg.org/multipage/#default-fetch-and-process-the-linked-resource
|
||||||
let global = self.element.global();
|
let global = self.element.global();
|
||||||
let request = create_a_potential_cors_request(
|
let request = create_a_potential_cors_request(
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[parser-inserted-stylesheet-link.html]
|
|
||||||
[Rendering is blocked before render-blocking resources are loaded]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[remove-attr-stylesheet-link-keeps-blocking.html]
|
|
||||||
[Rendering is blocked before render-blocking resources are loaded]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue