wordpress优化之启用Gzip压缩

GZIP压缩是一个经常被用到的WEB性能优化的技巧,它主要是对页面代码,CSS,Javascript,PHP等文件进行压缩,而且在压缩的前后,文件的大小会有明显的改变,从而达到网站访问加速的目的。下面是我的网站开启后的效果:

20160704105447

接下来我们就介绍一下什么是GZIP压缩,以及GZIP压缩是个什么概念。

一、GZIP压缩的概念

GZIP网页压缩,是一种WEB服务器与浏览器之间共同遵守的协议,也就是说WEB服务器和浏览器都必须支持该技术才能实现GZIP压缩,而当下主流的浏览器都是支持GZIP压缩,包括IE6、IE7、IE8、IE9、FireFox、谷歌浏览器、Opera等,而常见的WEB服务器通常有Apache和IIS两种。

GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。目前,GZIP已经成为Internet上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载. 一般服务器中都安装有这个功能模块的。

二、WEB服务器与浏览器之间的交互

下面介绍一下GZIP压缩时,WEB服务器与浏览器之间的协商过程如下:

1、首先浏览器请求某个URL地址,并在请求的开始部分头(head) 设置属性accept-encoding值为gzip、deflate,表明浏览器支持gzip和deflate这两种压缩方式(事实上deflate也是使用GZIP压缩协议,在之后的内容之我们会介绍二者之间的区别);

2、WEB服务器接收到请求后判断浏览器是否支持GZIP压缩,如果支持就传送压缩后的响应内容,否则传送不经过压缩的内容;

3、浏览器获取响应内容后,判断内容是否被压缩,如果是压缩文件则解压缩,然后显示响应页面的内容。

HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指 WWW服务器中安装的一个功能,当有人来访问这个服务器的网站时,服务器的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来。一般对纯文 内容可压缩到原大小的40%,这样以来文件的体积就减小了很多,传输速度也就快了。效果就是你点击网址后会很快的显示出来。当然这也会增加服务器的负载,一般的服务器中都会安装有这个功能模块。

GZIP压缩的比率往往在3倍到10倍,也就是本来90k大小的页面,采用压缩后实际传输的内容大小只有28至30K大小,这可以大大节省服务器的网络带宽,同时如果应用程序的响应足够快时,网站的速度瓶颈就转到了网络的传输速度上,因此内容压缩后就可以大大的提升页面的浏览速度。

在实际应用中,我们并不需要对网站所有文件都进行压缩,只需要对静态文件进行压缩就可以了,比如Javascript、CSS及和HTML文件。对其他文件进行压缩并不会给WEB性能带来太多的改观,并且对网站开启GZIP功能是需要牺牲部分服务器性能的。而且对于FLASH文件来说开启GZIP压缩之后还会影响其效果。

三、给WP网站开启Gzip

1、打开wordpress的Gzip功能

目前4.5的wordpress版本都支持Gzip压缩,不过默认是关闭的,首先在functions.php下加入以下代码:

//网站GZIP压缩
function gzippy() {
 ob_start('ob_gzhandler');
}
if(!stristr($_SERVER['REQUEST_URI'], 'tinymce') && !ini_get('zlib.output_compression')) {
 add_action('init', 'gzippy');
}

到这里你已经开启了Gzip功能,不过为了保险起见,还是检测去一下吧:http://tool.chinaz.com/Gzips/

通过这一步骤,网站的性能已经提高了一个档次,不过对于CSS和JS,默认是不进行压缩的,以上仅压缩页面。下一步我们就让它也对JS和CSS进行压缩。

2、让JS和CSS支持Gzip压缩
1)在你网站的根目录下新建立一文件夹wp-cache,用来存放Gzip压缩文件,请确保该文件夹权限为可读写。 2)在你网站的根目录下新建一名字为gzip.php的文件,代码如下:
<?php

define('ABSPATH', dirname(__FILE__).'/');

$cache = false;//Gzip压缩开关
$cachedir = 'wp-cache/';//存放gz文件的目录,确保可写

$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=ABSPATH.$key;

$symbol='^';

$rel_path=str_replace(ABSPATH,'',dirname($filename));
$namespace=str_replace('/',$symbol,$rel_path);

$cache_filename=ABSPATH.$cachedir.$namespace.$symbol.basename($filename).'.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: text/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");
	}
}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");
	}
}

?>
3)在你网站的根目录下的.htaccess中添加以下代码,如果.htaccess不存在则新建一个。
RewriteCond %{HTTP:User-Agent} !MSIE\ [5-6]
 RewriteRule (.*.css$|.*.js$) gzip.php?$1 [L]

IE6对Gzip的支持不是很好,如果对CSS、JS进行Gzip压缩,会使部分JS失效或者CSS无法加载,所以就直接跳过IE5-6。

时间: 2016年07月04日上午10:51  |  
作者:
4 COMMENTS
  1. 2016/07/09
    紫杉倒影

    长见识了!虽然已经启用了,但是现在才有进一步的了解。

  2. 2017/04/04
    甲子百科

    为什么不在Apache上设置呢?
    代码还是应该处理跟业务逻辑相关的

  3. 2017/06/06
    代写

    支持楼主,赞赞。

  4. 2018/01/28

    感谢分享 受教了

LEAVE A REPLY
loading
正在赶回来……