On HQ.training's /settings (stx 0.2.511), two components inside a falsy :if run their onMount on page load and on client navigation:
<div :if="shownPane === 'door-access' && doorsAllowed" data-pane="door-access">
<DoorAccessPane />
</div>shownPane is derived(() => pane() || 'profile') and doorsAllowed is false for the account, so the branch is never shown and its element is not in the DOM after hydration. Yet DoorAccessPane's onMount(daLoad) fires (the same for TillPane in the next :if). Stack of the request it makes:
daLoad
runMountCallbacks runtime.js
(anonymous) runtime.js
Array.forEach
hydrateComponentScopes runtime.jsSo hydrateComponentScopes seems to run the mount callbacks of component scopes that the server rendered inside an :if branch which the client then removes.
A minimal page with the same shape (layout, derived condition with === and &&, a component with onMount) did not reproduce it, on a full load or a client navigation, so something else on the settings page is involved (it is a large page with many panes, components and :if branches; the console also showed "cloned component setup error" and a hydration-invariant warning for another component on that load).
Expected: a component inside an :if branch that is false does not mount until the branch is shown.
HQ worked around the effect at the source of the requests (stacksjs/hq.training b9b0dc6: each pane checks the account before loading), but other pages with hidden panes would still mount and load them.