Nginx下PageSpeed前端优化模块的安装与配置_基于Ubuntu系统

2017年11月25日 99 字 教程整理


ngx_pagespeed是Nginx的一个扩展模块,主要的功能是针对前端页面而进行服务器端的优化,对前端设计人员来说,可以省去优化css、js以及图片的过程。

作为Nginx的组件,ngx_pagespeed的主要作用是自动合并和缩减js/css脚本,以及图片的压缩实现前端网页的重写,让用户以更快的速度进行访问。

PageSpeedpagespeed 主要用来加快浏览器的渲染加载,旨在缩短网页加载的时间,减少网站服务器的带宽使用量。有了 PageSpeed,网站开发人员就可以在开发前端页面的时候,可以稍微轻松一点,把前端优化的任务都交给服务器来处理。虽然这会使服务器负载增加;但从减少客户请求数的角度去看,牺牲部分服务器性能还是值得的,随着服务器的逐渐普及,对应的负载可以通过增加服务器配置来支持。

1. ngx_pagespeed项目简介及主要作用

1.1. ngx_pagespeed的功能特性

ngx_pagespeed是一个开源的Nginx模块,由Google创建,通过重写网页以减少延迟和带宽来帮助Web更快。ngx_pagespeed几乎为我们提供了优化网站前端页面所需要的所有功能,可以使用数量众多的重写“过滤器”,每个过滤器都可以选择性地开启/关闭,从而自动进行各种优化(比如,减小文档大小,减少HTTP请求数据,减少HTTP往返次数以及缩短DNS解析时间)。如下是一些比较常用的功能:

  • 图像优化:移除图片元数据、动态调整,重新压缩
  • CSS 和 JavaScript 压缩、合并、级联、内联,把当前页面需要的 CSS 直接放在页面中,符合 PageSpeed Insights 提出的 “清除首屏内容中阻止呈现的 JavaScript 和 CSS” 原则。
  • 小资源内联,比如比较小的图片,直接转换成 base64 格式的,放在 HTML 中。
  • 推迟图像和 JavaScript 加载,只加载当前屏幕显示的图像,异步加载 JavaScript
  • 对HTML重写、压缩空格、去除注释等,将 HTML 页面中不必要的内容移除,减少了 HTML 的体积。
  • 提升缓存周期,把静态资源的缓存过期时间提高了。
  • 最小化往返次数 - 削减连续的请求/响应周期数。
  • 最小化请求开销 - 削减上传大小。
  • 最小化负载大小 - 削减响应,下载及缓存页面大小。
  • 优化浏览器渲染 - 改善浏览器页面布局。
  • 移动方面的优化 - 优化站点移动网络和设备方面的相关特性。

ngx_pagespeed目前还在不断更新和完善中,更多信息可以查看专题网站或GitHub项目主页:

1.2. 优化效果

ngx_speed自动处理页面加载的CSS/js文件,这个机制很赞,多个重用度高的外联CSS文件都被合并压缩了,重用度很低的文件直接添加到了html的header头。安装ngx_pagespeed之后再加载服务器上的网页项目,发现对应的脚本和请求变为如下的样式,说明ngx_pagespeed配模块已经配置成功:

网站服务器使用 ngx_pagespeed 优化过后,通过 PageSpeed Insights 测试出来的分数,不管是移动端、还是桌面端,均达到了100分,这是手工优化前端页面很难达到的高度。当然,优化的过程是动态的,也不是每个页面随时都能达到这个分数,但是整体上来看,使用 ngx_pagespeed 优化后,前端页面的打开速度确实快了许多,用肉眼就能分辨出来。

2. 安装步骤

与Apache网站服务器不一样,Nginx模块无法在运行时动态加载,而是必须在编译时加载。目前阶段,ngx_pagespeed模块并未内置在随主要Linux发行版(比如Fedora 19)发布的Nginx程序包中。因而,想使用Nginx中的PageSpeed,还是要利用源代码来重新编译和构建Nginx来完成安装。也就是说,如果服务器已安装Nginx,需要在此基础上增加ngx_pagespeed模块,仍需重装或在原来的安装包基础上重新编译和安装Nginx

【注】由于ngx_pagespeed模块仍在开发阶段,并没有与不同版本的Nginx程序及依赖库完美兼容,所以在如下步骤中,应根据实际Nginx和ngx_pagespeed的版本来选择对应依赖库的下载和安装。(这也是为什么目前网络上安装ngx_pagespeed教程的成功案例无法复制的原因。)
如本文所选的配置组合如下:

  • nginx-1.10.3
  • openssl-1.0.2m
  • pcre-8.3.9
  • ngx_pagespeed-latest-beta
  • PSOL-1.13.35.1

如果上述其中任何一个依赖库或安装包的版本不能同步兼容,可能最后安装编译就不会成功。因此在参照网络上的安装教程时,一定注意自己选择的版本及对应的关联依赖库的版本配合。

以下为ngx_pagespeed模块安装的完整步骤:

2.1. 进入源码目录,准备下载源码及依赖库

首先进入nginx 源码同级目录,如 ‘/usr/local/src/‘,下载并保存多个源码及依赖库的压缩文件,以备后续的统一管理:

cd /usr/local/src/

2.1.1. 下载并解压ngx_pagespeed模块

下载ngx_pagespeed压缩包:

wget https://github.com/pagespeed/ngx_pagespeed/archive/latest-beta.tar.gz

下载完成后,解压安装包:

tar zxvf  latest-beta.tar.gz

2.1.2. 下载psol优化库

接下来要下载预构建的PSOL(PageSpeed优化库,https://developers.google.com/speed/pagespeed/psol),并将它安装到ngx_pagespeed目录下。这里要注意版本要配合ngx_pagespeed的对应需求,网络上有些教程是早期的教程,可能导致下载到的psol是早期版本,编译不能通过。

在这里,可以打开解压过的ngx_pagespeed安装包,查看PSOL_BINARY_URL文件,可见这一版本ngx_pagespped对应的PSOL版本为:1.13.35.1 。

在这里需注意,在本文所用版本的ngx_pagespeed中,允许的PSOL版本为1.13.35.1版本(详见【下载指定版本的PSOL压缩包】章节),对其余版本的ngx_pagespeed可能不适用。

2.1.2.1. 下载指定版本的PSOL压缩包:

wget https://dl.google.com/dl/page-speed/psol/1.13.35.1-$BIT_SIZE_NAME.tar.gz

使用uname -ar命令,先查看系统位数。如系统为64位,则输入:

wget https://dl.google.com/dl/page-speed/psol/1.13.35.1-x64.tar.gz

即可下载。

2.1.2.2. 将PSOL源码解压到ngx_pagespeed源码目录下

tar xzf 1.13.35.1-x64.tar.gz -C /usr/local/src/ngx_pagespeed-latest-beta/  

2.1.3. 准备Nginx安装包

这里分为两种情况,已预先安装好Nginx服务器和未安装过Nginx。在这里推荐选择重装的方式进行再次编译,以保证各个模块不发生冲突。

如之前预先安装过Nginx,可通过./nginx -V命令查看Nginx版本。如版本明显高于ngx_pagespeed部件,则可能不支持两者的关联,建议重新下载稍微早些的版本压缩包。

在这里,假设为第二种情况进行这一步准备:

2.1.3.1. 下载并解压Nginx安装包

wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -xvzf nginx-1.10.3.tar.gz

2.1.3.2. 下载openSSL

cd /usr/local/src
wget https://www.openssl.org/source/openssl-1.0.2m.tar.gz
tar -xzvf openssl-1.0.2m.tar.gz && rm -rf openssl-1.0.2m.tar.gz

2.1.3.3. 下载PCRE

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz
tar -xzvf pcre-8.39.tar.gz && rm -rf pcre-8.39.tar.gz

2.2. 获取并更新Nginx-configure arguments

2.2.1. 查看Nginx程序configure配置参数

这一步适用于之前安装过Nginx服务器的用户。如新安装Nginx,则直接进入下一步。

输入: nginx -V ,查看Nginx的configure arguments。
如下:

2.2.2. 重新整理configure arguments

在上述查询到的configure arguments结果下,重新整理所需软件及依赖库(如为新安装Nginx,直接拼接即可):

2.2.2.1. 添加openssl目录位置

 --with-openssl=../openssl-1.0.2m

2.2.2.2. 添加pcre目录位置

--with-pcre=../pcre-8.39

2.2.2.3. 添加ngx_pagespeed模块

在–prefix最末尾添加:

--add-module=/usr/local/src/ngx_pagespeed-latest-beta

最终调整结果类似如下结构:

--prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-ipv6 --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=/usr/local/src/openssl-1.0.2m --with-pcre=/usr/local/src/pcre-8.39 --with-pcre-jit --with-ld-opt=-ljemalloc --add-module=/usr/local/src/ngx_pagespeed-latest-beta

2.2.3. 开始安装和编译Nginx

2.2.3.1. 重新编译Nginx安装文件

进入nginx源码目录:

cd /usr/local/src/nginx-1.11.3/

按照前一步获得的configure arguments,重新编译nginx:

make clean
./configure <整理过的configure arguments参数>

如:

 ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-ipv6 --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=/usr/local/src/openssl-1.0.2m --with-pcre=/usr/local/src/pcre-8.39 --with-pcre-jit --with-ld-opt=-ljemalloc --add-module=/usr/local/src/ngx_pagespeed-latest-beta

2.2.3.2. 开始安装:make&make install

make && make install

至此,配置有ngx_pagespeed模块的Nginx服务器已完成安装。

接下来调整Nginx服务器的配置,即可使ngx_pagespeed模块开始工作。

3. 配置Nginx中的ngx_pagespeed模块

想启用并配置ngx_pagespeed,就要编辑Nginx配置的server部分。nginx.conf的下面这个示例表明了如何指定一个或多个PageSpeed过滤器。

在nginx.conf文件的server模块里面加入如下代码:

# 启用ngx_pagespeed
pagespeed on;
pagespeed FileCachePath /tmp/cache/ngx_pagespeed_cache;
# 禁用CoreFilters
pagespeed RewriteLevel PassThrough;
# 启用压缩空白过滤器
pagespeed EnableFilters collapse_whitespace;
# 启用JavaScript库卸载
pagespeed EnableFilters canonicalize_javascript_libraries; #谷歌被墙,并不确定这个设置有没有副作用 
# 把多个CSS文件合并成一个CSS文件
pagespeed EnableFilters combine_css;
# 把多个JavaScript文件合并成一个JavaScript文件
pagespeed EnableFilters combine_javascript;
# 删除带默认属性的标签
pagespeed EnableFilters elide_attributes;
# 改善资源的可缓存性
pagespeed EnableFilters extend_cache;
# 更换被导入文件的@import,精简CSS文件
pagespeed EnableFilters flatten_css_imports;
pagespeed CssFlattenMaxBytes 5120;
# 延时加载客户端看不见的图片
pagespeed EnableFilters lazyload_images;
# 启用JavaScript缩小机制
pagespeed EnableFilters rewrite_javascript;
# 启用图片优化机制
pagespeed EnableFilters rewrite_images;
# 预解析DNS查询
pagespeed EnableFilters insert_dns_prefetch;
# 重写CSS,首先加载渲染页面的CSS规则
pagespeed EnableFilters prioritize_critical_css; 
# Example 禁止pagespeed 处理/wp-admin/目录(可选配置,可参考使用)
pagespeed Disallow "*/wp-admin/*";

然后,新增缓存文件夹:

mkdir -p /tmp/cache/ngx_pagespeed_cache

最后,重启Nginx即可生效(实测发现这个模块的修改必须重启nginx,reload是无效的)。

4. 工作效果

重启Nginx后,可以刷新一下这台服务器上的网页,可以发现源码大部分都已经被替换或合并为一个以’+’/‘pagespeed’等字符编码结尾的脚本文件(如图示)。绝大部分js、css的url都变了,被合并成了一个url。

体积小一些的图片,如logo,也被转成了浏览器编码的形式,算是减少服务器请求的一种优化:

查看网页的源码,发现html也被压缩了:

以【http://tool.chinaz.com/sitespeed/】测试加速前后的区别,测试结果如下:

优化前表现:

优化后响应速度明显提升了很多:

可见加速效果还是很明显的。另外,如果是 Apache 服务器,类似的可以集成 mod_pagespeed。具体流程基本相同,在这里不再详述。

5. 常见安装问题及处理方式

5.1. PSOL安装过程中,-std=c++11命令的识别错误

在【重新整理configure arguments】步骤中,有时已按照要求正确下载和解压PSOL至ngx_pagespeed目录下,在./configure的时候还是会报:

mod_pagespeed_dir=/usr/local/src/ngx_pagespeed-latest-beta/psol/include
build_from_source=false
checking for psol ... not found
./configure: error: module ngx_pagespeed requires the pagespeed optimization library.
Look in /usr/local/src/nginx-1.10.3/objs/autoconf.err for more details.

错误。

这时我们根据报错后的提示,打开nginx安装源码目录下的/usr/local/src/nginx-1.10.3/objs/autoconf.err文件,查看详细错误信息,发现如下异常:

这是因为系统的GCC版本较低(Ubuntu12.04 LTS默认GCC G++为4.6.*版本,不支持最新的c++11标准),不能支持最新版本ngx_pagespeed的c++11标准,这时候,这种情况升级一下GCC 就可以了。具体方法如下:

5.1.1. 添加PPA源

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update

5.1.2. 安装新版gcc/g++

可参考的安装:

sudo apt-get install gcc-4.9 g++-4.9

sudo apt-get install gcc-5 g++-5

 sudo apt-get install gcc-6 g++-6

选较新的版本安装好之后,再次更新系统:

sudo apt-get upgrade

5.1.3. 将本地安装的GCC/G++ 切换到最新版本

查看本地安装版本:

ls -lh /usr/bin/g++ *

接下来切换GCC/G++到上一步安装的版本:

sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-<新版本> <优先级order值;如:20,50>
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-<新版本> <优先级order值;如:20,50>

sudo update-alternatives --config gcc #选择新版本的序号
sudo update-alternatives --config g++ #选择新版本的序号

如:

sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 20

sudo update-alternatives --config gcc
sudo update-alternatives --config g++

配置完成后,以

gcc --version
g++ --version

命令查看GCC/G++版本,发现版本已升级到最近安装的新版本。

此时再重新执行configure arguments步骤。

5.2. /usr/bin/ld: cannot find -lxxx错误

还是【/usr/bin/ld】步骤,PSOL checking环节。
具体报错如下:

checking for psol

/usr/bin/ld: cannot find -luuid
collect2: error: ld returned 1 exit status

发生这样情况的原因有以下三种情形:

  1. 系统没有安装相对应的lib;
  2. 相对应的lib版本不对;
  3. lib(.so档)的symbolic link 不正确,没有连结到正确的函式库文件(.so)。

具体解决方式如下:

  1. 先判断在/usr/lib 下的相对应的函式库文件(.so) 的symbolic link 是否正确。若不正确改成正确的连结目标即可解决问题。
  2. 若不是symbolic link 的问题引起,而是系统缺少相对应的lib安装lib即可解决。
  3. ldconfig 重建ld.so.cache文件,ld的库文件检索目录存放文件。尤其刚刚编译安装的软件,必须运行ldconfig,才能将新安装的库文件导入ld.so.cache。

/usr/bin/ld: cannot find -luuid错误为例,解决详细过程如下:

5.2.1. 首先查看uuid是否有安装

在终端下运行命令: locate libuuid,出现如下反馈:

这说明uuid的库已经是安装的。反之,如果没有安装uuid库,则通过apt-get install uuid安装即可解决问题。

5.2.2. 创建相应的链接文件

从上述反馈的代码中可以看到系统安装了多个版本:

/lib/i386-linux-gnu/libuuid.so.1
/lib/i386-linux-gnu/libuuid.so.1.3.0
/lib/x86_64-linux-gnu/libuuid.so.1
/lib/x86_64-linux-gnu/libuuid.so.1.3.0

选择其中一个版本为其创建链接文件即可:

sudo ln -sf /lib/x86_64-linux-gnu/libuuid.so.1.3.0 /usr/lib/libuuid.so

命令成功后,会在 /usr/lib/ 目录下生成 libuuid.so。
再次编译代码,即可成功。

5.3. nginx: [emerg] getpwnam(“www”) failed 错误

5.3.1. 解决方案1:修改配置文件,去除”user nobody”

打开Nginx配置文件nginx.conf,将user nobody去掉既可。

5.3.2. 解决方案2:创建”www”用户

在服务器系统中添加”www”用户组及用户”www”,命令如下:

/usr/sbin/groupadd -f www
/usr/sbin/useradd -g www www

5.4. 问题:fastcgi_cache和pagespeed加速是否存在冲突?

fastcgi_cache已经是缓存到本地的文件,那么pagespeed肯定是后处理的。通俗来说,就是当用户访问WEB时,Nginx 应该是先调用 fastcgi缓存,然后再进行pagespeed优化处理,最后返回数据给用户。