Doesn’t Rails generate gzipped assets on running rake assets:precompile? It did so, until Rails 4.2. What changed?

Rails uses sprockets gem, for compiling and serving web assets. Before Sprockets 3 was introduced, rake assets:precompile generated .gz versions for all the assets.

This change, seems backward, for several reasons

Gzipping should always be enabled for static assets. It’s super charges serving of static content. Assets should be gzip’ed beforehand as part of the build process, rather than letting the webserver do it on the fly, saving on CPU cycles. Also, Nginx has the ability to serve static .gz files directly, by using the gzip_static on; directive.

The reason for dropping this, was its incompatibility with Apache.

Since Sprockets 3 dropped this feature, it means Rails had to loose it too. The Rails team, plans to bring it back as an opt-in. Nevertheless, what does one do in the meantime?

Here are the options to generate Gzipped Assets with Rails

namespace :assets do desc "Create .gz versions of assets" task :gzip => :environment do zip_types = /\.(?:css|html|js|otf|svg|txt|xml)$/ public_assets = File.join( Rails.root, "public", Rails.application.config.assets.prefix) Dir["#{public_assets}/**/*"].each do |f| next unless f =~ zip_types mtime = File.mtime(f) gz_file = "#{f}.gz" next if File.exist?(gz_file) && File.mtime(gz_file) >= mtime File.open(gz_file, "wb") do |dest| gz = Zlib::GzipWriter.new(dest, Zlib::BEST_COMPRESSION) gz.mtime = mtime.to_i IO.copy_stream(open(f), gz) gz.close end File.utime(mtime, mtime, gz_file) end end # Hook into existing assets:precompile task Rake::Task["assets:precompile"].enhance do Rake::Task["assets:gzip"].invoke end end