Problem/Motivation

We're still seeing some unexpected layout shifting occasionally in both Chrome and Firefox on Android during page transitions on Omnipedia, usually when first downloading a new set of aggregates (navigating to a page with different ones for the first time in a session) or if the device's screen goes to sleep for a while, probably resulting in certain caches being slow to respond or a re-download being initiated.

Originally, Turbo had this incredibly basic method of adding new stylesheets that didn't take the order of <link> into account, leading to incorrect specificity which was fixed as part of #3488459: Turbo: Reduce or eliminate FOUC due to stylesheets being merged in and removed:

document.head.appendChild(element);

This fixed the specificity issue, but Turbo only delays rendering waiting for new stylesheets for a set amount of time before resuming rendering, so any stylesheets that do end up loading after that point (or even during?) still result in visible jumbling of styles as the browser renders and then re-renders several times as each stylesheet loads.

Note that we may also be able to build on this using the preloader from #3531642: Add a lazy link preloader to warm Turbo and Drupal caches while scrolling to also warm the browser's cached stylesheets by pinging those, but it'll require testing to see if this actually does what we intend. Unclear if this would benefit from #3534032: Turbo: use Cache API for Turbo cache as that may require a service worker.

Steps to reproduce

See above.

Proposed resolution

We have two main options:

  1. Use LoadJS to load them and only insert them once they've all loaded; the library is already included in core and used for various things like the Ajax system.
  2. We can keep the current Turbo code but try inserting the links using the rel="preload" as="style" attributes to have them load without being applied, and only applying them all as rel="stylesheet" in one go when all have loaded. This will need some testing to verify that it results in reliable load events across major browsers.

The ideal solution would allow applying all the new stylesheets in one go in their correct order, meaning that they shouldn't just be added to the document naively, hoping for the best, but loaded/preloaded in the background and applied in one go to minimize or eliminate FOUC, with well defined fallback strategies if one or more stylesheets take longer than a certain amount of time to load.

Remaining tasks

See above.

User interface changes

Less layout shifting and styles being applied/unapplied.

API changes

None probably.

Data model changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ambient.impact created an issue. See original summary.

ambient.impact’s picture

Title: Turbo: Chrome on Android still encounters brief style shifting during RefreshLess loads » Turbo: Still encountering FOUC during RefreshLess loads

  • ambient.impact committed 425dba59 on 2.x
    Issue #3500115: Reduce FOUC significantly by only moving changed styles.
    

alex.skrypnyk’s picture

@ambient.impact
https://git.drupalcode.org/project/refreshless/-/commit/425dba59f7a9d53a...
This commit did not add a credit to me but it used my patch from
https://www.drupal.org/files/issues/2026-01-13/refreshless-3399314-sort-...

Can I please get a credit on either this or 3399314 issue.

Thanks

  • ambient.impact committed 34b207cd on 2.x
    fix: #3500115 Turbo: Still encountering FOUC during RefreshLess loads...

  • ambient.impact committed 5c61f471 on 2.x
    Revert "Issue #3500115: Reduce FOUC significantly by only moving changed...
ambient.impact’s picture

My bad. I'm still getting the hang of the new contribution record system and thought it would give you credit when I updated it on https://new.drupal.org/contribution-record/10016343

I reverted and re-applied the commit (to avoid rewriting history) with the updated commit message tagging you in it. Let me know if that looks good and we can close this issue.