-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[AssetMapper] add support for assets pre-compression #59020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
287ee79
to
b268420
Compare
src/Symfony/Component/AssetMapper/Command/CompressAssetsCommand.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Outdated
Show resolved
Hide resolved
The Psalm errors are false positives (the constants are defined if the extensions are installed). Should I ignore them explicitly or let the baseline generator do is job? |
Thinking out loud here... I'm wondering if this could/should be in a dedicated package ? Except the "compress on write", the Compressor is not really linked to the AssetMapper.. and maybe could benefit other components / projects ? |
To be honest, I hesitated between putting it in I've no strong opinion about this. Let's wait for @symfony/mergers opinions. |
e863ee2
to
4bbfe60
Compare
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Show resolved
Hide resolved
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Show resolved
Hide resolved
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/Command/CompressAssetsCommand.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/Compressor/BrotliCompressor.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/Compressor/ZstandardCompressor.php
Outdated
Show resolved
Hide resolved
Let the baseline generator do its job for next PRs (ignoring the job failure in this PR). We don't add explicit Psalm ignore rules in the project |
src/Symfony/Component/AssetMapper/Compressor/GzipCompressor.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/Compressor/ChainCompressor.php
Outdated
Show resolved
Hide resolved
f1f4b27
to
b64d3df
Compare
4895f54
to
f0e62b4
Compare
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/Compressor/CompressorTrait.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/Compressor/SupportedCompressorInterface.php
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With minor comment
b02b01a
to
5fa3e92
Compare
Thank you @dunglas. |
(new Process([$this->executable, '--', $path]))->mustRun(); | ||
} | ||
|
||
private function createStreamContext() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dunglas this method with no return type and no phpdoc @return
makes our CI fail for the check about our migration to native return types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type is documented in the PHPDoc of the abstract function in the trait, but I can add it here too if needed.
final class GzipCompressor implements SupportedCompressorInterface | ||
{ | ||
use CompressorTrait { | ||
compress as baseCompress; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be used as private baseCompress
instead. We don't want to expose a public method.
|
||
public function compress(string $path): void | ||
{ | ||
if (null === $reason = $this->zopfliCompressor->getUnsupportedReason()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't the getUnsupportedReason
implementation also check whether zopfli is supported ? Maybe your server has the zopfli executable but does not have the gzip one and the zlib extension. In such case, the current implementation would mark this compressor as unsupported while the compress
method would work
This PR was merged into the 7.3 branch. Discussion ---------- [AssetMapper] minor fixes for pre-compression | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | #59020 (review) | License | MIT Fixes `@stof`'s comments. Commits ------- b6597b6 [AssetMapper] minor fixes for pre-compression
Nice work 👍 , I think its worth mentioning that nginx gzip with |
Adds support for assets and files precompression using Zstandard, Brotli, and gzip (this will be part of my talk at SymfonyCon next week).
When calling
bin/console asset-map:compile
and if the new optionasset_mapper.precompress
is enabled, all files matching the configured extensions will be compressed in Brotli, Zstandard, and gzip (zopfli when available) at maximal compression (defaults to the list supported by Caddy and Cloudflare). The PHP extension is used if available, otherwise the Unix command is used as a fallback.The compressed files are created with the same name as the original asset but with the
.br
,.zst
, or.gz
extension appended.This allows native compatibility with web servers supporting precompression such as Caddy and FrankenPHP or NGINX with the Brotli module.
Apache can also use these files but will require some extra config.
This PR also adds an
assets:compress
command that can be used to compress files not managed by AssetMapper (e.g.robots.txt
).Finally, the new
asset_mapper.compressor
service can be used to precompress files uploaded by the user (among various other use cases).TODO: