pagespeedGitHub)是 Goolge 为 Apache 和 nginx 开发的前端优化扩展模块,其中适用 Apache 环境的叫 mod_pagespeed,适用于 nginx 环境的叫 ngx_pagespeed

pagespeed 功能简介

pagespeed 的功能包括但不限于以下方面:
优化传输带宽(过滤)(压缩图片、CSS、JS文件,去除html空白、注释...)、降低请求(CSS、JS文件合并、图片雪碧、识别并重定向常用JS库、缓存控制)、域名映射(支持CDN)、提升客户端体验(图片预加载、延迟加载,移动端图像优化),同时还提供对 https 的支持。

nginx 下 pagespeed 的编译安装

安装方法 Google pagespeed 网站上有详细介绍,复制过来方便不能翻墙的朋友查看。

安装依赖

RedHat, CentOS, or Fedora

sudo yum install gcc-c++ pcre-devel zlib-devel make unzip libuuid-devel

Ubuntu or Debian

sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip uuid-dev

下载 ngx_pagespeed

目前 ngx_pagespeed 最新的版本是 1.13.35.2-stable(需要 gcc ≥ 4.8 或者 clang ≥ 3.3,如果不符合要求请升级 gcc 或 clang,或者继续使用旧版:1.9.32.11),想使用其它版本直接用新版本号替换掉下面的 1.13.35.2-stable 即可。

#[check the release notes for the latest version]
NPS_VERSION=1.13.35.2-stable
cd
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}.zip
unzip v${NPS_VERSION}.zip
nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d)
cd "$nps_dir"
NPS_RELEASE_NUMBER=${NPS_VERSION/beta/}
NPS_RELEASE_NUMBER=${NPS_VERSION/stable/}
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.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 并编译 ngx_pagespeed 模块

编译 ngx_pagespeed 模块分两种情况:1、全新安装;2、当前版本添加。

1、全新安装 nginx 并加入 ngx_pagespeed 模块

下面是全新安装 nginx 1.16.1,改成需要的版本即可。

cd
NGINX_VERSION=1.16.1
cd
wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
tar -xvzf nginx-${NGINX_VERSION}.tar.gz
cd nginx-${NGINX_VERSION}/
./configure --add-module=$HOME/ngx_pagespeed-${NPS_VERSION} ${PS_NGX_EXTRA_FLAGS}
make
sudo make install
2、当前版本添加 ngx_pagespeed 模块

如果当前服务器已经安装了 nginx 则需要先查看当前的 nginx 版本号:
nginx -V

确定了当前服务器的 nginx 版本号,即可使用下面的代码编译安装了,./configure 中的 module 请根据需要进行配置:

NGINX_VERSION=1.16.0
wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
tar -xvzf nginx-${NGINX_VERSION}.tar.gz
cd nginx-${NGINX_VERSION}/
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --add-module=/root/incubator-pagespeed-ngx-1.13.35.2-stable
make
sudo make install

配置 ngx_pagespeed

配置用的过滤参数这里有详细说明:http://ngxpagespeed.com/

创建配置文件

在 /usr/local/nginx/conf/ 添加 pagespeed 配置文件:
vi /usr/local/nginx/conf/pagespeed.conf
根据实际需求加入类似下面的配置参数:

		# on 启用,off 关闭
		pagespeed on;
		# 重置 http Vary 头
		pagespeed RespectVary on;
		# html字符转小写
		pagespeed LowercaseHtmlNames on;
		# 压缩带 Cache-Control: no-transform 标记的资源
		#pagespeed DisableRewriteOnNoTransform off;
		# 相对URL
		#pagespeed PreserveUrlRelativity on;
		pagespeed XHeaderValue "Powered By ngx_pagespeed";
		
		# 开启 https
		#pagespeed FetchHttps enable;
		
		# 配置服务器缓存位置和自动清除触发条件(空间大小、时限)
		pagespeed FileCachePath "/var/ngx_pagespeed/";
		pagespeed FileCacheSizeKb 2048000;
		pagespeed FileCacheCleanIntervalMs 43200000;
		pagespeed FileCacheInodeLimit 500000;
		# 过滤规则
		pagespeed RewriteLevel PassThrough;
		# 不需过滤的目录或文件
		pagespeed Disallow "*/wp-admin/*";
		pagespeed Disallow "*/wp-login.php*";
		
		# 移除不必要的url前缀,开启可能会导致某些自动加载功能失效
		#pagespeed EnableFilters trim_urls;
		# 移除 html 空白
		pagespeed EnableFilters collapse_whitespace;
		# 移除 html 注释
		pagespeed EnableFilters remove_comments;
		# DNS 预加载
		pagespeed EnableFilters insert_dns_prefetch;
		# 压缩CSS
		pagespeed EnableFilters rewrite_css;
		# 合并CSS
		pagespeed EnableFilters combine_css;
		# 重写CSS,优化加载渲染页面的CSS规则
		pagespeed EnableFilters prioritize_critical_css;
		# google字体直接写入html 目的是减少浏览器请求和DNS查询
		pagespeed EnableFilters inline_google_font_css;
		# 压缩js
		pagespeed EnableFilters rewrite_javascript;
		# 合并js
		pagespeed EnableFilters combine_javascript;
		
		#pagespeed EnableFilters rewrite_style_attributes;
		# 压缩图片
		#pagespeed EnableFilters rewrite_images;
		# 不加载显示区域以外的图片
		pagespeed LazyloadImagesAfterOnload off;
		# 图片预加载
		pagespeed EnableFilters inline_preview_images;
		# 移动端图片自适应重置
		pagespeed EnableFilters resize_mobile_images;
		# 图片延迟加载
		pagespeed EnableFilters lazyload_images;
		# 雪碧图片,图标很多的时候很有用
		#pagespeed EnableFilters sprite_images;
		# 扩展缓存 改善页面资源的可缓存性
		pagespeed EnableFilters extend_cache;
		# 不将规则应用在 wp-admin目录 和 wplogin.php页面
		pagespeed Disallow "*/wp-admin/*";
		pagespeed Disallow "*/wp-login.php*";

		
		# 风险指数高,不建议开启
		#pagespeed EnableFilters local_storage_cache;
		# 不能删
		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_global_admin {
			allow 127.0.0.1;
			deny all;
			}
		
		pagespeed StatisticsPath /ngx_pagespeed_statistics;
		pagespeed MessagesPath /ngx_pagespeed_message;
		pagespeed ConsolePath /pagespeed_console;
		pagespeed AdminPath /pagespeed_admin;
		
		# 控制台 可通过 http://domain.com/ngx_pagespeed_admin 来查看控制台
		pagespeed Statistics on;
		pagespeed StatisticsLogging on;
		pagespeed LogDir /var/log/pagespeed;
		location /pagespeed_console {
			allow 127.0.0.1;
			deny all;
			}
		pagespeed AdminPath /ngx_pagespeed_admin;
		
		location ~ ^/pagespeed_admin {
			allow 127.0.0.1;
			deny all;
		}
		# 日志限制
		pagespeed StatisticsLoggingIntervalMs 60000;
		pagespeed StatisticsLoggingMaxFileSizeKb 1024;

ESC键,输入:wq保存并退出。

引入 pagespeed 到网站配置文件

打开网站的配置文件,如:
vi /usr/local/nginx/conf/vhost/nanshanxia.com.conf
i加入
include pagespeed.conf;,最后再ESC:wq保存退出。

检查 nginx 配置

/usr/local/nginx/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 使 pagespeed 生效

接着重启 nginx 让 pagespeed 生效
service nginx restart

验证 pagespeed 是否生效

使用 curl 验证 pagespeed 是否生效:
curl -I 'http://maliyana.com' | grep X-Page-Speed

然后再访问网站,速度就有提升了。

启用 pagespeed 后 WP Super Cache 这个插件基本就没什么作用了,所以,又可以减掉一个插件了。

今晚把这个网站的 VPS 服务器升级到 PHP7,感觉网站在 PHP7 下的响应速度比 5.4、5.6 时快了稍许,再配合 pagespeed 速度优势明显,要是再加上 cloudflare 估计会更快。我的 VPS 是 256M 的 OpenVZ,探针显示 PHP7 下服务器内存占用相比 5.x 时有降低。

WordPress 升级 PHP7

上面说的都是好处,其实问题也很多。

兼容性问题

WordPress 程序本身完全兼容 PHP7,但是,有部分插件或主题可能会有不兼容的问题。

在用的 WP Super Cache、Akismet、Google XML Sitemaps 和 Comment Email Reply 这几个插件暂未发现兼容性问题。倒是上面一个同学的网站使用了国内的开源 PHP 程序不兼容 PHP7,直接挂掉了。

由于是刚发布的新版本,部分模块/扩展可能短时间无法及时跟进,技术文档相对欠缺,升级、调试甚至恢复必然要花费时间精力等成本。

昨天早上曾试图升级 PHP7,无奈有一处错误一直过不去,不能耽误孩子的周末,作罢,结果昨晚回家重启了一下 VPS 数据库死活启动不了…

综上,如果不是非升不可,建议等上一段时间,待条件成熟相对稳定了再升级。

特定条件下 Home 键失灵:

表现为:屏幕锁定隔一段时间后按下 home 键无法激活(点亮)屏幕,第二次再按一切正常:亮屏、解锁…

少数情况无法自动锁定:

设定一分钟自动锁定,奇怪的是有个别时候静置很久却没有自动锁定,哪怕是在主屏幕。

偶尔无法清除通知栏消息:

出现通知栏消息无法清除的频率很低,一共遇到三次:IFTTT、QQ 和 inbox 各一次,重启系统后可正常清除。

现在看来,除了权限控制还是 moto x 用的顺手。

这个博客自开始使用无限滚动至今已有好长时间了。最开始用的是 infinite-scroll 这个插件来实现无限滚动,这个插件有很长时间没有更新了,jQuery 在这期间都迭代几个版本了,作者大概也不想花心思在这个插件上面了,说实话尽管如此它仍能很好地忠于本职工作,最近偶然用了一次 IE8,无限滚动竟然不能正常工作了,这可不行。并不打算弄清楚具体是什么原因导致的了,只是想换一种实现方式。

于是,找到了 JScroll,这个比 infinite-scroll 要轻一些,功能和使用方法类似,有一个不好地方是 JScroll 在实现分页的时候会在每页容器内另加一层 div 包围,同时 IE8 上扔然有些小不完美,勉强也可以接受,在本地调试成功。谁知上传到服务器后特么的死活不滚了,还找不原因,看代码啥的也没问题,到底是肚子痛还是四肢麻木无从知晓,真是有缘无分(后来用了接下来的这个插件才找出来原因:问题出在 nginx 配置的一个插件的设置上),这给了我认识下面这个插件的机会。

周二晚上回家的路上,无意找到了 infinite ajax scrollgithub地址),简称 ias,这是个商业插件,非盈利性网站可免费使用,最新版本是v3.0.1,用法跟前面两个相似:

第一步:

1、下载 jquery-ias.min.js,把jquery-ias.min.js文件放到主题目录下的 js 文件夹里。

2、查看主题是否已经加载了 jQuery 库,如果没有那么打开主题目录下的footer.php文件,把下面一行代码粘贴在</body>标签之前,这是 cloudflare 免费提供的 jQuery 公共库,好处是支持 https:

<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>

3、接着加载jquery-ias.min.js:把下面一行代码放到上面代码的下面。

<script src="<?php echo get_template_directory_uri(); ?>/js/jquery-ias.min.js" type="text/javascript"></script>

第二步:

查看页面的 div 结构,目的是为第三步做准备:

<div id="content">
	<div class="post">日志一</div>
	<div class="post">日志二</div>
	<div class="post">日志三</div>
</div>
<div class="pagination">
	<a href="/page2/" >next</a>
</div>

第三步:

infinite ajax scroll 共有4个必要的配置参数,分别是:containeritempaginationnextdelaynegativeMargin可选,不建议修改)
并且需要和第二步 html 代码里的 id 或 class 做如下的映射关系方可正常工作:

container 对应 #content
item 对应 .post
pagination 对应 #pagination
next 对应 .next

映射完毕,得到如下的代码,放到第一步<script src="<?php echo get_template_directory_uri(); ?>/js/jquery-ias.min.js" type="text/javascript"></script>所在行的后面:

<script type="text/javascript">
	var ias = $.ias({
		container: "#content",
		item: ".post",
		pagination: ".navigation",
		next: ".navigation a",
	});
</script>

添加完毕,刷新一下即可无限滚动了。

这个插件还支持扩展

半自动加载,更改手动加载提示文字

启用后默认一滚到底,如果想搞点个性的也是可以的,如从第五页开始手动加载offset: 5,手动加载的提示文字为加载更多...,那么代码如下

ias.extension(new IASTriggerExtension({
	offset: 5,
	text: '加载更多&hellip;',
	html: '<div class="ias-trigger ias-trigger-prev bee"><a>{text}</a></div>'
}));

更改 gif 图片:

ias.extension(new IASSpinnerExtension({
	src: "gif图片地址",
	html: '<div class="ias-spinner bee"><img src="{src}"/></div>'
}));

更改末尾的提示文字:

ias.extension(new IASNoneLeftExtension({
	text: '已到结尾',
	html: '<div class="ias-trigger ias-noneleft bee">{text}</div>'
}));

把上面的扩展代码添加到第三步</script>前面就成了。

除了滚动日志列表,还可以滚动评论,滚动文章内容。

参考插件网站获取更多个性设置:http://infiniteajaxscroll.com

将 gif 转换成代码内嵌到代码中

上面更改 gif 图片时会用到 gif 的路径地址,特别是在 js 文件中是很不方便的,可以把 gif 图片通过 base64 编码转换成一串代码(data URI)内嵌到代码中,通过浏览器访问的时候,会把代码解读还原成图片,很方便,这里有一个在线转换服务,可以转换 JPG、PNG、GIF 或 BMP 格式的图像文件:
https://www.base64-image.de

优点:自然是免去更改文件位置带来的麻烦,减少 http 请求。
缺点:IE8 以下(IE6、7,不包括IE8)的浏览器不支持,IE8 只能支持最多 32KB 的 data URI。

上周启用了 https,昨天偶然使用 IE8 竟然打不开我的网站了,连链接都没有建立,刷新、清缓存、InPrivate 都不行,换 Chrome 也不行,还好 Chrone 有错误提示:
ERR_SSL_VERSION_OR_CIPHER_MISMATCH

唯有我常用的 Firefox 可以正常打开,忘了说,我的操作系统是 Windows XP。

我的主题对 IE 家族做了特殊照顾,向下兼容到 IE6,如果单单是 IE8 以下的浏览器打不开这还能接受,但是 Chrome 也打不开,这就不能接受了。Google 一下ERR_SSL_VERSION_OR_CIPHER_MISMATCH这个错误,在 nginx 网站找到一个答案,说要启用 SNI。然而,这并不是造成以上问题的原因,真正的原因是 cloudflare 的免费CDN 对使用 TLS 协议封装加密的 https 做了限制,要求客户端浏览器必须支持 TLS 的 SNI 扩展,而 XP 系统上 IE、chrome 都不支持 SNI。

SNI 是什么

简单来说 SNI 是 TLS 的一个功能扩展,有了 SNI 就可以在单个 IP 上启用多个 SSL 证书,现实一点说就是可以在只有一个 IP 地址的 VPS 上建立两个或更多的 https 网站了。

关于 SNI 这里有详细介绍:
http://blog.layershift.com/sni-ssl-production-ready

支持 SNI 的浏览器

当今地球上支持 SNI 的主流浏览器如下:

  • Opera 8.0 及更新版本;
  • MSIE 7.0(Windows Vista 或更新版本,XP 下的 MSIE 不支持 SNI);
  • Firefox 2.0 或使用 Mozilla 1.8.1 及更新平台的其它浏览器(的确牛逼);
  • Safari 3.2.1(Windows Vista 或更新版本);
  • Chrome(Windows Vista 或更新版本)。

详情请参见:
http://nginx.org/en/docs/http/configuring_https_servers.html

OpenSSL 对 SNI 的支持

OpenSSL 自 0.9.8f 开始支持 SNI(选配),选配参数--enable-tlsext
OpenSSL 0.9.8j 开始默认启用 SNI。

检测 nginx 是否启用 SNI

nginx -V
出现:
TLS SNI support enabled
即表明 SNI 已启用。

多个SSL证书报错

在有 SNI 之前,以往一个 IP 地址只能存在一个 SSL 证书,否则会提示证书错误。

cloudflare 的免费CDN 只适用于支持 SNI 的浏览器

用了 cloudflare 的免费CDN,速度确实快了很多很多,但是,上面说了 cloudflare 的免费 CDN 限制采用 TLS 封装的 https 只有在支持 SNI 扩展的浏览器才能正常访问。

表现为:

  • IE(6、7、8)无法建立连接。
  • chrome 提示:
    ERR_SSL_VERSION_OR_CIPHER_MISMATCH

本可以不对客户端的浏览器做 SNI 限制,这样做很大一部分原因可能是从成本或产品策略考虑。结合上面说的支持 SNI 扩展的浏览器,也就是说在 Windows XP 下的 IE全线、chrome 浏览器都无法通过 https 方式访问,这恰恰是企业无法忽略的。

这个不该成为问题的问题困扰了我两天时间,一直到当我怀疑这是 cloudflare 免费CDN的限制的时候,停掉 cloudflare 的免费CDN,问题才不解自破。

回头再看,cloudflare 的页面上有这方面限制的明确说明,只能怪自己做事不仔细。

如果同一服务器启用多个 https 网站后无法访问,可能有以下原因:

  1. 服务器只有一个IP地址(有多个IP需做配置);
  2. 服务器没有启用 SNI;
  3. cloudflare 的免费CDN 对使用 TLS 协议加密的 https 做了限制,要求浏览器必须支持 TLS 的 SNI 扩展。

还有多少人使用 Windows XP

有多少人使用 Windows XP 这个问题无从知晓,但Google 统计显示在访问我博客的Windows用户中,Windows XP约占36%,以实际访问量来换算,除了我自己之外,大概很少很少有其他人了,所以,目前不用急着去解决启用 SNI 后 Windows XP 的兼容问题。