Aggregation creates two extra aggregates when it encounters {media: screen} in a library declaration

Created on 29 March 2016, about 8 years ago
Updated 20 August 2023, 10 months ago

Problem/Motivation

Viewing the front page of a Drupal 10.1 install as user 1 shows the following CSS aggregates in the header.

As you can see, there are four aggregates, with the second aggregate including media="screen".

    <link rel="stylesheet" media="all" href="/sites/default/files/css/css_AI3tdfWguXKwGYQh77azpIWFB75vRNg_QczKMd7wJAo.css?delta=0&amp;language=en&amp;theme=olivero&amp;include=contextual/drupal.contextual-links%2Csystem/base%2Colivero/global-styling%2Ccore/drupal.active-link%2Colivero/powered-by-block%2Colivero/feed%2Cviews/views.module%2Colivero/navigation-secondary%2Colivero/search-wide%2Colivero/navigation-primary%2Colivero/search-narrow%2Ccore/modernizr%2Ccore/drupal.debounce%2Ctoolbar/toolbar%2Cuser/drupal.user.icons%2Ccore/shepherd%2Ctour/tour-styling%2Ctour/tour%2Ccore/drupal.tabbingmanager%2Ccontextual/drupal.contextual-toolbar%2Cshortcut/drupal.shortcut%2Ctoolbar/toolbar.escapeAdmin%2Cbig_pipe/big_pipe" />
<link rel="stylesheet" media="screen" href="/sites/default/files/css/css_5FA3K14RQkYOhjLi22sUkXa3rr9UmOmp2HuTM9zq2n4.css?delta=1&amp;language=en&amp;theme=olivero&amp;include=contextual/drupal.contextual-links%2Csystem/base%2Colivero/global-styling%2Ccore/drupal.active-link%2Colivero/powered-by-block%2Colivero/feed%2Cviews/views.module%2Colivero/navigation-secondary%2Colivero/search-wide%2Colivero/navigation-primary%2Colivero/search-narrow%2Ccore/modernizr%2Ccore/drupal.debounce%2Ctoolbar/toolbar%2Cuser/drupal.user.icons%2Ccore/shepherd%2Ctour/tour-styling%2Ctour/tour%2Ccore/drupal.tabbingmanager%2Ccontextual/drupal.contextual-toolbar%2Cshortcut/drupal.shortcut%2Ctoolbar/toolbar.escapeAdmin%2Cbig_pipe/big_pipe" />
<link rel="stylesheet" media="all" href="/sites/default/files/css/css_kuhPJIoUEPrw6lSo2T4L7_-4v37wAeKmhT8fPFwvE1E.css?delta=2&amp;language=en&amp;theme=olivero&amp;include=contextual/drupal.contextual-links%2Csystem/base%2Colivero/global-styling%2Ccore/drupal.active-link%2Colivero/powered-by-block%2Colivero/feed%2Cviews/views.module%2Colivero/navigation-secondary%2Colivero/search-wide%2Colivero/navigation-primary%2Colivero/search-narrow%2Ccore/modernizr%2Ccore/drupal.debounce%2Ctoolbar/toolbar%2Cuser/drupal.user.icons%2Ccore/shepherd%2Ctour/tour-styling%2Ctour/tour%2Ccore/drupal.tabbingmanager%2Ccontextual/drupal.contextual-toolbar%2Cshortcut/drupal.shortcut%2Ctoolbar/toolbar.escapeAdmin%2Cbig_pipe/big_pipe" />
<link rel="stylesheet" media="all" href="/sites/default/files/css/css_qKcdHo1cKu_xYxsR9LUksx-DrCUAFfMtkTdFg2jt9CM.css?delta=3&amp;language=en&amp;theme=olivero&amp;include=contextual/drupal.contextual-links%2Csystem/base%2Colivero/global-styling%2Ccore/drupal.active-link%2Colivero/powered-by-block%2Colivero/feed%2Cviews/views.module%2Colivero/navigation-secondary%2Colivero/search-wide%2Colivero/navigation-primary%2Colivero/search-narrow%2Ccore/modernizr%2Ccore/drupal.debounce%2Ctoolbar/toolbar%2Cuser/drupal.user.icons%2Ccore/shepherd%2Ctour/tour-styling%2Ctour/tour%2Ccore/drupal.tabbingmanager%2Ccontextual/drupal.contextual-toolbar%2Cshortcut/drupal.shortcut%2Ctoolbar/toolbar.escapeAdmin%2Cbig_pipe/big_pipe" />

The media="screen" contains only the CSS file for tour-styling, due to this:

tour-styling:
  version: VERSION
  css:
    component:
      css/tour.module.css: { media: screen }

I think when we added media support many years ago, we thought it'd add one extra file to support media="screen" (and that it would mostly be used for media="print"), however in fact it turns one aggregate into three which is a lot of extra http requests.

This is because we also deal with weights of assets, so if some assets in an aggregate need to go before tour, and some after, for it to be in the middle there have to be three files. And we also add weights based just on the order that files are added to the page, so that's pretty much all the time unless an asset with media screen happened to be the very last or very first one. Even if we remove weight support, unless we explicitly put screen assets first or last, they could still end up in the middle and require their own aggregate.

Proposed resolution

Inline media declarations during aggregation, for anything that is not media="print", this means that the common case of media="screen" will be included in the same aggregates. Since we're concerned about front end performance on screens, and not worried about a few extra CSS bytes when someone's printing a web page, there should not be a downside to doing it like this.

All browsers that Drupal supports, support nested media queries now that we've dropped support for IE11.

Here's how the CSS aggregates for exactly the same page look after applying the patch and clearing caches:

  <link rel="stylesheet" media="all" href="/sites/default/files/css/css_fp0O1ULW3vedV1lZnnaJEzM2rc-NGp8-8c7NCRZR1ng.css?delta=0&amp;language=en&amp;theme=olivero&amp;include=contextual/drupal.contextual-links%2Csystem/base%2Colivero/global-styling%2Ccore/drupal.active-link%2Colivero/powered-by-block%2Colivero/feed%2Cviews/views.module%2Colivero/navigation-secondary%2Colivero/search-wide%2Colivero/navigation-primary%2Colivero/search-narrow%2Ccore/modernizr%2Ccore/drupal.debounce%2Ctoolbar/toolbar%2Cuser/drupal.user.icons%2Ccore/shepherd%2Ctour/tour-styling%2Ctour/tour%2Ccore/drupal.tabbingmanager%2Ccontextual/drupal.contextual-toolbar%2Cshortcut/drupal.shortcut%2Ctoolbar/toolbar.escapeAdmin%2Cbig_pipe/big_pipe" />
<link rel="stylesheet" media="all" href="/sites/default/files/css/css_qKcdHo1cKu_xYxsR9LUksx-DrCUAFfMtkTdFg2jt9CM.css?delta=1&amp;language=en&amp;theme=olivero&amp;include=contextual/drupal.contextual-links%2Csystem/base%2Colivero/global-styling%2Ccore/drupal.active-link%2Colivero/powered-by-block%2Colivero/feed%2Cviews/views.module%2Colivero/navigation-secondary%2Colivero/search-wide%2Colivero/navigation-primary%2Colivero/search-narrow%2Ccore/modernizr%2Ccore/drupal.debounce%2Ctoolbar/toolbar%2Cuser/drupal.user.icons%2Ccore/shepherd%2Ctour/tour-styling%2Ctour/tour%2Ccore/drupal.tabbingmanager%2Ccontextual/drupal.contextual-toolbar%2Cshortcut/drupal.shortcut%2Ctoolbar/toolbar.escapeAdmin%2Cbig_pipe/big_pipe" />

As you can see, this reduces four aggregates down to two. The reason we still have two aggregates instead of one, is because core intentionally puts theme CSS into its own aggregate, that's unrelated to this change and by design.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Fixed

Version

10.0 ✨

Component
Asset libraryΒ  β†’

Last updated 1 day ago

No maintainer
Created by

πŸ‡¬πŸ‡§United Kingdom catch

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.69.0 2024