Problem/Motivation
Drupal supports compressing aggregated assets with gzip.
It would be nice to also support brotli, since it provides better performances.
advagg provides this functionality but only on non-aggregated files.
Proposed resolution
Modify AssetDumper to generate Brotli-compressed assets alongside gzipped files and update the .htaccess file to serve them.
Rename the system.performance.css.gzip and system.performance.js.gzip settings to system.performance.css.compress and system.performance.js.compress. These boolean settings would enable every available compression algorithm (currently gzip and Brotli but more could be added in the future).
Remaining tasks
review, commit
User interface changes
no
Introduced terminology
no
API changes
config renamed from system.performance.*.gzip to system.performance.*.compress
Data model changes
no
Release notes snippet
Drupal now generates Brotli-compressed versions of aggregated CSS and JS assets when the brotli PHP extension is installed.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3184242
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:
- 3184242-fix-test
changes, plain diff MR !15602
- 3184242-support-brotli-compression
changes, plain diff MR !9980
Comments
Comment #2
cilefen commentedComment #3
prudloff commentedThe attached patch add new
system.performance.css.brotliandsystem.performance.js.brotlisettings that enable Brotli compression.I could not find a GUI to enable/disable gzip compression (it seems it is only provided by advagg?) so I did not create one for Brotli.
Comment #4
cilefen commentedComment #5
prudloff commentedI just noticed that the previous patch was giving priority to gzip in
.htaccess.I put brotli first so gzip is used as a fallback if brotli is not available.
Comment #6
cilefen commentedComment #9
webflo commentedRe-rolled the patch from @prudloff because this patch was from the substree-split (drupal/core).
Comment #10
webflo commentedAnd the same patch without patches to /.htaccess - the patch can not be applied with composer otherwise.
Comment #12
yogeshmpawarUpdated patch will fix test failures.
Comment #14
catchAdding #1040534: Rewrite rules for gzipped CSS and JavaScript aggregates cause lots of lstats for files that will never exist as a related issue.
One issue here is that if brotli compression isn't available on the server, this will add even more lstats for files that will never exist. Trying to think through ways around this and how to reconcile it with the latest approach on that issue.
Comment #15
socialnicheguru commentedDoes this just work with apache2?
Does it work with nginx?
Comment #16
catch#1040534: Rewrite rules for gzipped CSS and JavaScript aggregates cause lots of lstats for files that will never exist improves the regexp so that it doesn't look for files like .gz.gz, but that won't help on servers that don't have brotli compression enabled - where we'd be looking for a .br file that will never exist.
However one of the possible solutions in #1040534: Rewrite rules for gzipped CSS and JavaScript aggregates cause lots of lstats for files that will never exist was to write a .htaccess file to the aggregate folder with the rewrite rules, so that it only applies to those folders.
If we were to do that, we could also potentially write different .htaccess files dependent on whether brotli compression is available or not, then sites without it won't check file existence for .br files.
Comment #17
socialnicheguru commentedHow would that work if you are using nginx server as they do not use .htaccess?
Comment #19
gaëlgComment #20
ravi.shankar commentedAdded reroll of patch #12 on Drupal 10.1.x.
Comment #21
jnoordsijFor nginx you would need to install the brotli module (see https://github.com/google/ngx_brotli), then add a `brotli_static on` directive to the correct block of your configuration.
Comment #22
prudloff commentedHere is #20 without changes to
.htaccessso that it can be applied with Composer.Comment #23
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #24
jnoordsijAdded rerolls of patch #20 and the non-
.htaccessversion of #22 on Drupal 10.1.x.I also added some changes to the added
.htaccessrules to make the rewriterule conditions consistent with the ones for gzip.Comment #25
smustgrave commentedSo taking a look at this
Could we add it's own test case? Seems some tests had to be updated for it but not sure if it's actually testing.
Since the schema is updating most likely will need an upgrade path + upgrade path tests.
If this new setting is required (which seems to be) it will require a change record also
Thanks!
Comment #27
andypostWhat if new compression algo will be added to browsers?
Better to deprecate "gzip" option in favor of "compress" which will be common trigger to produce all possible assets archives.
Also it could be a sequence of algo to limit :
Not sure it makes sense to introduce new configuration and without UI, it could re-use "gzip" setting to produce compressed assets using gzip/brotli
Comment #28
catchA compress item with a sequence sounds good.
Having said that we've got the problem that the .htaccess rules can't be configured - they will always need to check in order of likelihood-of-support first. So if we add brotli support to htaccess but it's disabled by the site, the rewrite rules will still look for those files.
Makes me wonder if we should just do 'compress' as a boolean and write out everything we possibly can.
Comment #29
jnoordsijAdded rerolls of patches in #24 on Drupal 10.2.x. I think they should also apply on 11.x-dev.
Comment #30
jnoordsijAdded rerolls of patches in #29 on Drupal 10.2.x.
Comment #31
jnoordsijReversed the naming in #30; added
https://www.drupal.org/files/issues/2024-01-05/3184242-asset-brotli-comp...
and
https://www.drupal.org/files/issues/2024-01-05/3184242-asset-brotli-comp...
which are correct.
Comment #32
socialnicheguru commentedIs there a variable we can set in settings.php?
Comment #33
andypostNot sure how tests can cover it but CR should mention update of nginx conf as well
Comment #35
pgndrupal commentedwith a new D11 v11.1.0 install,
i see in generated assets,
, no brotli (.br)
checking,
status here says "Needs work", and "Remaining tasks: I will submit a patch."
the MR, #9980 submitted a month ago, is "Ready to merge" and "1 commit will be added to 11.x".
but has not been merged.
@prudloff
what's outstanding?
what release can this be expected in?
Comment #36
sd123 commentedHope this will be added soon...
It would be great if automatic creation of static gzip and brotli files is also added for all svg files people have in their themes and uploaded files directories. I am now creating those manually on my server.
Comment #37
prudloff commentedI added a test but it requires the brotli PHP extension.
I managed to build it in the CI but it does not seem to be enabled in tests so I'm not sure that's the correct way to do this.
Should we create an issue in the drupalci project to get the extension included in the Docker image?
We might want to add support for zstandard compression after this (#3346184: Does Drupal support ZSTD compression?) so I agree it might be easier to keep a single boolean that enables every possible algorithm depending on what the server can generate.
I'm not sure there is a use case for enabling gzip but not brotli.
Comment #38
andypostas both kinds of compression are common I think better to add them to images, just file issue to https://www.drupal.org/project/issues/drupalci_environments
Comment #39
prudloff commentedPostponed until #3512083: Add brotli, igbinary, zstd PHP extensions.
Comment #40
andypostAdded both brotli and zstd to dev images, rebased and looks like tests passed
PS: probably zstd could be added in related
Comment #41
prudloff commentedThis issue is already quite old so we might want to keep the scope small in order to get it committed then add zstd in a followup.
Comment #42
andypostSure, let's focus the issue on title and there's so many "needs" tags so not sure it fits into 11.2
Comment #43
andypostCI images now has
brotli0.17.0 with latest fixes https://github.com/kjdev/php-ext-brotli/commit/48c719a9f0e2b1ae53e08acf2...Comment #44
andyposttests are here
Comment #45
prudloff commentedI updated the MR to use a single setting for both gzip and brotli (and future algorithms).
I also added an upgrade path.
We still need a change record I think.
Comment #46
andypostCreated CR using Claude Opus 4
Comment #47
prudloff commentedThe CR seems to contain some hallucinations:
Comment #48
andypostFixed https://www.drupal.org/node/3526344/revisions/view/14005103/14005483
this is where aggregate js/css checkboxes are
Comment #49
prudloff commentedThe aggregate setting is not the same as the gzip/compress setting (which as far as I can tell does not have a UI).
Comment #50
andypostyes, this settings enabling aggregation, now having aggregated assets core applies compression
Comment #51
sd123 commentedWhat about svg and webmanifest assets? Or are non-aggregated assets beyond the scope of this issue report?
Comment #52
prudloff commented@sd123 this is out of the scope of this issue. Feel free to open a separate issue about this (if there isn't one already).
Comment #53
sd123 commentedOk, maybe a suggestion for the nginx example config in the CR:
Isn't it better and cleaner to combine both as follows or can this induce problems?
Not sure if this should be in the example configuration, but it also can be with better caching parameters:
Comment #54
smustgrave commentedShouldn't these keys be deprecated?
Comment #55
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #56
prudloff commentedI merged the latest 11.x and deprecated the gzip properties instead of removing them.
Comment #57
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #58
prudloff commentedI merged the latest 11.x.
Comment #59
dcam commentedI left some comments on the MR.
The issue summary needs to be updated. The full summary template should be applied. The proposed resolution section needs to be updated with information about the changes to the system.performance config schema. And the UI Changes section still mentions modifying the Performance form, which is no longer happening.
Comment #60
prudloff commentedI applied the suggested changes.
Comment #61
dcam commentedMy feedback was addressed.
Comment #62
catchOne question on the MR.
Comment #63
dcam commentedSetting to Needs Work to fix the line flagged by @catch.
Comment #65
prudloff commentedI answered the comment.
Comment #66
godotislateDeprecation version should be bumped before being committed. I also removed the line in the CR about migrating settings from "admin/config/development/performance", since the form does not control compression settings, and the only way to change them is programmatically or through CLI.
Comment #67
dcam commentedNeeds Work for another rebase and for the latest comments made by @godotislate.
Comment #68
prudloff commentedI rebased the MR and applied suggestions.
Comment #69
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. The merge request has merge conflicts and cannot be merged. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #70
prudloff commentedComment #71
dcam commentedRecent feedback from @godotislate was addressed. I'm going to go ahead and RTBC this, but I realized upon re-review that the removal version is still set as D12. That may need to be updated to D13. I'm not 100% sure because it's been a while since we had those discussions.
Comment #72
catchWent back and forth on the config schema deprecation a bit (with myself...).
Assuming we're able to land this in both 12.x and 11.4, then the update will be in both versions, so whether you go 11.3 -> 11.4 -> 12.0 or 11.3 -> 12.0 the update will run and your config will be correct.
This isn't a config entity so we don't need to worry about shipped configuration with modules, the only case where it could be shipped would be in a recipe (unlikely) or distribution (more likely if they ship essentially the entire contents of the config/sync directory).
I'm not entirely sure about the possibly disruption to distributions after typing that out, it might be easier to defer the deprecation for removal in 13.0 which would be the same version that the update path is removed in though.
We need a release note here because this changes site-owner managed files.
Also tagging for 11.4.0 release highlights since it'll be another thing to put in the performance section.
Comment #73
catchComment #74
andypostadded snippet and IS a bit
Comment #75
andypostComment #76
andypostadded release note snippet
Comment #77
dcam commentedThe added release note is a good one-sentence summary of the change.
Comment #81
catchThought about the deprecation more and the use case for customising this in a distribution is so narrow I think we're fine to deprecate for removal in 12.x
Committed/pushed to main and 11.x, thanks! Manually resolved a straightforward merge conflict in 11.x for the post update, just context.
Comment #85
godotislateThink this has broken HEAD. Opened https://git.drupalcode.org/project/drupal/-/merge_requests/15602 to address.
Comment #86
godotislateOh never mind, @alexpott already got it.
Comment #89
longwaveThis also broke HEAD in 11.x.
Comment #90
longwaveHotfixed in 468b307.