Before talking about asset aggregation in Drupal 8, it’s worth considering whether it’s still relevant after ten years; why improve something that’s about to become obsolete? HTTP/2 allows multiple asset files to share a single TCP connection, which reduces the overhead of multiple requests for multiple files compared to regular HTTP.
While there have obviously been changes to Drupal’s asset aggregation since 2007, the implementation in core has remained remarkably similar:
When rendering CSS and JS in the HTML <head> and the footer, files are put into groups (for example to allow different groups for different media queries). The groups are hashed to create a unique file name. If the file doesn’t exist, within the main page request the file is generated and saved to disk. Then the browser can read the aggregated files from disk.
This has a number of drawbacks:
- In a cold cache situation on a busy site, this means <em>no</em> HTML page can be served until some assets have been written to disk, and each asset has to be created serially.
- This in turn leads to stampedes, with multiple pages trying to generate the same files
- Because everything is done in the page, features like js minification on-the-fly would be prohibitively slow to add.
- The ability to add arbitrary files under arbitrary conditions makes it hard to predict what the aggregates will be without the full context of the main page request.
In 2011 I opened a Drupal core issue to suggest a different approach, based on the way that image derivates in Drupal core work.
Instead of creating files in the main page request, we’d only generate the URL to the files. Then a page controller at the file path intercepts any requests for missing files, and creates them lazily, writing to disk so that the next request can get the file straight from disk. This approach was implemented in two Drupal 7 modules, http://drupal.org/project/agrcache and http://drupal.org/project/advagg but for various reasons it’s never yet been adopted for core.
Drupal 8 requires all assets to be registered via a library, which means instead of dozens or hundreds of individual files added per page, there are usually a handful of libraries (which may include dozens or hundreds of files). From the list of library definitions for a page, it’s possible to recreate the order and groupings of the individual assets.
During 8.0.x’s development cycle we discussed using the library information to build asset aggregate URLs - encoding the information needed to produce the aggregate in the filename itself. This would massively reduce the necessary work in the main request, even compared to agrcache and advagg, however the issue stalled due to numerous pre-requisites and difficulty of implementation.
One of the advantages of the new Drupal 8 release cycle is that even though an issue might not have got into 8.0.x, it can be released in later minor version as long as it maintains backwards compatibility for the public API, and these come up every six months.
The patch still needs some reviews, but with luck might be included in the 8.3.x minor release.