nginx前端优化模块ngx_pagespeed

发布时间:2015-09-23 15:51 | 人气数:722

ngx_pagespeed 是 Nginx 的一个扩展模块,主要的功能是针对前端页面而进行服务器端的优化,对前端设计人员来说,可以省去优化css、js以及图片的过程。ngx_pagespeed对nginx自身负载能力的提升基本是看不到的,甚至会因为进行服务器端的优化而使系统增加负载;但从减少客户请求数的角度去看,牺牲部分服务器性能还是值得的。ngx_pagespeed模块的主要功能如下:

图像优化:剥离元数据、动态调整,重新压缩
CSS和JavaScript压缩、合并、级联、内联
小资源内联
推迟图像和JavaScript加载
对HTML重写、压缩空格、去除注释等
提升缓存周期

提示:ngx_pagespeed模块目前仍处于开发阶段,功能上与mod_pagespeed相比稍有欠缺。但开源的力量不可小觑,Github上针对ngx_pagespeed Bugs的反馈更新很频繁,基本上都能很快得到解决,使用前务必考虑这点,不建议部署在生产环境。另,系统内GCC版本必须大于4.2。

ngx_pagespeed更新频率较高,建议及时更新到最新版本,而且最好先部署在本地环境中,经过一番测试稳定后再上线生产环境。主要测试方法参考这里:https://github.com/pagespeed/ngx_pagespeed/wiki/Testing

编译nginx和ngx_pagespeed,务必查看官方的材料:
ngx_pagespeed官方 http://ngxpagespeed.com/
Github https://github.com/pagespeed/ngx_pagespeed
Google Developers https://developers.google.com/speed/docs/mod_pagespeed/build_ngx_pagespeed_from_source
这里环境为nginx 1.4.6 和pagespeed 1.7.30.4,步骤如下:

# git clone git://github.com/pagespeed/ngx_pagespeed.git
# cd ngx_pagespeed/
# wget -c https://dl.google.com/dl/page-speed/psol/1.7.30.4.tar.gz
# rm -rf psol
# tar -zxvf 1.7.30.4.tar.gz # expands to psol/
# ./scripts/pagespeed_libraries_generator.sh > /usr/local/nginx/conf/pagespeed_libraries.conf

然后重新编译nginx,首先查看线上使用的编译参数,然后追加ngx_pagespeed模块进去,编译后覆盖到原来nginx的sbin路径,然后重启一下nginx就可以了。

# nginx -V
nginx version: nginx/1.4.6
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-file-aio --with-ipv6 --with-http_geoip_module --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_sub_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_addition_module --add-module=/usr/local/src/ngx_pagespeed --with-pcre=/usr/local/src/pcre-8.34 --with-debug
# make # 只make,接下来不需要make install
# mv /usr/sbin/nginx /usr/sbin/nginx.old # 备份原来的执行文件
# cp objs/nginx /usr/sbin/nginx # 复制刚刚编译好的执行文件
# /usr/sbin/nginx -t # 测试配置文件
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

测试通过,然后进行平滑升级nginx,首先发送USR2信号给nginx,然后再优雅退出旧的进程。

# kill -USR2 `cat /var/run/nginx.pid`
# kill -QUIT `cat /var/run/nginx.pid.oldbin`
另外32位系统编译时,需要在./configure 后面加上–with-cc-opt=’-DLINUX=2 -D_REENTRANT -D_LARGEFILE64_SOURCE -march=i686 -pthread’ 。强烈建议在64位系统下使用ngx_pagespeed模块,64位系统并不会比32位系统使用更多内存。

安装ngx_pagespeed后第一件事情就去看Google官方帮助文件,必须了解清楚模块的运作和相应过滤器的功能,个人建议是不用开这么多过滤。还要记得打开日志记录以便于查看运行产生的错误,一般在nginx.conf的error处指定日志输出路径(如:error_log /var/log/nginx/error.log info;),nginx启动后在终端中查看日志输出。在你所打开的任何一个过滤器(EnableFilters)后,建议都做这个步骤检查pagespeed是否出错。

个人使用时发现默认的配置会和nginx的rewrite系统有一些不兼容的情况,特别是开启了lazyload_images rewrite_css rewrite_images rewrite_javascript之类的,那么html源码里面出现的ngx_pagespeed_static url地址一访问就会出现404 not found的错误,或者直接rewrite到index.php,那么你需要做一件事:在ngx_pagespeed公用配置里面添加一行,如下红字部分。重点:Discuz论坛不要开启lazyload_images这个过滤器,否则会出现不能显示帖子内的图片附件。

#  Ensure requests for pagespeed optimized resources go to the pagespeed
#  handler and no extraneous headers get set.
location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" { add_header "" ""; }
location ~ "^/ngx_pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }
location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; }
location /ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; }
location /ngx_pagespeed_message { allow 127.0.0.1; deny all; }
location /pagespeed_console { allow 127.0.0.1; deny all; }
if ($request_uri ~ "(ngx_pagespeed_([^.]+)/(.*)?)") { break; }


添加之后无需更改原有网站的rewrite规则,即可正常使用。

本站开启了ngx_pagespeed,然后用几个前端测试工具进行测试,在PageSpeed测试环节,本站得到了93分。测试结果可以点击下列地址查看:
http://gtmetrix.com/reports/blog.icodex.org/jmELNaSS
http://www.webpagetest.org/result/130510_X8_4Z8/

总结:经过朋友和自己的多番测试,nginx部署安装前端优化模块ngx_pagespeed还是非常有必要的。

——————————————————– 分割线——————————————————–

附本站所在服务器上的配置文件片段:

**0. nginx编译参数部分**

[icodex@srv0 ~]$ sudo nginx -V
nginx version: nginx/1.4.6
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-file-aio --with-ipv6 --with-http_geoip_module --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_sub_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_addition_module --with-google_perftools_module --add-module=/usr/local/src/ngx_cache_purge-2.1 --add-module=/usr/local/src/ngx_pagespeed --with-pcre=/usr/local/src/pcre-8.34 --with-debug

1. /usr/local/nginx/conf/pagespeed.conf

pagespeed on;
 pagespeed UseNativeFetcher on;
 resolver 8.8.8.8;
 pagespeed Disallow "*.php*";
 pagespeed FetcherTimeoutMs 300;
 pagespeed RewriteDeadlinePerFlushMs 300;
 pagespeed FetchWithGzip on;
 pagespeed ForceCaching on;
 #needs to exist and be writable by nginx
 pagespeed FileCachePath /var/cache/nginx/ngx_pagespeed_cache;
 #pagespeed FileCachePath /dev/shm/ngx_pagespeed_cache;
 pagespeed FileCacheSizeKb          102400;
 pagespeed FileCacheCleanIntervalMs 360000;
 pagespeed FileCacheInodeLimit      500000;
 pagespeed DefaultSharedMemoryCacheKB 50000;
 pagespeed LRUCacheKbPerProcess     8192;
 pagespeed LRUCacheByteLimit        16384;
 pagespeed BlockingRewriteKey psatest;
 #Rewriting Level
 pagespeed RewriteLevel CoreFilters;
 #pagespeed RewriteLevel PassThrough;
 pagespeed EnableFilters elide_attributes,rewrite_domains;
 pagespeed EnableFilters rewrite_images,inline_preview_images,lazyload_images;
 pagespeed EnableFilters resize_mobile_images,sprite_images;
 pagespeed EnableFilters convert_jpeg_to_webp,convert_to_webp_lossless;
 pagespeed EnableFilters resize_rendered_image_dimensions;
 pagespeed EnableFilters insert_image_dimensions;
 pagespeed EnableFilters dedup_inlined_images;
 pagespeed EnableFilters canonicalize_javascript_libraries,inline_google_font_css;
 pagespeed EnableFilters inline_import_to_link,decode_rewritten_urls;
 pagespeed EnableFilters fallback_rewrite_css_urls,flatten_css_imports;
 pagespeed EnableFilters inline_css,move_css_above_scripts,move_css_to_head;
 pagespeed EnableFilters outline_css,combine_css,rewrite_css;
 #pagespeed EnableFilters prioritize_critical_css;
 pagespeed EnableFilters rewrite_style_attributes_with_url,rewrite_style_attributes;
 pagespeed EnableFilters combine_javascript,defer_javascript;
 pagespeed EnableFilters inline_javascript;
 pagespeed EnableFilters outline_javascript,rewrite_javascript;
 pagespeed EnableFilters local_storage_cache,extend_cache;
 pagespeed EnableFilters combine_heads,insert_ga,trim_urls,collapse_whitespace,remove_comments,remove_quotes,convert_meta_tags,insert_dns_prefetch,make_google_analytics_async,add_head;
 #pagespeed EnableFilters add_instrumentation;
 pagespeed EnableFilters pedantic;

 pagespeed CombineAcrossPaths off;
 pagespeed LazyloadImagesAfterOnload on;
 pagespeed LazyloadImagesBlankUrl "http://www.gstatic.com/psa/static/1.gif";
 pagespeed MaxSegmentLength 256;
 pagespeed CssFlattenMaxBytes 5120;
 pagespeed CssImageInlineMaxBytes 3000;
 pagespeed CssInlineMaxBytes 10485760;
 pagespeed CssOutlineMinBytes 51200;
 pagespeed MaxCombinedCssBytes -1;
 pagespeed ImageInlineMaxBytes 10485760;
 pagespeed ImageLimitOptimizedPercent 100;
 pagespeed ImageLimitResizeAreaPercent 100;
 pagespeed ImageRecompressionQuality 75;
 pagespeed ImageResolutionLimitBytes 32000000;
 pagespeed JpegRecompressionQuality 80;
 pagespeed JpegRecompressionQualityForSmallScreens 70;
 #pagespeed JpegNumProgressiveScans 8;
 #pagespeed JpegNumProgressiveScansForSmallScreens 10;
 #pagespeed WebpRecompressionQuality 80;
 #pagespeed WebpRecompressionQualityForSmallScreens 70;
 pagespeed JsInlineMaxBytes 10485760;
 pagespeed JsOutlineMinBytes 51200;
 pagespeed MaxCombinedJsBytes 10485760;
 pagespeed MaxInlinedPreviewImagesIndex -1;
 pagespeed MinImageSizeLowResolutionBytes 3072;
 pagespeed RetainComment " google_ad_section*";
 pagespeed RewriteRandomDropPercentage 0;
 pagespeed ImageMaxRewritesAtOnce 0;
 pagespeed ProgressiveJpegMinBytes 5120;
 pagespeed CriticalImagesBeaconEnabled false;
 pagespeed AvoidRenamingIntrospectiveJavascript on;
 #pagespeed AddOptionsToUrls on;

 #Respecting Vary Headers
 pagespeed RespectVary on;
 #Lower-casing HTML element and attribute names
 pagespeed LowercaseHtmlNames on;
 #Preserving HTML caching headers
 pagespeed ModifyCachingHeaders on;
 #Specifying the value for the PageSpeed header
 pagespeed XHeaderValue "Powered By Pagespeed";
 #Respecting X-Forwarded-Proto
 pagespeed RespectXForwardedProto on;
 #pagespeed RunExperiment on;
 pagespeed AnalyticsID UA-12345678-1;
 #pagespeed ExperimentVariable 1;
 #pagespeed ExperimentSpec "id=1;percent=50;level=CoreFilters;enabled=collapse_whitespace,remove_comments;";
 #pagespeed ExperimentSpec "id=2;percent=50;default;";

 #let's speed up PageSpeed by storing it in the super duper fast memcached
 pagespeed MemcachedServers "127.0.0.1:11211";
 pagespeed MemcachedTimeoutUs 100000;
2. /usr/local/nginx/conf/pagespeed_statslog.conf
#  Pagespeed stats logging 1.6.29.3+
pagespeed Statistics on;
pagespeed StatisticsLogging on;
pagespeed LogDir /var/log/pagespeed;
3. /usr/local/nginx/conf/pagespeed_handler.conf
#  Ensure requests for pagespeed optimized resources go to the pagespeed
#  handler and no extraneous headers get set.
location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" { add_header "" ""; }
location ~ "^/ngx_pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }
location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; }
location /ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; }
location /ngx_pagespeed_message { allow 127.0.0.1; deny all; }
location /pagespeed_console { allow 127.0.0.1; deny all; }
if ($request_uri ~ "(ngx_pagespeed_([^.]+)/(.*)?)") { break; }
4. /usr/local/nginx/conf/nginx.conf
user  www;
google_perftools_profiles /tmp/tcmalloc;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
# no need for more workers in the proxy mode
worker_processes 8;
error_log /var/log/nginx/error.log info;
#error_log /dev/null info;
worker_rlimit_nofile 5120;
events {
 worker_connections 5120; # increase for busier servers
 use epoll; # you should use epoll here for Linux kernels 2.6.x
}
http {
 access_log off;
 server_name_in_redirect off;
 server_names_hash_max_size 2048;
 server_names_hash_bucket_size 256;
 server_tokens off;
 include    mime.types;
 default_type  application/octet-stream;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 client_header_timeout 60s;
 client_body_timeout 60s;
 send_timeout 600s;
 reset_timedout_connection on;
 keepalive_timeout 5 60;
 fastcgi_connect_timeout 300;
 fastcgi_send_timeout 300;
 fastcgi_read_timeout 300;
 fastcgi_keep_conn on;
 fastcgi_buffer_size 16k;
 fastcgi_buffers 16 16k;
 fastcgi_busy_buffers_size 32k;
 fastcgi_temp_file_write_size 32k;
 fastcgi_intercept_errors on;
 open_file_cache max=51200 inactive=20s;
 open_file_cache_valid 30s;
 open_file_cache_min_uses 1;
 ssi on;
 ssi_silent_errors on;
 ssi_types text/shtml;
 gzip on;
 gzip_disable "MSIE [1-6].(?!.*SV1)";
 gzip_vary on;
 gzip_http_version 1.0;
 gzip_min_length 1100;
 gzip_comp_level 6;
 gzip_buffers 16 16k;
 gzip_proxied any;
 gzip_types application/ecmascript;
 gzip_types application/javascript;
 gzip_types application/pdf;
 gzip_types application/postscript;
 gzip_types image/svg+xml;
 gzip_types text/plain;
 gzip_types text/css;
 gzip_types text/csv;
 gzip_types application/json;
 gzip_types application/x-javascript;
 gzip_types text/xml;
 gzip_types application/xml;
 gzip_types application/xml+rss;
 gzip_types text/javascript;
 connection_pool_size 256;
 client_max_body_size 100m;
 client_body_buffer_size 128k;
 client_header_buffer_size 4k;
 large_client_header_buffers 4 4k;
 request_pool_size 32k;
 output_buffers 4 32k;
 postpone_output 1460;
 client_body_temp_path /tmp/nginx_client;
 proxy_temp_path /tmp/nginx_proxy;
 fastcgi_temp_path /tmp/nginx_fastcgi;
 uwsgi_temp_path /tmp/nginx_uwsgi;
 scgi_temp_path /tmp/nginx_scgi;
 limit_conn_zone $binary_remote_addr zone=one:10m;

 set_real_ip_from  127.0.0.1;
 real_ip_header    X-Forwarded-For;
 real_ip_recursive on;
 geoip_country  /var/lib/GeoIP/GeoIP.dat;
 geoip_city     /var/lib/GeoIP/GeoIPCity.dat;

 include pagespeed_libraries.conf;
 include pagespeed.conf;
 include pagespeed_statslog.conf;

 include "/usr/local/nginx/conf/vhosts/*.conf";
}
5. /usr/local/nginx/conf/vhosts/default.conf
server {
  listen 80 default;
  server_name _;
  access_log /var/log/nginx/default-access.log combined;
  error_log /var/log/nginx/default-error.log;
  root /var/www/html;
  index index.html index.htm index.php;
  charset utf-8;

  pagespeed on;
  include pagespeed_handler.conf;

  if (-d $request_filename){
    rewrite ^/(.*)([^/])$ $scheme://$host/$1$2/ permanent;
  }

  #include /var/www/html/nginx.conf;

  location / {
    try_files $uri @backend-runtime;
  }

  location @backend-runtime {
    proxy_set_header X-Forwarded-Ssl on;
    proxy_pass http://127.0.0.1:8080;
  }

  location ~* .(ftpquota|htaccess|htpasswd|asp|aspx|jsp|asa|mdb)?$ {
    deny all;
  }
}
关键词:nginx前端,前端优化模块,ngx_pagespeed