【问题标题】:Compressing rails assets and nginx gzip压缩 Rails 资产和 nginx gzip
【发布时间】:2024-11-16 23:50:01
【问题描述】:

如果我使用rake assets:precompile 压缩了rails 资产,我是否必须配置nginx 来压缩资产(gzip 设置为打开)?我的意思是这有意义吗?性能会更好还是更差?谢谢!

【问题讨论】:

    标签: ruby-on-rails nginx asset-pipeline


    【解决方案1】:

    做 rake assets:precompile 并且你必须配置 nginx 来发送 gzip 版本的文件,我使用这个配置。

    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;
                    }
    
        }
    
    }
    

    【讨论】:

    • nginx 文档说我们不需要添加 text/html 因为它是默认完成的(在 gzip_types 下)。使用基于位置的 gzip 压缩的一件事,显然这在 443 土地上不起作用,对吗?我把它移到了 http 块,这样所有东西都被压缩了。顺便说一句,你的过期时间也很棒。
    • 我从不在 https 上测试(它无法工作,因为我设置了监听端口 80)并且我的过期是因为谷歌页面速度建议将其设置为 4 周。
    【解决方案2】:

    不,你没有。它们不是同一种压缩。当您运行rake assets:precompile 时,您真正要做的就是将一堆文件合并到一个文件中并将其转储到磁盘上。其实根据official documentation,是两个文件:

    当文件被预编译时,Sprockets 也会创建一个 gzipped (.gz) 您的资产的版本。 Web 服务器通常配置为使用 适度的压缩比作为折衷方案,但由于预编译 发生一次,Sprockets 使用最大压缩比,因此 将数据传输的大小降至最低。在另一 手,Web 服务器可以配置为提供压缩内容 直接从磁盘,而不是压缩非压缩文件 自己。

    这对您很重要,因为它允许您根据需要使用 gzip,但它不会强迫您这样做。 Gzip compression,这是真正的压缩(不仅仅是连接文件)减少了您必须传输的数据量,但会以处理器能力(压缩和解压缩)为代价。它可能会显着改善您的网站,具体取决于页面大小和您(和您的用户)的硬件。

    【讨论】:

    【解决方案3】:

    这是一个完整的配置(我在我的网站上使用它):

    一般配置

    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;
    }
    

    /opt/nginx/conf/nginx_host.conf的内容;

    主机配置

    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;
     }
    }
    

    对于服务资产:

    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】:

      是的,如果您想提高性能,您应该这样做。

      只需将以下块添加到您的站点配置中:

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

      更改配置中的根路径。仅此而已。

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

      【讨论】:

        【解决方案5】:

        对我有用的是配置 Nginx:

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

        然后在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)
        

        【讨论】: