IT技术博客大学习 共学习 共进步

使用Gzip压缩网页

标点符 2010-03-01 13:47:12 浏览 4,083 次

    gzipGNU zip的缩写,它是一个GNU自由软件的文件压缩程序,也经常用来表示gzip这种文件格式。

    HTTP/1.1协议允许客户端可以选择要求从服务器下载压缩内容,这个标准本身定义了两种压缩方法:“gzip”(内容用gzip数据流进行封装)以及“deflate”(内容是原始格式、没有数据头的DEFLATE数据流)。许多HTTP客户端库以及绝大多数当今的浏览器都支持这两种格式。在用户浏览器发送请求的HTTP头中, 带有“Accept-Encoding: gzip, deflate”参数则表明支持gzip和deflate两种压缩算法。

    gzip命令的常用选项

    -c,-stdout 将解压缩的内容输出到标准输出,原文件保持不变

    -d,-decompress 解压缩

    -f,-force 强制覆盖旧文件

    -l,-list 列出压缩包内储存的原始文件的信息(如,解压后的名字、压缩率等)

    -n,-no-name 压缩时不保存原始文件的文件名和时间戳,解压缩时不恢复原始文件的文件名和时间戳(此时,解出来的文件,其文件名为压缩包的文件名)

    -N,-name 压缩时保存原始文件的文件名和时间戳,解压缩时恢复原始文件的文件名和时间戳

    -q,-quiet 抑制所有警告信息

    -r,-recursive 递归

    -t,-test 测试压缩文件完整性

    -v,-verbose 冗余模式(即显示每一步的执行内容)

    -1、-2、…、-9 压缩率依次增大,速度依次减慢,默认为-6

    使用Gzip压缩时的一些注意事项:

Gzip不仅可以对HTML、PHP等文件进行压缩,对CSS,JS等文件同样也可以;Gzip压缩会增加服务器的负载;不要使用Gzip对非文本(图片,视频,音频等)文件进行压缩;有选择性的使用Gzip压缩(对文本代码较多的页面进行压缩);并不是最高的压缩率,压缩的文件就最小;

    高压缩率同时意味着高服务器负载;

    建议把压缩率设为5~8;IIS,Apache1.3,Apache2.0+启用Gizp,配置方法是不同的;未开启Gizp压缩模块的虚拟主机(如Godaddy),只要加载了Zlib库,同样可以实现;

    如果你的服务器不支持HTTP压缩,但支持PHP,那么下面的代码就可能对你很有用,下面的代码会自动压缩文件并给浏览器发送缓存设置。

<?php
 
ob_start();
 
/*
 * The mkdir function does not support the recursive
 * parameter in the version of PHP run by Yahoo! Web
 * Hosting. This function simulates it.
 */
 
function mkdir_r( $dir_name, $rights=0777 ) {
   $dirs = explode( "/", $dir_name );
   $dir = "";
   foreach ( $dirs as $part ) {
       $dir .= $part . "/";
       if ( !is_dir( $dir ) && strlen( $dir ) > 0 )
           mkdir( $dir, $rights );
   }
}
 
/*
 * List of known content types based on file extension.
 * Note: These must be built-in somewhere...
 */
 
$known_content_types = array(
    "htm"  => "text/html",
    "html" => "text/html",
    "js"   => "text/javascript",
    "css"  => "text/css",
    "xml"  => "text/xml",
    "gif"  => "image/gif",
    "jpg"  => "image/jpeg",
    "jpeg" => "image/jpeg",
    "png"  => "image/png",
    "txt"  => "text/plain"
);
 
/*
 * Get the path of the target file.
 */
 
if ( !isset( $_GET["uri"] ) ) {
    header( "HTTP/1.1 400 Bad Request" );
    echo( "<html><body><h1>HTTP 400 - Bad Request</h1></body></html>" );
    exit;
}
 
/*
 * Verify the existence of the target file.
 * Return HTTP 404 if needed.
 */
 
if (($src_uri = realpath( $_GET["uri"] )) === false) {
    /* The file does not exist */
    header( "HTTP/1.1 404 Not Found" );
    echo( "<html><body><h1>HTTP 404 - Not Found</h1></body></html>" );
    exit;
}
 
/*
 * Verify the requested file is under the doc root for security reasons.
 */
 
$doc_root = realpath( "." );
 
if (strpos($src_uri, $doc_root) !== 0) {
    header( "HTTP/1.1 403 Forbidden" );
    echo( "<html><body><h1>HTTP 403 - Forbidden</h1></body></html>" );
    exit;
}
 
/*
 * Set the HTTP response headers that will
 * tell the client to cache the resource.
 */
 
$file_last_modified = filemtime( $src_uri );
header( "Last-Modified: " . date( "r", $file_last_modified ) );
 
$max_age = 300 * 24 * 60 * 60; // 300 days
 
$expires = $file_last_modified + $max_age;
header( "Expires: " . date( "r", $expires ) );
 
$etag = dechex( $file_last_modified );
header( "ETag: " . $etag );
 
$cache_control = "must-revalidate, proxy-revalidate, max-age=" . $max_age . ", s-maxage=" . $max_age;
header( "Cache-Control: " . $cache_control );
 
/*
 * Check if the client should use the cached version.
 * Return HTTP 304 if needed.
 */
 
if ( function_exists( "http_match_etag" ) && function_exists( "http_match_modified" ) ) {
    if ( http_match_etag( $etag ) || http_match_modified( $file_last_modified ) ) {
        header( "HTTP/1.1 304 Not Modified" );
        exit;
    }
} else {
    error_log( "The HTTP extensions to PHP does not seem to be installed..." );
}
 
/*
 * Extract the directory, file name and file
 * extension from the "uri" parameter.
 */
 
$uri_dir = "";
$file_name = "";
$content_type = "";
 
$uri_parts = explode( "/", $src_uri );
 
for ( $i=0 ; $i<count( $uri_parts ) - 1 ; $i++ )
    $uri_dir .= $uri_parts[$i] . "/";
 
$file_name = end( $uri_parts );
 
$file_parts = explode( ".", $file_name );
if ( count( $file_parts ) > 1 ) {
    $file_extension = end( $file_parts );
    $content_type = $known_content_types[$file_extension];
}
 
/*
 * Get the target file.
 * If the browser accepts gzip encoding, the target file
 * will be the gzipped version of the requested file.
 */
 
$dst_uri = $src_uri;
 
$compress = true;
 
/*
 * Let's compress only text files...
 */
 
$compress = $compress && ( strpos( $content_type, "text" ) !== false );
 
/*
 * Finally, see if the client sent us the correct Accept-encoding: header value...
 */
 
$compress = $compress && ( strpos( $_SERVER["HTTP_ACCEPT_ENCODING"], "gzip" ) !== false );
 
if ( $compress ) {
    $gz_uri = "tmp/gzip/" . $src_uri . ".gz";
 
    if ( file_exists( $gz_uri ) ) {
        $src_last_modified = filemtime( $src_uri );
        $dst_last_modified = filemtime( $gz_uri );
        // The gzip version of the file exists, but it is older
        // than the source file. We need to recreate it...
        if ( $src_last_modified > $dst_last_modified )
            unlink( $gz_uri );
    }
 
    if ( !file_exists( $gz_uri ) ) {
        if ( !file_exists( "tmp/gzip/" . $uri_dir ) )
            mkdir_r( "tmp/gzip/" . $uri_dir );
        $error = false;
        if ( $fp_out = gzopen( $gz_uri, "wb" ) ) {
            if ( $fp_in = fopen( $src_uri, "rb" ) ) {
                while( !feof( $fp_in ) )
                    gzwrite( $fp_out, fread( $fp_in, 1024*512 ) );
                fclose( $fp_in );
            } else {
                $error = true;
            }
            gzclose( $fp_out );
        } else {
            $error = true;
        }
 
        if ( !$error ) {
            $dst_uri = $gz_uri;
            header( "Content-Encoding: gzip" );
        }
    } else {
        $dst_uri = $gz_uri;
        header( "Content-Encoding: gzip" );
    }
}
 
/*
 * Output the target file and set the appropriate HTTP headers.
 */
 
if ( $content_type )
    header( "Content-Type: " . $content_type );
 
header( "Content-Length: " . filesize( $dst_uri ) );
readfile( $dst_uri );
 
ob_end_flush();
 
?>
   上面的PHP文件下载:http://www.box.net/shared/e5vvdtg1no

    

建议继续学习

  1. 使用.htaccess 开启gzip 缓存文件 网页 提高速度 (阅读 7,483)
  2. windows下压缩包在linux解压乱码的解决办法 (阅读 5,305)
  3. php的echo为什么这么慢 (阅读 5,223)
  4. 使用系统命令实现文件的压缩与加密 (阅读 5,185)
  5. 启用memcached压缩注意事项 (阅读 5,124)
  6. Android设计中的.9.png (阅读 4,904)
  7. MySQL从压缩文件恢复数据 (阅读 4,682)
  8. 前端性能优化之Html压缩 (阅读 4,645)
  9. 项目中对模板和js,css文件进行压缩的处理类 (阅读 4,523)
  10. 开源压缩算法Zopfli介绍 (阅读 4,464)