要保证web站点的性能,需要确保你发送的经过gzip压缩过的内容,如何开始对网站内容进行gzip,并且还与你主机所允许的规定相一致呢?下面就是将要介绍的几种选择。文章的假设服务器运行的PHP和Apache。
选择1: 对Apache 2 以前的版本进行mod_gzip操作
如果你使用Apache 1.2 和1.3,那么mod_gzip 模块是可用的。为了检查Apache的版本,你可以检查Firebug'中Net面板,查找对于任何请求,服务器响应的头部。如果你不能看到它,那么检查提供商的文档或者创建一个简单的PHP脚本来回显这些信息到浏览器中去,如:
<?php echo apache_get_version(); ?>
在服务器头部信息中,你或许能看到mod_gzip版本,如果它被安装了的话。它或许是这个样子的:
Server: Apache/1.3.37 (Unix) mod_gzip/1.3.26.1a.....
好了,在我们将信息发送给浏览器之前,我们已经建立了我想要压缩的所有内容,PHP脚本输出,静态HTML页面,javascripts和样式表。那么现在就可以通过mod_gzip来实现,在你站点的根目录下创建一个.htaccess文件,包括:
mod_gzip_on Yes
mod_gzip_item_include mime ^application/x-javascript$
mod_gzip_item_include mime ^application/json$
mod_gzip_item_include mime ^text/.*$
mod_gzip_item_include file .html$
mod_gzip_item_include file .php$
mod_gzip_item_include file .js$
mod_gzip_item_include file .css$
mod_gzip_item_include file .txt$
mod_gzip_item_include file .xml$
mod_gzip_item_include file .json$
Header append Vary Accept-Encoding
第一行是的mod_gzip命令可用。下面的三行设置压缩是基于MIME类型上的。下面的部分是一样,只是以文件扩展为基础。最后的一行是设置Vary头部的,包括Accept-Encoding值。
如果你想发送Vary: *头部,使用:
Header set Vary *
需要注意的是,一些主机提供商不允许你使用Header 定向。如果存在这种情况,希望你可以用下面这句话来代替最后一行“
mod_gzip_send_vary On
这也将要设置Vary头部为Accept-Encoding.
需要注意的是,这里或许有很小的文件存在,如果你的文件太小(举个例子,小于1KB),那么它们就需要gzip,即时你已经将所有的东西都设置正确了。如果你gzip的话,你的主机不得不为每个小的文件进行不必要的gzip开销。
选择2:Apache 2.0 2.0版本使用mod_deflate
如果你的主机运行的是Apache 2版本,那么你可以使用mod_deflate。尽管的它的名字没有带有gzip的信息,但是它也是使用gzip进行压缩。为了设置mod_deflate,需要在.htaccess文件中添加下面的信息:
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript application/json
Header append Vary Accept-Encoding
选择3:使用php.ini.ini文件
理想情况下,我们希望Apache能gzip内容,但是不幸的是,一些主机提供商或许不允许你这么做。如果你的主机提供商这这样的话,你就可以使用php.ini文件。若干你将一个php.ini文件放到一个目录下,那么它就会重写这个目录和它子目录下的PHP设置。
如果你不能使用Apache的mod_gzip 或mod_deflate模块,你仍旧能够使用PHP来压缩你的内容,达到预期的解决方案,你需要设置你的web服务器,因此所有的静态HTML、javascript 、CSS都能经过PHP处理。这意味着服务器有更多的开销,但是根据你的主机情况了,不过这是唯一的选择了。
在下面的.htaccess文件增加下面的命令:
AddHandler application/x-httpd-php .css
AddHandler application/x-httpd-php .html
AddHandler application/x-httpd-php .js
这会确保PHP会处理这些文件。如果不能起作用,我们可以试着重命名,加一个.php扩展名(如example.js.php)来达到同样的效果。
现在在相同目录下创建一个php.ini文件,包含下面的内容:
[PHP]
zlib.output_compression = On
zlib.output_compression_level = 6
auto_prepend_file = "pre.php"
short_open_tag = 0
上面这些命令可以进行压缩,并且压缩的程度能达到6的级别,压缩水平从0到9,9是最好的压缩水平。最后一行设置了一个文件叫pre.php,这个文件将会在每个脚本运行前执行,就好象你在没有脚本的最上面写上了<?php include "pre.php"; ?>。你需要这个文件来设置Content-Type的头部,因为当你发送一个含有text/html 内容的头部的CSS文件时,一些浏览器或许不识别。
这里的short_open_tag 设置使得PHP短标签(<? ... ?>, as compared to <?php ... ?>)失效。这一点是非常重要的,因为不这样的话,PHP会尝试将你HTML代码中的<?xml标签当作PHP代码。
最终,创建的pre.php文件将会包含一下的内容:
<?php
$path = pathinfo($_SERVER['SCRIPT_NAME']);
if ($path['extension'] == 'css') {
header('Content-type: text/css');
}
if ($path['extension'] == 'js') {
header('Content-type: application/x-javascript');
}
?>
在每个以.php, .html, .js 或者.css为扩展名的文件运行前都要执行这段脚本。对于HTML和PHP文件,缺省设置Content-Type text/html是没有问题的,但是对于javascript和CSS文件,我们将要使用PHP的头部函数功能改变它。
选择3(变种2):.htaccess文件中进行PHP设置
如果你的主机允许你在.htaccess文件中进行设置,那么你将不需要使用php.ini文件来进行压缩设置。取而代之,在.htaccess文件中使用php_value (和 php_flag)进行设置。
看看上面修改过过的例子,我们有同样的pre.php文件,没有php.ini文件,并且有一个修改过的.htaccess文件包含下面的命令:
AddHandler application/x-httpd-php .css
AddHandler application/x-httpd-php .html
AddHandler application/x-httpd-php .js
php_flag zlib.output_compression on
php_value zlib.output_compression_level 6
php_value auto_prepend_file "pre.php"
php_flag short_open_tag off
选择4:写入脚本表达式
如果你的主机提供商不允许你在.htaccess文件中使用php_value,或者也不让你使用php.ini文件,那么最后的求助的办法只能是修改脚本,手工引入进行压缩设置的pre.php文件。这是最后的选择,但是有些时候你没有其它的选择了。
如果这是你的唯一选择,你将不能使用.htaccess文件包含选择3的那些命令,或者也不能将每个.js 和 .css文件扩展成.php文件。那么在每个文件的头部,添加<?php include "pre.php"; ?>并且创建一个名为pre.php的文件,包含下面的内容:
<?php
ob_start("ob_gzhandler");
$path = pathinfo($_SERVER['SCRIPT_NAME']);
if ($path['extension'] == 'css') { header('Content-type: text/css');
}
if ($path['extension'] == 'js') {
header('Content-type: application/x-javascript');
}
?>
正如我给你展示的那样,这个是最后一个不得已的办法,你应该首先选择1或者2,如果它们不能实施,考虑选择3或者4,或者两者的同时实施,这都根据你的主机所允许的情况了。
一旦你已经建立主机所允许的自由度,你就可以使用相关技术来压缩你的静态文件,实现与Apache相关的设置。举个例子,早先的时候我给你展示了如何设置过期的头部。现在,猜猜我将给你介绍什么?一些主机不允许这么做。如果你现在你的情况正好是这样的,那么你可以使用PHP的头部函数功能来设置过期头部。
为了完成这个任务,你或许要将你的pre.php文件改成这个样子:
<?php
header("Expires: Mon, 25 Dec 2017 05:00:00 GMT");
?>