LoginSignup
8
6

More than 3 years have passed since last update.

RailsのAssetsをGzipで提供する

Posted at

TL;DR

server {
  # ...省略
  gzip on;
  gzip_types image/gif image/png image/jpeg; # Railsは画像を圧縮しないので、欲しいであれば自分で圧縮すること

  # ...省略
  location /assets {
    root   /usr/share/rails/app/assets;
    location ~ .*.(js|css|html|svg)+$ {
      gzip_static on;
      # gunzip on; # Railsの`public/assets`に圧縮してないファイルもあるので省略
    }
  }

目的

最近GoogleのPage Speed Insightsが遅い遅いとつっこまれたので、調べてみたら、「テキスト圧縮の有効化」が効いてないと指摘されて、その対策を探るために調査を行いました。

現象

Nginx Gzipで検索したら、たくさん結果が出て、そのほとんどは、下記の構文で、Nginx自分の機能で圧縮を行う手法を提案しています。

server {
  # ...省略
  gzip on;
  gzip_types text/css application/javascript application/json;
  gzip_types application/font-woff application/font-tff;
  gzip_types image/gif image/png image/jpeg;
  gzip_types application/octet-stream;
  # ...省略
}

この手法にはいくつか欠点があります。まず、アクセスする度に、Nginxを使ってアセットのGzipを行うので、サーバーのCPUを大量に使います。そして、NginxはデフォルトSVGのmime typeを認識しないため、SVGの圧縮を行いたい場合は別途設定が必要でした。

また、rake assets:precompileが実行される際のログを見てみると、ちゃんと.gzファイルも出しているのをわかりました。なぜかNginxこれら.gzファイルを認識していなく、圧縮前のファイルだけ提供しています。

解決策

そこで見つかったのはNginxのgzip_staticの設定でした。その設定をonにすると、リクエストにgzipしたアセットを優先的に提供していて、もしgzipを明示的に不要とした場合、圧縮前のアセットを提供するしようでした。

ちなみに、もしgzip済のアセットのみ存在する場合、gunzip onの設定を追加すると、gzip不要なクライアントに対して、Nginxが一回gzipしたアセットを解凍し、提供することになります。

ただし、Railsのassets:precompileは画像ファイルを圧縮しないため、もしどうしても画像ファイルもgzipとして提供したい場合、おとなしくgzip_types image/gif image/png image/jpegを設定しましょう。

また、Nginxはデフォルトでhtmlファイルをgzipしているので、ここでの設定は不要です。

余談: Page Speed Insights点数を改善するための開発手法

施策まで

施策をする前に、点数は非常に低かったです。
PageSpeed_Insights_before.png

Googleさんが指摘した問題点を分析すると、「JSの読み込みが遅い」「アセットが圧縮されていない」が大きくペナルティを食らったことがわかりました。

JSの読み込みが遅い問題に対しては、scriptタグにasyncやdeferを付けることで解決できます。ただし、JSの読み込み順が変わってしまうので、細かく動作確認が必要です。

アセットが圧縮されていない問題は上記のように、Nginxでの施策で対処できます。

効果確認

ここで効果確認するために、production環境のDockerを作って、NginxのDocker、そしてデータベースのDockerと繋いて、Ngrokなどプロキシでフォワーディングして、テストをしました。

PageSpeed_Insights_ngrok.png

対策した結果、だいぶ点数が上がりました。残りの問題点を調べると、TTFBが遅いと指摘されました。それはおそらくローカル環境なので、DBが重いのが原因でした。

結果

対策して、本番リリースしたら、より点数がアップしました。やはりTTFBの遅さはローカル環境のせいでした。

PageSpeed_Insights_after.png

ちなみに、Page Speed Insightsの「モバイル」の方は、回線速度や機器のスペクトルなど、かなりペナルティを課しているそうです。PCだと点数が全く違います。
PageSpeed_Insights_after_pc.png

参考

https://qiita.com/RyoMa_0923/items/55078f6fb57e9d70a37f
https://gist.github.com/equivalent/9352734#file-nginx-on-ruby-on-rails-with-unicorn-and-gzip-assets-L35
https://qiita.com/cubicdaiya/items/2763ba2240476ab1d9dd
https://stackoverflow.com/questions/3972675/how-to-tell-gzip-static-not-to-look-for-image-files
https://qiita.com/yuuna/items/9a2954300a130a9637b8
https://guides.wp-bullet.com/enable-svg-gzip-compression-nginx/

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6