标签归档:压缩

CSS、JS、字体、图片静态文件nginx配置压缩指南

静态文件简介

Web 开发中需要的静态文件有:CSS、JS、字体、图片,可以通过web框架进行访问,但是效率不是最优的。
Nginx 对于处理静态文件的效率要远高于 Web 框架,因为可以使用 gzip 压缩协议,减小静态文件的体积加快静态文件的加载速度、开启缓存和超时时间减少请求静态文件次数。

下面就介绍如何通过 Nginx 管理静态文件的访问,优化网站的访问速度。

一、开启 gzip

配置介绍和参数如下,建议使用时删掉注释。

gzip on;
#该指令用于开启或关闭gzip模块(on/off)

gzip_buffers 16 8k;
#设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。16 8k代表以8k为单位,安装原始数据大小以8k为单位的16倍申请内存

gzip_comp_level 6;
#gzip压缩比,数值范围是1-9,1压缩比最小但处理速度最快,9压缩比最大但处理速度最慢

gzip_http_version 1.1;
#识别http的协议版本

gzip_min_length 256;
#设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是0,不管页面多大都压缩。这里我设置了为256

gzip_proxied any;
#这里设置无论header头是怎么样,都是无条件启用压缩

gzip_vary on;
#在http header中添加Vary: Accept-Encoding ,给代理服务器用的

gzip_types
    text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
    text/javascript application/javascript application/x-javascript
    text/x-json application/json application/x-web-app-manifest+json
    text/css text/plain text/x-component
    font/opentype font/ttf application/x-font-ttf application/vnd.ms-fontobject
    image/x-icon;
#进行压缩的文件类型,这里特别添加了对字体的文件类型

gzip_disable "MSIE [1-6]\.(?!.*SV1)";
#禁用IE 6 gzip

二、扩展压缩类型

修改 /etc/nginx/mime.types 文件,增加需要压缩的文件对应 type 到上述 gzip 配置中。下面几乎涵盖了所有静态文件对应的类型:

types {
    application/atom+xml                atom;
    application/dart                    dart;
    application/gzip                    gz;
    application/java-archive            jar war ear;
    application/javascript              js jsonp;
    application/json                    json;
    application/owl+xml                 owl owx;
    application/pdf                     pdf;
    application/postscript              ai eps ps;
    application/rdf+xml                 rdf;
    application/rss+xml                 rss;
    application/vnd.ms-fontobject       eot;
    application/x-7z-compressed         7z;
    application/x-bittorrent            torrent;
    application/x-chrome-extension      crx;
    application/x-font-otf              otf;
    application/x-font-ttf              ttc ttf;
    application/x-font-woff             woff;
    application/x-opera-extension       oex;
    application/x-rar-compressed        rar;
    application/x-shockwave-flash       swf;
    application/x-web-app-manifest+json webapp;
    application/x-x509-ca-cert          crt der pem;
    application/x-xpinstall             xpi;
    application/xhtml+xml               xhtml;
    application/xml                     xml;
    application/xml-dtd                 dtd;
    application/zip                     zip;

    audio/midi                          kar mid midi;
    audio/mp4                           aac f4a f4b m4a;
    audio/mpeg                          mp3;
    audio/ogg                           oga ogg;
    audio/vnd.wave                      wav;
    audio/x-flac                        flac;
    audio/x-realaudio                   ra;

    image/bmp                           bmp;
    image/gif                           gif;
    image/jpeg                          jpe jpeg jpg;
    image/png                           png;
    image/svg+xml                       svg svgz;
    image/tiff                          tif tiff;
    image/webp                          webp;
    image/x-icon                        cur ico;

    text/cache-manifest                 appcache manifest;
    text/css                            css less;
    text/csv                            csv;
    text/html                           htm html shtml;
    text/mathml                         mml;
    text/plain                          txt;
    text/rtf                            rtf;
    text/vcard                          vcf;
    text/vtt                            vtt;
    text/x-component                    htc;
    text/x-markdown                     md;

    video/3gpp                          3gp 3gpp;
    video/avi                           avi;
    video/mp4                           f4p f4v m4v mp4;
    video/mpeg                          mpeg mpg;
    video/ogg                           ogv;
    video/quicktime                     mov;
    video/webm                          webm;
    video/x-flv                         flv;
    video/x-matroska                    mkv;
    video/x-ms-wmv                      wmv;
}

三、开启超时时间

通过设置Expires,开启缓存。

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
    expires 30d;
    access_log off;
}

location ~ .*\.(eot|ttf|otf|woff|svg)$ {
    expires 30d;
    access_log off;
}

location ~ .*\.(js|css)?$ {
    expires 7d;
    access_log off;
}

利用Nginx的ngx_http_image_filter_module做实时的图片压缩缩略图

你还在用 ImageMagick 生成网站的上传图片缩略图吗?其实有更好的方法一部到位,简单有效。

现而今有非常多的云存储服务支持图片空间,并根据设定的规则来生成空间里面的图片缩略图了,例如 UpYun、Aliyun OSS 都支持。

但有时候我们会因为一些其他的考虑(例如:价格因素),选择本地文件存储上传文件,这个时候,我们如何实现图片缩略图呢?

其实 Nginx 内置了 ngx_http_image_filter_module 可以帮助你处理图片:

  • 缩放
  • 裁剪
  • 调整图片品质
  • 旋转
  • 锐化

我们常用的可能就是缩放和裁剪了,根据业务和设计需要,在合适的位置不同尺寸的缩略图。

安装

可能一些标准的 Nginx 安装包没有带这个 module 的,你需要使用 Nginx 官方的源安装,并额外安装 nginx-module-image-filter 这个包:

curl -O http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
sudo bash -c 'echo "deb http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx
deb-src http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx-stable.list' sudo apt-get update
sudo apt-get install -y nginx nginx-module-image-filter 

也可以直接用做好的 安装脚本

curl -sSL https://git.io/vVHhf | bash 

场景

以 Ruby China 的场景为例,我设计了下面几种不同的缩略图版本:

版本名称 限定尺寸 (px) 缩略方式
large 1920 限定宽度,高度自适应
lg 192×192 固定宽度和高度
md 96×96 固定宽度和高度
sm 48×48 固定宽度和高度
xs 32×32 固定宽度和高度

配置 Nginx

假定我们的上传文件存放在 /var/www/homeland/public/uploads 里面。

下面是 Ruby China 这个缩略图规则的完整 Nginx 配置:

/etc/nginx/nginx.conf

user nobody;
worker_processes auto;
pid /var/www/pids/nginx.pid;
daemon on;

# 载入 ngx_http_image_filter_module
load_module modules/ngx_http_image_filter_module.so;

http {
   # ... 省略
} 

/etc/nginx/conf.d/ruby-china.conf

proxy_cache_path /var/www/cache/uploads-thumb levels=1:2 keys_zone=uploads_thumb:10m max_size=50G; server { listen 80 default_server; listen 443 ssl http2; root /var/www/homeland/public; location /uploads { expires 7d; gzip_static on; add_header Cache-Control public; add_header X-Pownered "nginx_image_filter"; # HTTP Response Header 增加 proxy_cache 的命中状态,以便于以后调试,检查问题  add_header X-Cache-Status $upstream_cache_status; proxy_pass http://127.0.0.1/_img/uploads; # 将缩略图缓存在服务,避免每次请求都重新生成  proxy_cache uploads_thumb; # 当收到 HTTP Header Pragma: no-cache 的时候,忽略 proxy_cache  # 此配置能让浏览器强制刷新的时候,忽略 proxy_cache 重新生成缩略图  proxy_cache_bypass $http_pragma; # 由于 Upload 文件一般都没参数的,所以至今用 host + document_uri 作为  proxy_cache_key "$host$document_uri"; # 有效的文件,在服务器缓存 7 天  proxy_cache_valid 200 7d; proxy_cache_use_stale error timeout invalid_header updating; proxy_cache_revalidate on; # 处理 proxy 的 error  proxy_intercept_errors on; error_page 415 = /assets/415.png; error_page 404 = /assets/404.png;
  } # 原始图片  location /_img/uploads { alias /var/www/homeland/public/uploads/$filename; expires 7d;
  } # 缩略图  location ~* /_img/uploads/(.+)!(large|lg|md|sm|xs)$ { set $filename /uploads/$1; if (-f $filename) { break;
    } # 根据 URL 地址 ! 后面的图片版本来准备好需要的参数(宽度、高度、裁剪或缩放)  set $img_version $2; set $img_type resize; set $img_w -; set $img_h -; if ($img_version = 'large') { set $img_type resize; set $img_w 1920;
    } if ($img_version = 'lg') { set $img_type crop; set $img_w 192; set $img_h 192;
    } if ($img_version = 'md') { set $img_type crop; set $img_w 96; set $img_h 96;
    } if ($img_version = 'sm') { set $img_type crop; set $img_w 48; set $img_h 48;
    } if ($img_version = 'xs') { set $img_type crop; set $img_w 32; set $img_h 32;
    } rewrite ^ /_$img_type;
  } # 缩放图片的处理  location /_resize { alias /var/www/homeland/public$filename; image_filter resize $img_w $img_h; image_filter_jpeg_quality 95; image_filter_buffer 20M; image_filter_interlace on;
  } # 裁剪图片的处理  location /_crop { alias /var/www/homeland/public$filename; image_filter crop $img_w $img_h; image_filter_jpeg_quality 95; image_filter_buffer 20M; image_filter_interlace on;
  }
} 

你可能会觉得上面为何写得这么绕啊!

没办法,Nginx 不支持在 if {} 这个 block 里面用 image_filter 函数,image_filter 的第一个参数 resize/crop 也不能用变量的方式传输,所以…

然后,重启 Nginx,就可以尝试了。

注意点

  • 由于开启了 proxy_cache 缩略图将会在服务器上以文件的形式存在,你需要确保每次上传新文件名尽可能的是唯一的(例如用时间,或文件内容 MD5 作为文件名,参考 CarrieWave 文件名设计
  • 浏览器强制刷新,会发起 Pragma: no-cache 的 Request Header,Nginx 会忽略 proxy_cache 重新生成图片。

效果演示

扩展阅读