Put theme.js after the stylesheet so Gecko cannot paint unstyled

Root cause of the Firefox-only flash of blue links on the first click after
an idle spell (Bugzilla 1459305, still open): Gecko does not block the
parser on a pending stylesheet, it only suppresses painting, and any layout
flush in that window (an extension content script, a ResizeObserver, a
getComputedStyle) initialises layout and paints the unstyled body. With
theme.js *before* the <link>, nothing stalled the parser while app.css was
coming back from the disk cache, so the whole body was parsed unstyled and
one flush painted it. Chrome blocks rendering on the sheet outright, which
is why it never showed this.

Gecko refuses to run a parser-blocking script while stylesheets are
pending, so a synchronous script placed after the <link> stalls the parser
inside <head>: there is nothing to paint. theme.js still runs before any
body content exists, so has-js and the saved theme are applied pre-paint
exactly as before.

Reproduced with Playwright Firefox, a proxy delaying app.css and an init
script forcing offsetHeight on every mutation: a 1.2 s unstyled paint with
the old order, none with the new order, in both Firefox and Chromium.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MD4VWGq6mGcd8Bg67qyx9k
This commit is contained in:
2026-09-04 19:08:52 +00:00
co-authored by Claude Fable 5.1
parent 1047cf4633
commit 239125a8e5
+5 -1
View File
@@ -5,8 +5,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>{{ page.title }} · The Daily EPUB</title>
<script src="/static/theme.js?v={{ page.asset_version }}"></script>
<link rel="stylesheet" href="/static/app.css?v={{ page.asset_version }}">
{# Keep this synchronous script *after* the stylesheet: Gecko will not run a
parser-blocking script while a stylesheet is pending, so the parser stalls
here and nothing unstyled exists to paint if something forces a layout
flush (Bugzilla 1459305). Chrome blocks rendering on the sheet regardless. #}
<script src="/static/theme.js?v={{ page.asset_version }}"></script>
<link rel="alternate" type="application/atom+xml" title="The Daily EPUB" href="/feed.xml">
<link rel="icon" href="/static/favicon.svg">
</head>