全站Gzip优化攻略(网站加速篇)

现在很多网站都用Gzip来优化网络传输。而不支持Gzip的浏览器几乎没人用了,当然我们也不准备支持这些不支持Gzip浏览器。

实现全站Gzip化,有那么若干个方法。

方法一:

如果服务器的Apache装有mod_deflate模块,可以在.htaccess写进下面代码轻松实现全站Gzip:

 
#标明压缩级别
DeflateCompressionLevel 7
#针对网页和文本压缩
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php
#针对css和js压缩
AddOutputFilter DEFLATE css js
#规则结束

大多数服务器上Apache的现状,默认没有加载deflate模块。

怎么办呢?跟服务器客服沟通,建议他们加上这个模块呗!(雷吧,这个答案)。

当然,我们还有其他办法实现!

 
#识辨gz档案的支持
AddEncoding gzip .js
ForceType application/x-javascript

AddEncoding gzip .css
ForceType text/css

RewriteEngine On
RewriteBase /

#读到css和js档,就重导至gzip.php
RewriteRule (.*.css$|.*.js$) gzip.php?$1 [L]

#读到.css,判断如果浏览器支持gzip且.css.gz档存在,就进行重导
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*).css $1.css.gz [L,QSA]

#读到.js,判断如果浏览器支持gzip且.js.gz档存在,就进行重导
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*).js $1.js.gz [L,QSA]
#规则结束

方法二:

使用PHP内部Gzip压缩。在.htaccess加上以下语句:

 
#Gzip
php_flag zlib.output_compression on
php_value zlib.output_compression_level 2
#END Gzip

这时候只能压缩PHP生成的网页,其它比如css、js怎么办呢?

这时候,可以利用强大的Rewrite来压缩css和js。

建立一个gzip.php的文件,内容如下:(gzip.php修改优化自网上代码,出处未知)

 
< ?php
//注:本文件需要在其目录下关闭Gzip压缩PHP!
$cur_dir = 'wp-content/';//相对网站根目录,本文件的目录

$cache = true;//Gzip压缩开关
$cachedir = 'wp-content/gzip-cache/';//相对网站根目录,存放gz文件的目录,确保可写
$ht_dir = '';//相对网站根目录,使gzip生效的.htaccess文件存放目录

$ws_dir = dirname(__FILE__);
$ws_dir = str_replace('\\','/',$ws_dir).'/';
$ws_dir = str_replace($cur_dir,'',$ws_dir);//计算出网站根目录的绝对路径

$gzip = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
$deflate = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate');
$encoding = $gzip ? 'gzip' : ($deflate ? 'deflate' : 'none');

if(!isset($_SERVER['QUERY_STRING'])) exit();

$key=array_shift(explode('?', $_SERVER['QUERY_STRING']));
$key=str_replace('../','',$key);

$filename=$ws_dir.$ht_dir.$key;//要压缩的文件的绝对路径

$symbol='^';

$cache_filename=$ws_dir.$cachedir.str_replace('/',$symbol,$key).'.gz';//生成gz文件路径

$type="Content-type: text/html"; //默认的类型信息

$ext = array_pop(explode('.', $filename));//根据后缀判断文件类型信息
	switch ($ext){
		case 'css':
		 $type="Content-type: text/css";
		 break;
		case 'js':
		 $type="Content-type: application/x-javascript";
		 break;
		default:
		 exit();
	}

if($cache){
	if(file_exists($cache_filename)){//假如存在gz文件

		$mtime = filemtime($cache_filename);
		$gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';

		if( (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
      		array_shift(explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE'])) ==  $gmt_mtime)
			){

			// 浏览器cache中的文件修改日期是否一致,将返回304
			header ("HTTP/1.1 304 Not Modified");
			header("Expires: ");
			header("Cache-Control: ");
			header("Pragma: ");
			header($type);
			header("Tips: Cache Not Modified (Gzip)");
			header ('Content-Length: 0');

		}else{

			//读取gz文件输出
			$content = file_get_contents($cache_filename);
			header("Last-Modified:" . $gmt_mtime);
			header("Expires: ");
			header("Cache-Control: ");
			header("Pragma: ");
			header($type);
			header("Tips: Normal Respond (Gzip)");
			header("Content-Encoding: gzip");
			echo $content;
		}

	}else if(file_exists($filename)){//没有对应的gz文件

		$mtime = mktime();
		$gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';

		$content = file_get_contents($filename);//读取文件
		$content = gzencode($content, 9, $gzip ? FORCE_GZIP : FORCE_DEFLATE);//压缩文件内容

		header("Last-Modified:" . $gmt_mtime);
		header("Expires: ");
		header("Cache-Control: ");
		header("Pragma: ");
		header($type);
		header("Tips: Build Gzip File (Gzip)");
		header ("Content-Encoding: " . $encoding);
        header ('Content-Length: ' . strlen($content));
		echo $content;

		if ($fp = fopen($cache_filename, 'w')) {//写入gz文件,供下次使用
                fwrite($fp, $content);
                fclose($fp);
            }

	}else{
		header("HTTP/1.0 404 Not Found");
		echo "";
	}
}else{ //处理不使用Gzip模式下的输出。原理基本同上
	if(file_exists($filename)){
		$mtime = filemtime($filename);
		$gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';

		if( (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
		array_shift(explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE'])) ==  $gmt_mtime)
		){

		header ("HTTP/1.1 304 Not Modified");
		header("Expires: ");
		header("Cache-Control: ");
		header("Pragma: ");
		header($type);
		header("Tips: Cache Not Modified");
		header ('Content-Length: 0');

	}else{

		header("Last-Modified:" . $gmt_mtime);
		header("Expires: ");
		header("Cache-Control: ");
		header("Pragma: ");
		header($type);
		header("Tips: Normal Respond");
		$content = readfile($filename);
		echo $content;

		}
	}else{
		header("HTTP/1.0 404 Not Found");
		echo "< ! 404 Not Found >";
	}
}

exit();
//本脚本退出
?>

记得将第4、7、8行的变量填好哦。比如这个配置,是将gzip.php存放在网站根目录下的wp-content目录,也就是http://www.youdomain.com/wp-content对应的目录。然后在该目录下建立一个“gzip-cache”文件夹,属性设为777。

然后,开始设置Rewrite规则。我们在网站根目录的.htaccess文件添加以下内容:

 
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} ^.*\.(css|js)$
# NOT MS Internet Explorer - Mozilla v4
RewriteCond %{HTTP_USER_AGENT} !^Mozilla/4(.*)MSIE
RewriteRule (.*.css$|.*.js$) /gzip-cache/gzip.php?$1 [L]
#end

第五行是遇到css和js结尾的文件,就触发Rewrite规则之一;第七行是如果浏览器不是IE一族,就触发本Rewrite规则。以上两个Rewrite规则都为真时,就应用倒数第三行的Rewrite规则。

可以看到,我们不给IE一族浏览器传递css和js的Gzip压缩数据,当然你可以去掉这条判断条件。原因是,我发现IE6对css和js的Gzip压缩支持很差,速度巨慢巨卡。我就干脆加个判断条件,管你是IE几,把所有IE浏览器都排除掉。

如此之后,css和js就可以gzip压缩输出了。要记住的是,如果更改了相应的css和js后,记住清空gzip的缓存,好让它生成新的缓存哦。

全站Gzip优化攻略到此结束。(ps: 这是攻略么,这是寂寞。)

2 Replies to “全站Gzip优化攻略(网站加速篇)”

Leave a Reply