Browser Startup
How do first run/first startup experiments work?
Why does synchronously reading Nimbus feature values work for
customizing display features like about:welcome
onboarding and the
default browser prompt? The key invariant is that the display
decisions wait for sessionstore-windows-restored
to show
customizable UI, and therefore we just need Nimbus available to read
at that point. This is arranged either via the --first-startup
flag; or, for subsequent startups, the relevant Nimbus features being
marked isEarlyStartup: true
. When isEarlyStartup: true
, Nimbus
caches all its feature variables as Gecko preferences, ready to be
read during early startup. (See the early startup
docs.)
Customizable display features like about:welcome
or the default
browser prompt are used in
_maybeShowDefaultBrowserPrompt()
,
which is invoked as part of a startup idle task. Startup idle tasks
are scheduled in response to
sessionstore-windows-restored
.
Now, why is sessionstore-windows-restored
late enough for a
first startup experiment? The answer is subtle.
During Firefox launch, final-ui-startup
is
notified,
and in response SessionStore
is initialized. Additionally,
Nimbus/Normandy initialization is started but not
awaited.
Then the command line is
handled.
When --first-startup
is passed, we spin the event loop to allow
Nimbus/Normandy time to complete its initialization and first
fetch
before continuing to process the command line. See the
FirstStartup
module.
(Important caveat: --first-startup
is only used on Windows; see Bug
1872934, for
example.)
This races with SessionStore
, which itself waits for the first
browser window to be shown – in particular, the
sessionstore-windows-restored
notification waits for the first
browser window’s browser-delayed-startup-finished
notification.
This first browser-delayed-startup-finished
notification is not
guaranteed to be after --first-startup
has spun the event loop!
But, when launched with only --first-startup
and flags considered
very early in nsAppRunner.cpp
– as the stub installer
does
– then the first window is guaranteed to be after the event loop
has been spun, and therefore sessionstore-windows-restored
is after
as well. (As a counter-example: try firefox.exe --browser --first-startup
and witness the --browser
flag
creating a window before spinning the event loop, inadvertently racing
against sessionstore-windows-restored
.) Making this deterministic
is tracked by Bug
1944431.
Together, this means that first-startup experiments will be loaded in
time to impact display features such as about:welcome
and the
default browser prompt, and we should not have a “split brain”
scenario in which the Nimbus feature is intermittently unavailable to
the relevant display features.