1. 程式人生 > >web效能優化--用gzip壓縮資原始檔

web效能優化--用gzip壓縮資原始檔

一、gzip壓縮技術

gzip(GNU- ZIP)是一種壓縮技術。經過gzip壓縮後頁面大小可以變為原來的30%甚至更小,這樣,使用者瀏覽頁面的時候速度會快得多。gzip的壓縮頁面需要瀏覽器和伺服器雙方都支援,實際上就是伺服器端壓縮,傳到瀏覽器後瀏覽器解壓並解析。瀏覽器那裡不需要我們擔心,因為目前的大多數瀏覽器都支援解析gzip壓縮過的資原始檔。在實際的應用中我們發現壓縮的比率往往在3到10倍,也就是本來50k大小的頁面,採用壓縮後實際傳輸的內容大小隻有5至15k大小,這可以大大節省伺服器的網路頻寬,同時如果應用程式的響應足夠快時,網站的速度瓶頸就轉到了網路的傳輸速度上,因此內容壓縮後就可以大大的提升頁面的瀏覽速度。
實現gzip壓縮的方式有多種,比如:nginx、tomcat、java等,選用其中一種即可。

二、nginx啟用gzip

Nginx的壓縮輸出有一組gzip壓縮指令來實現。相關指令位於http{….}兩個大括號之間,如下:

  #開啟gzip壓縮
  gzip on;
  #不壓縮臨界值,大於1K的才壓縮,一般不用改
  gzip_min_length 1k;
  #設定系統獲取幾個單位的快取用於儲存gzip的壓縮結果資料流,這裡設定以16k為單位的4倍申請記憶體
  gzip_buffers 4 16k;
  #預設為http 1.1,現在99.99%的瀏覽器基本上都支援gzip解壓了,所有無需設定此項
  #gzip_http_version 1.0;
  #gzip壓縮比,1 最小處理速度最快,9 最大但處理最慢(傳輸快但比較消耗cpu)
gzip_comp_level 2; #要壓縮的檔案型別,注意"text/html"型別無論是否指定總是會被壓縮的 gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript application/x-httpd-php image/jpeg image/gif image/png; #on的話會在Header裡增加"Vary: Accept-Encoding",給代理伺服器用的,有的瀏覽器支援壓縮,有的不支援,所以避免浪費不支援的也壓縮,所以根據客戶端的HTTP頭來判斷,是否需要壓縮
#我這裡的瀏覽器肯定支援gzip壓縮,所以就不開啟此功能了 gzip_vary off; #IE6對Gzip不怎麼友好,不給它Gzip壓縮了 gzip_disable "MSIE [1-6]\.";

三、tomcat啟用gzip

目前大多數主流WEB中介軟體都支援GZIP壓縮、下面以Tomcat 為例進行說明:
找到Tomcat 目錄下的conf下的server.xml,並找到如下資訊:

      <Connector port = "8080" maxHttpHeaderSize = "8192" maxThreads = "150" minSpareThreads = "25"
              maxSpareThreads = "75" enableLookups = "false" redirectPort = "8443" acceptCount = "100"
              connectionTimeout = "20000" disableUploadTimeout = "true"
      將它改成如下的形式(其實在上面程式碼的下面已經有了,將他們開啟而已。):
      <Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25"
             maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100"
             connectionTimeout="20000" disableUploadTimeout="true"
             compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata"
             compressableMimeType="text/html,text/xml" >
      這樣,就能夠對html和xml進行壓縮了,如果要壓縮css 和 js,那麼需要將
           compressableMimeType=”text/html,text/xml”加入css和js:
           <Connector port="8080" ......... compressableMimeType="text/html,text/xml,text/css,text/javascript" >

一般文字型別的靜態檔案可以通過這種方式壓縮後傳輸、提高傳輸效率。

四、java伺服器啟用gzip

java本身可以通過過濾器filter實現gzip壓縮。下面提供一個gzip工具類:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZIPUtils  {
    public static final String GZIP_ENCODE_UTF_8 = "UTF-8"; 
    public static final String GZIP_ENCODE_ISO_8859_1 = "ISO-8859-1";


    public static byte[] compress(String str, String encoding) {
        if (str == null || str.length() == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes(encoding));
            gzip.close();
        } catch ( Exception e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    public static byte[] compress(String str) throws IOException {  
        return compress(str, GZIP_ENCODE_UTF_8);  
    }

    public static byte[] uncompress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        try {
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    public static String uncompressToString(byte[] bytes, String encoding) {  
        if (bytes == null || bytes.length == 0) {  
            return null;  
        }  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);  
        try {
            GZIPInputStream ungzip = new GZIPInputStream(in);  
            byte[] buffer = new byte[256];  
            int n;  
            while ((n = ungzip.read(buffer)) >= 0) {  
                out.write(buffer, 0, n);  
            }  
            return out.toString(encoding);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String uncompressToString(byte[] bytes) {  
        return uncompressToString(bytes, GZIP_ENCODE_UTF_8);  
    } 

    public static void main(String[] args) throws IOException {
        String s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        System.out.println("字串長度:"+s.length());
        System.out.println("壓縮後::"+compress(s).length);
        System.out.println("解壓後:"+uncompress(compress(s)).length);
        System.out.println("解壓字串後::"+uncompressToString(compress(s)).length());
    }
}

五、壓縮效果

壓縮前:
這裡寫圖片描述
壓縮後:
這裡寫圖片描述

這裡寫圖片描述
顯然壓縮後資原始檔變得小了很多,載入速度也快了不少。可見,gzip壓縮是頁面效能優化的一種有效方式。