Problem/Motivation
This will depend on #3565258: Support library-specific aggregates.
Symfony 6.3 added support for early hints: https://symfony.com/blog/new-in-symfony-6-3-early-hints
This lets you send a 103 header at any point while building the response with early hints: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/103
Most Drupal themes ship with a 'global' CSS library that is loaded on every page.
If we make the 'global' libraries appear in their own dedicated aggregate, which we should anyway, then as soon as the theme is negotiated, we'll know that we need to load that aggregate. Due to #3565258: Support library-specific aggregates it will also be possible to generate a URL to the aggregate given just a single library, we don't need any of the other libraries during the request, because the URL will be self-contained.
That should then allow the browser to start downloading the main theme CSS (the vast majority of the CSS on most pages) before any HTML gets sent.
Steps to reproduce
When you run Lighthouse against a Drupal site, it will tell you to inline critical CSS. However, inlining CSS has various trade-offs (increased document size, breaks browser caching, security issues - see #3499829: Support inlining critical CSS for faster core web vitals for discussion.
Two Lighthouse github issues suggest early hints as another way to deal with render blocking resources - https://github.com/GoogleChrome/lighthouse/issues/13773 and https://github.com/GoogleChrome/lighthouse/issues/13738
Proposed resolution
As soon as the theme has been negotiated, identify the global styles library for the theme, build the URL for the asset aggregate, and send the URL as an early hint.
We may also be able to do this for the system/base library if we're not able to completely get rid of it, or find a way to incorporate it into the global theme library.
Comments
Comment #2
andypostI bet it will need to replace Apache
mod_http2optionH2EarlyHints onwith FrankenPHP to test it properly #3437187: Add Caddyfile configurationComment #3
catchComment #4
catchOpened #3565258: Support library-specific aggregates which is at least theoretically the sole blocker for this issue.
Comment #5
catchComment #6
catch#3565258: Support library-specific aggregates is more or less working, so adding some extra notes here.
Early hints is mostly useful when there's a delay between the early hint being sent and the HTML response - that way the browser actually has time to do something with the early hint before the assets are linked via HTML anyway.
That means it won't be particularly useful to add them to page or dynamic page cache hits - in those cases the HTML response is usually fast anyway.
However, on dynamic page misses, if we have a point where we know we're going to serve an HTML response, but haven't rendered the main content or placeholders yet, then we're potentially able to start those critical asset requests hundreds of milliseconds before the HTML is sent, by that time they will have completed. Even if it's tens of milliseconds it won't hurt.
Unless something better comes up, the most obvious place to do this seems to be in HtmlRenderer - this is the first place we get the active theme (in the standard profile at least) and before the main content and placeholders are rendered.
So in there, we can determine the theme global library, generate asset URLs for that and system/base, and then add those as early hints.
Either as part of #3366561: Support preloading of fonts in the libraries API or in a follow-up, we can do the same for fonts.
On some requests, those files will be the only render blocking assets on the page. This is especially the case for big pipe responses where placeholder assets are rendered via js, so the number of additional libraries sent with the skeleton HTML is ideally none.
When there's a render blocking CSS asset that's not in early hints, then it may be that latency etc. means rendering is still blocked on latency, but even in that case, because the other files are loaded already, it may mean things like LCP images getting loaded faster.
We might want to put system/base in a container parameter so that sites or contrib modules can alter the list of additional libraries to early hint.
Comment #7
catchComment #9
catch@andypost is right in #2, #3570909-9: Support early hints for fonts for more details but we can work towards unblocking this alongside the PHP support issues.