Problem/Motivation

Currently, whenever a CSS file is added that uses a media query in the options array it creates a new aggregation group when processed. This introduces a frontend performance issue on sites that use many different media queries as it potentially raises the number of aggregates drastically. For example, if a media query dependent stylesheet is added in the middle of a group of CSS files the current behavior causes the creation of 3 aggregates instead of just one (pre-media-query-stylesheets / media-query-stylesheets / post-media-query-stylesheets).

Proposed resolution

Ignore the media query option of stylesheets that have 'preprocess' set to TRUE when CSS aggregation is enabled and write the media query into the CSS aggregate instead (wrap it around the string content of that file when building the cache).

Remaining tasks

Tests, maybe.

API changes

None. It doesn't have an effect on the weighting of stylesheets either.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Status: Needs review » Needs work

The last submitted patch, css-aggregation-media.patch, failed testing.

fubhy’s picture

Status: Needs work » Needs review
FileSize
3.5 KB
fubhy’s picture

FileSize
3.48 KB

Same patch but a easier to read.

nod_’s picture

Status: Needs review » Needs work

Good idea but current patch doesn't work. Don't think it takes much to fix it though.

JohnAlbin’s picture

Issue tags: +frontend performance

Tagging.

Wim Leers’s picture

Title: Incorporate media queries in aggregated CSS files » Incorporate media queries in aggregated CSS files, don't create a new group for each new media query
Category: feature » task

Needs reroll now that #352951: Make JS & CSS Preprocessing Pluggable has landed.

Definitely a task, not a feature: no APIs changed, just smarter CSS aggregation!

Wim Leers’s picture

Priority: Normal » Major
Issue tags: +Performance, +mobile, +CSS aggregation, +revisit before beta

We *must* do this before D8 release. This is at least a major performance problem. If we don't do it before release, then we must do it in a Drupal 8 point release.

sdboyer’s picture

this is being rolled in as part of #1762204: Introduce Assetic compatibility layer for core's internal handling of assets. we can mark it a dupe once that goes in.

(or just do it now, this is pretty simple and an immediate win)

iamcarrico’s picture

Status: Needs work » Needs review
FileSize
5.46 KB

I just revisited this in the current look of things, and added this re-roll.

This patch also updates the current tests, and then adds a new test to make sure this is actually working... which it seems to be.

sdboyer’s picture

looks like a step in the right direction. i should probably review the tests in more detail to ensure they really test the output fully here, but before that...

+++ b/core/lib/Drupal/Core/Asset/CssOptimizer.php
@@ -32,11 +32,19 @@ public function optimize(array $css_asset) {
+
+    // If this CSS file has a media query attached to it, we add the media tag
+    // within the aggregate file, to remove the number of total aggregates.
+    if (isset($css_asset['media']) && $css_asset['media'] != 'all') {
+      $contents = "\n" . $contents;
+      $contents = '@media ' . $css_asset['media'] . ' {' . $contents . '}' . "\n";
+    }
+    return $contents;

this is the bit that's been raising some question marks for me. i think this isn't quite right.

it seems like this should be right IF the media type of the containing aggregate asset is either not set, or 'all'. however, if the aggregate is something else, this won't be correct.

and, it is currently possible that the containing asset would have a different media type, as the groups no longer differentiate based on media - which means the aggregate inherits the media property of whatever css asset happens to be the first to pass through it.

the solution, i think, is to either simply enforce that we ALWAYS apply 'all' as the media type on aggregates, or that we remove the conditional in this code block and just *always* attach a media wrapper. and this is where i get fuzzy, because i don't know which is best.

iamcarrico’s picture

Status: Needs review » Needs work

Rodger, I will check it out and fix.

iamcarrico’s picture

Rodger, I will check it out and fix.

MustangGB’s picture

Issue summary: View changes
Status: Needs work » Closed (duplicate)

sdboyer appears to be re-writing the world in #1488910: Incorporate media queries in aggregated CSS files, don't create a new group for each new media query, whist throwing in this plus with it, keep up the good work.

Wim Leers’s picture

Status: Closed (duplicate) » Needs work

He's changing everything in the internals of asset handling. It will NOT affect aggregate generation, besides a few minor changes (typehinted parameters). This patch can still go in. :)

catch’s picture

Issue tags: -revisit before beta

This doesn't seem tied to the release, could do it any time no?

iamcarrico’s picture

It could--- also: there might be a use case to not doing this at all. I will ponder some use cases in the near future.

joginderpc’s picture

Status: Needs work » Needs review
Dane Powell’s picture

Status: Needs review » Needs work

Patch in #9 no longer applies and needs to be re-rolled.

NickDickinsonWilde’s picture

A *similar* implementation is included in AdvAgg. The D8 version is in development and does include that.

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

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should 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.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should 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.

catch’s picture

This is still valid and would make a big difference - i.e. just standard install logged in as admin, toolbar is set to 'screen' in the library definition, which results in two or three files that could have been one (it's usually three, because unless it's the first or last file in an aggregate, it ends up as a new aggregate sandwiched between two.

http://caniuse.com/#feat=css-mediaqueries shows that IE11 doesn't support nested media queries, so I don't think we can make this work without using a proper CSS preprocessor (that supports un-nesting media queries).

catch’s picture

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

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should 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.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should 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.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should 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.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should 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.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.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: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should 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: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
catch’s picture

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should 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.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should 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.

catch’s picture

I had opened #2695871: Aggregation creates two extra aggregates when it encounters {media: screen} in a library declaration four years later back in 2016 without realising it was a duplicate, and that issue got committed to 10.0.x, so marking this one outdated.