Problem/Motivation

In #3365122, we reverted the CSS collection optimizer service in Drupal 10.1+ to its state prior to Drupal 10.1.

This bought some time, but something else will have to be implemented for 11.0.

Proposed resolution

Given so much has changed in core, any path forward here will be disruptive. After reviewing the landscape of the core issues surrounding supporting the inlining of CSS, I've concluded that there likely is a strong case for supporting this module in Drupal 11+ given the likelihood of a performant core solution for inlining CSS is blocked by some very complicated issues and is likely very far off.

  1. Adjust support range to drop Drupal 10 support. Too much has changed to support two majors here...

  2. Steal some edge case tests from @larowlan from #3499829: Support inlining critical CSS for faster core web vitals 💙

  3. Implement specialized asset collection optimizer and renderer services.

    There will probably be more complexity here, but I don't see any way around that.

  4. Decorate the asset chain cache to prevent downstream cache corruption.

    The decorated cache backend should be able to "remember" which CIDs were associated with the request that could have possibly corrupt assets and prevent the corruption from propagating downstream.

Remaining tasks

This changeset needs some hardcore test coverage added.

User interface changes

None

API changes

Many. Things might spill over into a new major.

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

Luke.Leber created an issue. See original summary.

luke.leber’s picture

StatusFileSize
new4.83 KB

Let's try this, to get started...

luke.leber’s picture

StatusFileSize
new6.52 KB

Let's fix some tests...

luke.leber’s picture

StatusFileSize
new6.66 KB

Fix coding standard violation.

luke.leber’s picture

Status: Active » Needs review

Setting to NR; also requires manual testing against real sites.

alan delval’s picture

Did not work. Tested and found that works sometimes due to how HttpKernel works. The first request file is created and returns an instance of Response, afterward it returns an instance of BinaryFileResponse because the file already exists on file system.

// Since Drupal 10, assets are lazily constructed.
$sub_request = Request::create($asset['data']);

$raw_request = $this->httpKernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST);

if ($raw_request instanceof \Symfony\Component\HttpFoundation\BinaryFileResponse) {
    $css_request = $raw_request->getFile()->getContent();
}
else {
    $css_request = $raw_request->getContent();
}

    $css .= $css_request;
luke.leber’s picture

Thanks for the manual test!

It sounds like it's going to be hard to kernel test this...almost sounds race condition-ny...maybe we'll have to go heavier into functional test territory to land this.

luke.leber’s picture

Status: Needs review » Needs work
catch’s picture

I think it would be more maintainable long term to copy some of the logic in AssetControllerBase::deliver() (can be massively slimmed down because it doesn't need all the request validation) - build what would have been the filename contents from the contents of the $css_assets array, and store it in the Drupal object cache rather than as a file.

luke.leber’s picture

luke.leber’s picture

So there are still some major issues -- namely a failure to inline an asset seems to corrupt the asset resolver cache...and there doesn't seem to be a way to spy on the CIDs to invalidate in those cases 😭.

luke.leber’s picture

Issue summary: View changes
luke.leber’s picture

Issue summary: View changes
luke.leber’s picture

Issue summary: View changes
luke.leber’s picture

luke.leber’s picture

I think that adding test coverage for the group optimizer is all that's left. Everything else should have decent coverage.

The group optimizer is also the most complicated to unit test.