Web assets like CSS and JavaScript files can be compressed by up to 90%, which is why most servers compress them before sending them to clients. The three most commonly used compression formats for the web are:
- Gzip: a solid multi-purpose format with average compression speed and ratio;
- Brotli: typically produces the smallest output (it was designed specifically for web assets) but is slower than the others;
- Zstandard: by far the fastest format for compression and decompression, while producing very small outputs (often close to Brotli).
Ideally, you'd use the highest compression level available for each format. However, CPU usage increases much faster than the reduction in file size, so maximizing compression isn't always worth the cost.
In modern Symfony applications using AssetMapper or Webpack Encore, assets are versioned and guaranteed to never change. That's why dynamically compressing them for every request is inefficient; it means compressing the exact same content again and again.
Symfony 7.3 introduces a new feature to pre-compress web assets on your server once and serve the compressed versions to all clients. This saves a lot of CPU and lets you use the maximum compression level to squeeze every last bit out of your assets.
If you use AssetMapper, enable the feature by adding this configuration:
1 2 3 4 5 6 7
# config/packages/asset_mapper.yaml
framework:
asset_mapper:
# ...
precompress:
# possible values: 'brotli', 'zstandard', 'gzip'
format: 'zstandard'
That's it! When you run the asset-map:compile
command, all assets will be
compressed using the selected format and its highest compression level. The
compressed files will be stored alongside the originals with an additional
extension (e.g. app-8ec4b11.js
will generate app-8ec4b11.js.zstd
).
Web servers (FrankenPHP, Caddy, etc.) and services (Cloudflare, etc.) that support asset pre-compression will automatically use the compressed versions, so there's nothing else to configure on your server.
This will be very useful. Thanks for sharing.
I wish you guys hadn't been so intent on making this AssetMapper the standard so early on. CSS just isn't at the point where it can easily replace SASS yet. It's great that nesting is now natively a thing and that we have native CSS variables, but debugging CSS in your browser is a pain because Chrome doesn't understand nesting all that well yet, and variable notation is clunky and annoying, and worse: you can't use variables in media queries, so you have to use inline numeric constants every time you write one.
I get that you added this as an option as it's a perfectly good solution for many people. But it should not have been the default in Symfony 7, probably not even in Symfony 8. CSS just isn't there yet.
Webpack Encore is mentioned; will it be possible to use pre-compression with it, or is it limited to Asset Mapper?
@Andrew this feature is limited to AssetMapper. But, this feature also includes an
assets:compress
CLI command and a service calledasset_mapper.compressor
that you can use anywhere in your application to compress any kind of files. So, maybe you can build some script/code using any of those.@Jeroen van den Broek
I don't use Sass anymore, but AssetMapper certainly supports it: https://github.com/symfonycasts/sass-bundle