Skip to content

Commit a94335d

Browse files
committed
LibWeb: Block rendering while waiting for CSS @import downloads
The implementation here is a ad-hoc, but there's no clear spec for exactly how to handle "critical subresources" blocking rendering. For now, this is overly conservative but fixes ugly FOUC on some websites like https://hey.com/
1 parent 36c6079 commit a94335d

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

Libraries/LibWeb/CSS/CSSImportRule.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,15 @@ void CSSImportRule::fetch()
123123
// FIXME: Figure out the "correct" way to delay the load event.
124124
m_document_load_event_delayer.emplace(*m_document);
125125

126+
// AD-HOC: Track pending import rules to block rendering until they are done.
127+
m_document->add_pending_css_import_rule({}, *this);
128+
126129
// 4. Fetch a style resource from parsedUrl, with stylesheet parentStylesheet, destination "style", CORS mode "no-cors", and processResponse being the following steps given response response and byte stream, null or failure byteStream:
127130
(void)fetch_a_style_resource(parsed_url.value(), { parent_style_sheet }, Fetch::Infrastructure::Request::Destination::Style, CorsMode::NoCors,
128-
[strong_this = GC::Ref { *this }, parent_style_sheet = GC::Ref { parent_style_sheet }, parsed_url = parsed_url.value()](auto response, auto maybe_byte_stream) {
131+
[strong_this = GC::Ref { *this }, parent_style_sheet = GC::Ref { parent_style_sheet }, parsed_url = parsed_url.value(), document = m_document](auto response, auto maybe_byte_stream) {
129132
// AD-HOC: Stop delaying the load event.
130-
ScopeGuard guard = [strong_this] {
133+
ScopeGuard guard = [strong_this, document] {
134+
document->remove_pending_css_import_rule({}, strong_this);
131135
strong_this->m_document_load_event_delayer.clear();
132136
};
133137

Libraries/LibWeb/DOM/Document.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ void Document::visit_edges(Cell::Visitor& visitor)
546546
{
547547
Base::visit_edges(visitor);
548548
m_style_scope.visit_edges(visitor);
549+
visitor.visit(m_pending_css_import_rules);
549550
visitor.visit(m_page);
550551
visitor.visit(m_window);
551552
visitor.visit(m_layout_root);
@@ -6284,6 +6285,10 @@ bool Document::is_render_blocked() const
62846285
if (now > max_time_to_block_rendering_in_ms)
62856286
return false;
62866287

6288+
// AD-HOC: Consider pending CSS @import rules as render-blocking
6289+
if (!m_pending_css_import_rules.is_empty())
6290+
return true;
6291+
62876292
return !m_render_blocking_elements.is_empty() || allows_adding_render_blocking_elements();
62886293
}
62896294

@@ -6900,4 +6905,14 @@ StringView to_string(UpdateLayoutReason reason)
69006905
VERIFY_NOT_REACHED();
69016906
}
69026907

6908+
void Document::add_pending_css_import_rule(Badge<CSS::CSSImportRule>, GC::Ref<CSS::CSSImportRule> rule)
6909+
{
6910+
m_pending_css_import_rules.set(rule);
6911+
}
6912+
6913+
void Document::remove_pending_css_import_rule(Badge<CSS::CSSImportRule>, GC::Ref<CSS::CSSImportRule> rule)
6914+
{
6915+
m_pending_css_import_rules.remove(rule);
6916+
}
6917+
69036918
}

Libraries/LibWeb/DOM/Document.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,9 @@ class WEB_API Document
541541
void increment_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>);
542542
void decrement_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>);
543543

544+
void add_pending_css_import_rule(Badge<CSS::CSSImportRule>, GC::Ref<CSS::CSSImportRule>);
545+
void remove_pending_css_import_rule(Badge<CSS::CSSImportRule>, GC::Ref<CSS::CSSImportRule>);
546+
544547
bool page_showing() const { return m_page_showing; }
545548
void set_page_showing(bool);
546549

@@ -1094,6 +1097,8 @@ class WEB_API Document
10941097
// https://html.spec.whatwg.org/multipage/semantics.html#script-blocking-style-sheet-set
10951098
HashTable<GC::Ref<DOM::Element>> m_script_blocking_style_sheet_set;
10961099

1100+
HashTable<GC::Ref<CSS::CSSImportRule>> m_pending_css_import_rules;
1101+
10971102
GC::Ptr<HTML::History> m_history;
10981103

10991104
size_t m_number_of_things_delaying_the_load_event { 0 };

0 commit comments

Comments
 (0)