Problem/Motivation

When aggregating CSS & JS assets, the grouping is hugely important. Drupal 8's current grouping algorithm is old, and often results in inefficient groups.

Proposed resolution

Paraphrasing from #977844-15: Remove the 'every_page' option for CSS/JS assets: it is confusing, even damaging:
Every single asset in Drupal 8 is now loaded through asset libraries. That also means we know about all dependencies. Which means we can build a dependency tree, and thus we can calculate which assets appear on every page, and put those in a separate group.

Remaining tasks

TBD

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

Wim Leers created an issue. See original summary.

catch’s picture

Category: Feature request » Task
dawehner’s picture

I'm curious whether for example for this case, the calculation could be moved into a asynchron place, so by default return basically what we do know
but then also add for example a queue item, which then does the full calculation, which might be computational intensive.

wim leers’s picture

#3: Yep, we should also explore that. But, it could be that it's cheap/fast enough to analyze the entire tree at once. IDK yet :) One of the few places in core where we can actually play/experiment with algorithms to find a good solution!

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

catch’s picture

For CSS, I was thinking about this issue, but then found #2989324: Allow CSS to be added at end of page by rendering assets with placeholders and I think that would help here - i.e. placeholdered content gets it's CSS asset links rendered alongside it, instead of collected and eventually rendered in the head.

That would give us less libraries rendered in the HTML head, meaning less render blocking CSS. We'd still want to optimize the grouping but the results would be very different.

wim leers’s picture

👍

Note that we already do this, and have been for over half a decade, in one case: BigPipe serving responses to no-JS clients.

ambient.impact’s picture

I'm very interested in seeing how this works out because making aggregation work - especially for JavaScript - was a nightmare for RefreshLess 2.x: #3414538: Turbo: Implement additive JavaScript aggregation to prevent multiple evaluation

This particular improvement might be less relevant to that project since it was more the additive part that had to be implemented, but anything core can do to make the library system even more predictable would be awesome.

Also, this makes me wonder if we get core to provide a list of all possible aggregates given the known dependency trees, could we then use that as part of a post-deploy process to proactively/preemptively build all those aggregates? That would be awesome from a performance point of view.

catch’s picture

Also, this makes me wonder if we get core to provide a list of all possible aggregates given the known dependency trees, could we then use that as part of a post-deploy process to proactively/preemptively build all those aggregates?

We can get all the libraries. Then calculate every possible combination of libraries and pass it into AssetResolver. Aggregation will already normalize the list to the minimal representative set and calculate the resulting aggregate, so if 50 combinations of libraries result in the same actual libraries loaded due to dependencies, you'd still only get one aggregate. At least since #3467860: Ensure consistent ordering when calculating library asset order. However there will still be more or less impossible combinations of libraries (a slider for the front page + views_ui or similar). There are some other options to improve performance like using FileCache for individual file optimization, and maybe bringing back the stale aggregate file threshold (at least on production) to leave files on disk for 30 days across cache clears - we used to do that prior to the recent changes because it was required, now it's not required but it might still be good.

ambient.impact’s picture

🤔🤔🤔 #3467860: Ensure consistent ordering when calculating library asset order will definitely be helpful for this. Will have to experiment with 10.4 when I get a chance.

I have mixed feelings about the stale file threshold: I can see it being useful for some smaller sites and it would be nice to have cache clears not wipe out aggregates, but on the other hand, I feel like it's treating a symptom and not the root cause; the root cause usually being that it's the tool someone reaches for when they don't know how to use update hooks, the Cache API (tag invalidation, etc.), or the appropriate service to clear/rebuild a specific thing they need. That's specifically why I created the Rebuilder module, which can rebuild just aggregated assets among several other things.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.