使用 PageSpeed 优化 Nginx,让你的网站更快

发表于2017-01-15   2084次阅读

PageSpeed 是一个款Google开源(Google出品必输竞品)用来自动优化网站的神器!通过改写HTML、CSS、JS文件源码以及一些简单配置就可以达到加速网站的效果,几乎涵盖了所有 Google PageSpeed Insights 所有的优化建议。支持 Apache 和 Nginx,鉴于 Apache 已是日薄西山,本文是基于Nginx的 PageSpeed 扩展模块做介绍。

相关网址:

安装

PageSpeed 需要嫁接在 Web 服务器上使用,目前支持 Apache 和 Nginx,考虑到 Apache 日薄西山的趋势,文本只以 nginx 下的使用为例。在操作系统上,目前还只支持 Linux 版本(我试过在 Mac 下源码编译的,但是问题很多,最终放弃了)。

官方提供的安装方式很详尽,参见相关官方文档(镜像),但实际使用时总会遇到各种问题,下面是我参考官方文档编写的一个源码编译安装的脚本,按照 Nginx 动态模块方式编译,供参考:

#!/bin/bash
# 官方文档
# https://github.com/pagespeed/ngx_pagespeed

NGINX_BIN_PATH=/home/admin/nginx/sbin/nginx
# Nginx 源码目录
NGINX_SOURCE_CODE_PATH=/home/admin/nginx/source_code/nginx-1.11.3
# Nginx 动态模块目录
NGINX_MODULES_PATH=/home/admin/nginx/modules
# PageSpeed 源码目录
NGX_PAGESPEED_SOURCE_DIR=/home/admin/nginx/modules_source_code/ngx_pagespeed

if [ ! -d "$NGINX_SOURCE_CODE_DIR" ]; then
    mkdir -p $NGINX_MODULES_PATH
fi

if [ ! -d "$NGX_PAGESPEED_SOURCE_DIR" ]; then
    mkdir -p $NGX_PAGESPEED_SOURCE_DIR
fi

# 下载最新版 nginx pagespeed 扩展包源码
cd $NGX_PAGESPEED_SOURCE_DIR
wget https://github.com/pagespeed/ngx_pagespeed/archive/latest-stable.zip
unzip latest-stable.zip

cd $NGX_PAGESPEED_SOURCE_DIR/ngx_pagespeed-latest-stable

# 下载 pagespeed 库文件
psol_url=https://dl.google.com/dl/page-speed/psol/1.11.33.4.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})  # extracts to psol/

# 查看原来 nginx 编译时的配置
NGINX_BUILD_CONF=`$NGINX_BIN_PATH -V 2>&1 >/dev/null |   grep 'configure' --color | awk -F':' '{print $2;}'`

cd $NGINX_SOURCE_CODE_PATH

# 动态模块编译
NGINX_BUILD_CONF="$NGINX_BUILD_CONF --add-dynamic-module=$NGX_PAGESPEED_SOURCE_DIR/ngx_pagespeed-latest-stable"

# 编译
./configure $NGINX_BUILD_CONF
make 

# 把编译好的库文件拷贝到 nginx 的动态模块目录中
cp $NGINX_SOURCE_CODE_PATH/objs/ngx_pagespeed.so $NGINX_MODULES_PATH

# 写入加载模块指令
echo 'load_module "modules/ngx_pagespeed.so";' > $NGINX_MODULES_PATH/ngx_pagespeed.conf

开启

开启或关闭用 pagespeed on/off; 指令,例如:

load_module "modules/ngx_pagespeed.so";
http {
    ...
}
server {
    listen       80;
    pagespeed on;
    pagespeed FileCachePath /tmp/ngx_pagespeed_cache;
    ...
}

验证

$ curl http://test.coderxing.com/ngx_pagespeed/add_head.html -I

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html
Connection: close
Date: Sun, 15 Jan 2017 05:26:49 GMT
X-Page-Speed: 1.11.33.4-0
Cache-Control: max-age=0, no-cache

出现 X-Page-Speed 字样表示安装成功。如果处于安全原因你不想显示具体的版本号,可以通过 XHeaderValue 参数将其改成别的值,例如:

pagespeed XHeaderValue "coderxing.com";

模块配置

HTTP Vary 协议

为了达到优化的最大效果,对于资源文件(css、js,HTML 文件除外)等,PageSpeed 是不遵循 Vary HTTP 头的,如果你希望 PageSpeed 完全遵守 Vary 协议,可以使用指令 pagespeed RespectVary on,不过除非有特殊需求,建议不开启,默认配置往往是最佳配置。关于 Vary 可以参考这篇文章 《Vary: User-Agent header》,大体的意思是就是 Vary 可以标示同一个 url 可以返回不同的内容,主要是给缓存中间件用的,避免只缓存单一内容。

Cache-Control: no-transform 协议

另外,PageSpeed 默认遵守 Cache-Control: no-transform 协议(参考(《HTTP 头中的 Cache-Control 》)[https://www.coderxing.com/http-cache-control.html]), 表示不可被中间代理软件改写,如果想让优化效果最大化,可以这样:

pagespeed DisableRewriteOnNoTransform off;

该指令,表示不遵守 Cache-Control: no-transform 协议。

PageSpeed 默认情况下会修改 HTML 页面汇总的 Meta 缓存标记,将其统一执为 Cache-Control: no-cache, max-age=0,如果要保留 HTML 页面原始的缓存控制指令,可以这样:

pagespeed ModifyCachingHeaders off;

不过官方并不建议关闭该指令,官方解释如下:

Note: We do not suggest you turn this option off. It breaks PageSpeed's caching assumptions and can lead to unoptimized HTML being served from a proxy caches set up in front of the server. If you do turn it off, we suggest that you do not set long caching headers to HTML or users may receive stale or unoptimized content.

保留相对路径

默认情况下,PageSpeed 在优化时会把相对路径转成绝对路径,如果因此而产生问题,你可以使用如下指令来保留相对路径

pagespeed PreserveUrlRelativity on;

NOTE: 官方文档上说,未来会默认保留相对路径,而且将来也会移除该指令。

开启 debug 功能

ListOutstandingUrlsOnError 可以列出优化过程中所有失败的请求,debug 时很有用,失败的信息会打印到 error log 里。

pagespeed ListOutstandingUrlsOnError on;

更多配置参考相关官方文档

管理员页面

PageSpeed 还提供了一个 web 的管理员界面来进行监控管理,很方便,如下图所示:

配置如下:


http{
    pagespeed FileCachePath /tmp/ngx_pagespeed_cache;
    pagespeed GlobalStatisticsPath /ngx_pagespeed_global_statistics;
    pagespeed GlobalAdminPath /pagespeed_global_admin;
}

server{
    pagespeed StatisticsPath /ngx_pagespeed_statistics;
    pagespeed MessagesPath /ngx_pagespeed_message;
    pagespeed ConsolePath /pagespeed_console;
    pagespeed AdminPath /pagespeed_admin;
}

直接访问 <域名>/pagespeed_admin 就可以打开管理员界面了。

更多配置参考相关官方文档 《PageSpeed Admin Pages》

针对 URL 单独进行限制

默认情况下,PageSpeed 会对HTML源码,以及HTML源码中的所有本地资源文件(CSS、图片、JS)进行改写。如果有定制需求或者通过PageSpeed过滤后网页异常,可以使用如下指令进行定制:

    # 启用通配符匹配
    pagespeed Allow wildcard_spec;
    # 禁止某些js文件被过滤
    pagespeed Disallow "*/jquery-ui-1.8.2.custom.min.js";
    pagespeed Disallow "*/js_tinyMCE.js";

更复杂一点的例子:

    pagespeed Disallow "*";
    pagespeed Allow "http://*example.com/*.html";
    pagespeed Allow "http://*example.com/*/images/*.png";
    pagespeed Allow "http://*example.com/*/styles/*.css";
    pagespeed Disallow "*/images/captcha/*";

更多相关指令和例子参考《PageSpeed URL Control》《PageSpeed Authorizing and Mapping Domains》

回源配置

如果你有自建的资源服务器,这个指令会很有用,源站保存原始文件,前端的资源服务器安装 PageSpeed 做优化处理,用户发起请求是,如果本机缓存没有找到,则请求源站。回源配置例如:

pagespeed MapOriginDomain http://localhost https://www.example.com;
pagespeed ShardDomain https://www.example.com
                      https://example1.cdn.com,https://example2.cdn.com;

更多指令和例子参考《PageSpeed Authorizing and Mapping Domains》

过滤器配置

PageSpeed 是通过一个一个的“过滤器”进行优化的,由于过滤器较多,官方提供了三组过滤器集合来批量设置 PassThroughCoreFiltersOptimizeForBandwidth

CoreFilters 包含最新的过滤器,可靠性一般, OptimizeForBandwidth 提供更强的可靠性。如果想关闭 CoreFilters 可以使用如下指令:

pagespeed RewriteLevel PassThrough;

手动启用、关闭过滤器

启动过滤器用 EnableFilters 参数。

pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters combine_css,extend_cache,rewrite_images;
pagespeed EnableFilters rewrite_css,rewrite_javascript;

关闭过滤器用 DisableFilters 参数,例如:

pagespeed DisableFilters rewrite_images,combine_css;

禁用过滤器用 ForbidFilters 参数,例如:

pagespeed ForbidFilters rewrite_css,rewrite_javascript;

禁用所有关闭的过滤器:

pagespeed ForbidAllDisabledFilters true;

关闭的意思是关闭自动过滤功能,单通过 url 参数方式任然可以访问,比如即使设置了 pagespeed DisableFilters add_head; 但是访问 test.coderxing.com/ngx_pagespeed/add_head.html?PageSpeed=on&PageSpeedFilters=add_head 仍然有效,如果使用 ForbidFilters 则是彻底禁用。

可以通过 url 参数来动态控制过滤器

例如:

 http://modpagespeed.com/rewrite_css.html?PageSpeed=on&PageSpeedFilters=rewrite_css

开启过滤器用参数 PageSpeed=on, 过滤器列表用参数 PageSpeedFilters,多个过滤器用“,” 分割。

更多配置参考相关官方文档 《Experimenting with PageSpeed——Per-request configuration》

更多过滤器配置参数参考相关官方文档 《Configuring PageSpeed Filters》

常用过滤器

collapse_whitespace

去掉 HTML 页面中多余的空格,减少页面体积。例子参见《Collapse Whitespace》

combine_css

多个 css 文件合并成一个,可以减少资源请求次数。例子参见《Combine CSS》。可以通过 MaxCombinedCssBytes 来设置多大的 css 文件才可以合并,超过该值得则不会合并。

combine_heads

将多个 head 标签合并成一个。

combine_javascript

将多个 javascript 文件引用合并成一个。

inline_images

将小图片的 http 调用转成内联方式调用。

dedup_inlined_images

存在多个相同的内联图片的话,通过 js 控制,只保留第一个内联的数据。这样可以删除重复数据,较小页面体积。经常和 inline_images 过滤器配合使用。

elide_attributes

移除多余 HTML 标签。例子参见 《Elide Attributes》

pedantic

补全 script 和 style 的 type 标签。

extend_cache

增加静态资源的缓存效果,比如增加 max-age 缓存时间等等。该指令,相当于 extend_cache_imagesextend_cache_scriptsextend_cache_css 三个指令的合用效果。

inline_css

将小的 css 文件已内联方式引入,避免 http 请求。

inline_javascript

将小的 js 文件已内联方式引入,避免 http 请求。

insert_dns_prefetch

自动插入 dns-prefetch 标签。关于 dns-prefetch 的作用可参考博客的另一篇文章《dns-prefetch DNS 预解析优化页面加载速度》

lazyload_images

图片懒加载。详情参考 《Lazyload Images》

move_css_above_scripts

将 css 内容移动到 script 之前,优先于 script 渲染。

move_css_to_head

将 css 文件已到头部。显示优先,让用户体验更好。

outline_css、outline_javascript

inline_cssinline_javascript 相反,这两个指令是把 css 和 js 内容抽成文件再引入。

remove_comments

移除 HTML 中的注释。

remove_quotes

移除 HTML 属性中的不必要的引号。

resize_rendered_image_dimensions

按照合适的格式和尺寸展示图片,比如一个 700x700 的图片,实际显示时只是 200x200,那么会自动转成 200x200 大小的图片。例子参考 《Optimize Images》

rewrite_css

最小化 css 文件,去掉多余的空格和换行,并删除注释。

rewrite_javascript

最小化 js 文件,和 rewrite_css 类似。

trim_urls

删除无用的 url 前缀。例子参考 《Trim URLs》

sprite_images

自动将多张背景图片合并成一张图片。在处理一些图标图片时很有用。

resize_mobile_images

responsive_images

rewrite_images

图片优化专题

参考 《Image Filter and Option Reference》

更多过滤器

更多过滤器请访问如下网址:

更多功能

和 memcached/redis 集成

PageSpeed 可以和 memcached/redis 集成,让优化的缓存内容在多机之间共享,前提是多台机器的 PageSpeed 配置一致,集成指令如下:

    pagespeed MemcachedServers "host1:port1,host2:port2,host3:port3";

    pagespeed RedisServer "host:port";

而且还可以和 Varnish 集成,这里就不介绍了,参考这里《Configuring Downstream Caches》

注意:Redis 支持只有 1.12.34.1 版本以后才有。

相关官方文档参考 《PageSpeed System Integration》

远程配置

PageSpeed 可以使用远程配置文件,例如:

# 配置文件地址
pagespeed RemoteConfigurationUrl https://example.com/remote.conf;

# 配置文件缓存过期周期,以秒为单位
pagespeed RemoteConfigurationTimeoutMs 1500;

相关官方文档参考 《Configuring PageSpeed Filters》

其他

如果你使用 https 协议,则需要加上如下指令之后,某些过滤器才能生效,详见官方文档《PageSpeed HTTPS Support》


pagespeed FetchHttps enable,allow_self_signed,allow_unknown_certificate_authority,allow_certificate_not_yet_valid;

参考

coderxing.com 的配置是这样的

        pagespeed EnableFilters collapse_whitespace;
        pagespeed EnableFilters combine_css;
        pagespeed EnableFilters combine_javascript;
        pagespeed EnableFilters inline_images,dedup_inlined_images;
        pagespeed EnableFilters elide_attributes;
        pagespeed EnableFilters extend_cache;
        pagespeed EnableFilters insert_dns_prefetch;
        pagespeed EnableFilters lazyload_images,responsive_images,rewrite_images,resize_mobile_images,resize_rendered_image_dimensions;
        pagespeed EnableFilters move_css_above_scripts;
        pagespeed EnableFilters remove_comments;
        pagespeed EnableFilters resize_rendered_image_dimensions;
        pagespeed EnableFilters rewrite_css;
        pagespeed EnableFilters rewrite_javascript;

        pagespeed FetchHttps enable,allow_self_signed,allow_unknown_certificate_authority,allow_certificate_not_yet_valid;