Compressing rails assets and nginx gzip

2020-02-23 08:23发布

问题:

Do I have to configure nginx to compress assets (gzip set to on) if I have compressed rails assets with rake assets:precompile? I mean does it make sense or not? Will performance better or worse? Thank you!

回答1:

No, you do not. They are not the same kind of compression. When you run rake assets:precompile, all you're really doing is joining a bunch of files into one file and dumping it to the disk. Actually, according to the official documentation, it is two files:

When files are precompiled, Sprockets also creates a gzipped (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves.

This is important for you, because it allows you to use gzip, if you want, but it does not force you to do so. Gzip compression, which is real compression (not just concatenating files) reduces the amount of data you have to transfer, but at the expense of processor power (compressing and decompressing). It is likely to fairly dramatically improve your site, depending on page sizes and your (and your user's) hardware.



回答2:

Do rake assets:precompile and you have to configure nginx for send gzip version of files, i use this configuration.

user www-data www-data;
worker_processes 4;

pid /var/run/nginx.pid;

events{
    worker_connections 2048;
    use epoll;
}

http{
    include mime.types;
    default_type application/octet-stream;

    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    server_tokens off;
    server_name_in_redirect off;
    ignore_invalid_headers on;

    gzip off;
    sendfile on;

    upstream reverse-proxy{
        server 127.0.0.1:3000;
        server 127.0.0.1:3001;
        server 127.0.0.1:3002;
        server 127.0.0.1:3003;
    }   

    server{
        listen 80;
        server_name _;
        root /home/www-data/my_website/public;

        client_max_body_size 10M;
        client_body_buffer_size 512k;

        location ~ ^/assets/ {
            gzip_static on;

            add_header Cache-Control public;
            expires 4w;
            gzip on;
            gzip_vary on;
            gzip_proxied any;
            gzip_disable "MSIE [1-6]\.";
            gzip_comp_level 6;
            gzip_types application/x-javascript text/css text/html image/x-icon image/png image/jpeg image/gif;
        }

        location / {
            try_files $uri @ruby;
        }

               location @ruby {
                        proxy_set_header  X-Real-IP  $remote_addr;
                        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header  Host $http_host;
                        proxy_redirect    off;

                        proxy_pass http://reverse-proxy;
                }

    }

}


回答3:

Here is a complete configuration(I am using it for my site):

GENERAL CONFIGURATION

http {
passenger_root /usr/local/lib/ruby/gems/1.9.1/gems/passenger-4.0.5;
passenger_ruby /usr/local/bin/ruby;

include mime.types;

default_type application/octet-stream;
server_tokens off;
sendfile on;
keepalive_timeout 70;

gzip on;
gzip_http_version 1.1;
gzip_disable "msie6";
gzip_vary on;
gzip_min_length 1100;
gzip_buffers 64 8k;
gzip_comp_level 3;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml;


add_header Strict-Transport-Security "max-age=16070400; includeSubdomains";
add_header X-Frame-Options DENY;

limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

include /opt/nginx/conf/nginx_host.conf;
}

Content of /opt/nginx/conf/nginx_host.conf;

HOST CONFIGURATION

server {
listen 80;
server_name *.domain.com;
root APP_PATH/current/public;
        passenger_enabled on;
        access_log off;

error_log /dev/null;

# Cross domain webfont access
location ~* \.(?:ttf|ttc|otf|eot|woff|font.css)$ {
    add_header "Access-Control-Allow-Origin" "*";
    expires 1M;
    access_log off;
    add_header Cache-Control "public";
}

location ~* \.(ico|css|gif|jpe?g|png)(\?[0-9]+)?$ {
    expires max;
}

location ~ ^/(assets|uploaded_assets|system)/  {
  root   /home/travelobd/rails_apps/travelobd/current/public;
  gzip_static on; # to serve pre-gzipped version
  expires max;
  add_header Cache-Control public;
 }
}

For serving assets:

server {
        listen 80;
        server_name     static.domain.com;
        root APP_PATH/current/public;
        location / {
                if ($request_filename ~ "\.(jpg|css|gif|png|swf|ico|js)$") {
                        break;
                }
        return 404;
        }
        }


回答4:

Yes, you should if you want to improve performance.

Simply add the following block to your site configuration:

location ~ ^/(assets)/  {
  root /path/to/public; # CHANGE THIS
  gzip_static on; # to serve pre-gzipped version
  expires max;
  add_header Cache-Control public;
}

Change the root path in the configuration. That is all there is to it.

RecommendationFromDocumentation™: http://guides.rubyonrails.org/asset_pipeline.html



回答5:

What worked for me was configuring Nginx:

location ~ ^/(assets)/ {
  gzip_static on;
}

Then in application.rb:

  config.middleware.insert_before(Rack::Sendfile, Rack::Deflater)

  # Compress JavaScripts and CSS.
  config.assets.compress = true
  config.assets.js_compressor = Uglifier.new(mangle: false)