Apache & PHP 的gzip壓縮輸出的實現方法

1、gzip介紹

gzip是GNU zip的縮寫,它是一個GNU自由軟件的文件壓縮程序,也常常用來表示gzip這種文件格式。軟件的做者是Jean-loup Gailly和Mark Adler。1992年10月31日第一次公開發布,版本號是0.1,目前的穩定版本是1.2.4。javascript

Gzip主要用於Unix系統的文件壓縮。咱們在linux中常常會用到後綴爲.gz的文件,它們就是GZIP格式的。現今已經成爲Internet 上使用很是廣泛的一種數據壓縮格式,或者說一種文件格式。 當應用Gzip壓縮到一個純文本文件時,效果是很是明顯的,通過GZIP壓縮後頁面大小能夠變爲原來的40%甚至更小,這取決於文件中的內容。php

HTTP協議上的GZIP編碼是一種用來改進WEB應用程序性能的技術。web開發中能夠經過gzip壓縮頁面來下降網站的流量,而gzip並不會對cpu形成大量的佔用,略微上升,也是幾個百分點而已,可是對於頁面卻能壓縮30%以上,很是划算。css

利用Apache中的Gzip模塊,咱們可使用Gzip壓縮算法來對Apache服務器發佈的網頁內容進行壓縮後再傳輸到客戶端瀏覽器。這樣通過壓縮後實際上下降了網絡傳輸的字節數(節約傳輸的網絡I/o),最明顯的好處就是能夠加快網頁加載的速度。html

網頁加載速度加快的好處不言而喻,除了節省流量,改善用戶的瀏覽體驗外,另外一個潛在的好處是Gzip與搜索引擎的抓取工具備着更好的關係。例如 Google就能夠經過直接讀取gzip文件來比普通手工抓取更快地檢索網頁。在Google網站管理員工具(Google Webmaster Tools)中你能夠看到,sitemap.xml.gz 是直接做爲Sitemap被提交的。java

而這些好處並不只僅限於靜態內容,php動態頁面和其餘動態生成的內容都可以經過使用Apache壓縮模塊壓縮,加上其餘的性能調整機制和相應的服務器端 緩存規則,這能夠大大提升網站的性能。所以,對於部署在Linux服務器上的PHP程序,在服務器支持的狀況下,咱們建議你開啓使用Gzip Web壓縮。linux

2、Web服務器處理HTTP壓縮的過程以下:

    1. Web服務器接收到瀏覽器的HTTP請求後,檢查瀏覽器是否支持HTTP壓縮(Accept-Encoding 信息);
    1. 若是瀏覽器支持HTTP壓縮,Web服務器檢查請求文件的後綴名;
    1. 若是請求文件是HTML、CSS等靜態文件,Web服務器到壓縮緩衝目錄中檢查是否已經存在請求文件的最新壓縮文件;
    1. 若是請求文件的壓縮文件不存在,Web服務器向瀏覽器返回未壓縮的請求文件,並在壓縮緩衝目錄中存放請求文件的壓縮文件;
    1. 若是請求文件的最新壓縮文件已經存在,則直接返回請求文件的壓縮文件;
    1. 若是請求文件是動態文件,Web服務器動態壓縮內容並返回瀏覽器,壓縮內容不存放到壓縮緩存目錄中。

3、啓用apache的gzip功能

Apache上利用Gzip壓縮算法進行壓縮的模塊有兩種:mod_gzip 和mod_deflate。要使用Gzip Web壓縮,請首先肯定你的服務器開啓了對這兩個組件之一的支持。web

雖然使用Gzip同時也須要客戶端瀏覽器的支持,不過不用擔憂,目前大部分瀏覽器都已經支持Gzip了,如IE、Mozilla Firefox、Opera、Chrome等。算法

經過查看HTTP頭,咱們能夠快速判斷使用的客戶端瀏覽器是否支持接受gzip壓縮。若發送的HTTP頭中出現如下信息,則代表你的瀏覽器支持接受相應的gzip壓縮:apache

代碼以下:瀏覽器

Accept-Encoding: gzip 支持mod_gzip  
Accept-Encoding: deflate 支持mod_deflate   
Accept-Encoding: gzip,deflate 同時支持mod_gzip 和mod_deflate

如firebug查看:

輸入圖片說明

若是服務器開啓了對Gzip組件的支持,那麼咱們就能夠在http.conf或.htaccess裏面進行定製。

mod_gzip 的配置: 下面是一個.htaccess配置的簡單實例:

# mod_gzip:  
<ifModule mod_gzip.c>  
    mod_gzip_on Yes  
    mod_gzip_dechunk Yes  
    mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$  
    mod_gzip_item_include handler ^cgi-script$  
    mod_gzip_item_include mime ^text/.*  
    mod_gzip_item_include mime ^application/x-javascript.*  
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*  
<ifModule>

mod_deflate的配置實例:

打開apache 配置文件httpd.conf

去除開頭的#號

#LoadModule deflate_module modules/mod_deflate.so
#LoadModule headers_module modules/mod_headers.so
#LoadModule filter_module modules/mod_filter.so

增長代碼以下:

<IfModule deflate_module>  
    #必須的,就像一個開關同樣,告訴apache對傳輸到瀏覽器的內容進行壓縮   
    SetOutputFilter DEFLATE   
  
    #壓縮級別,1-9,9爲最高   
    DeflateCompressionLevel 6      
  
    #不進行壓縮的文件   
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary #設置不對後綴gif,jpg,jpeg,png的圖片文件進行壓縮   
    SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary #同上,就是設置不對exe,tgz,gz。。。的文件進行壓縮   
    SetEnvIfNoCase Request_URI \.(?:pdf|doc|mov|avi|mp3|mp4|rm)$ no-gzip dont-vary     
	#壓縮的文件
	AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-httpd-php application/x-javascript
	AddOutputFilterByType  DEFLATE js css
	AddOutputFilterByType INCLUDES .shtml .htm .xml .php .html
    #針對代理服務器的設置   
    <IfModule headers_moudle>  
    Header append vary User-Agent   
    </IfModule>  
</IfModule>

裏面的文件MIME類型能夠根據本身狀況添加,至於PDF、圖片、音樂文檔之類的這些自己都已經高度壓縮格式,重複壓縮的做用不大,反而可能會由於增長CPU的處理時間及瀏覽器的渲染問題而下降性能。因此就不必再經過Gzip壓縮。經過以上設置後再查看返回的HTTP頭,出現如下信息則代表返回的數據已通過壓縮。即網站程序所配置的Gzip壓縮已生效。

Content-Encoding: gzip

輸入圖片說明

注意:

  1. 無論使用mod_gzip 仍是mod_deflate,此處返回的信息都同樣。由於它們都是實現的gzip壓縮方式。
  2. CompressionLevel 9是指壓縮程度的等級(設置壓縮比率),取值範圍在從1到9,9是最高等級。據瞭解,這樣作最高能夠減小8成大小的傳輸量(看檔案內容而定),最少也可以 節省一半。 CompressionLevel 預設能夠採用 6 這個數值,以維持耗用處理器效能與網頁壓縮質量的平衡. 不建議設置過高,若是設置很高,雖然有很高的壓縮率,可是佔用更多的CPU資源.
  3. 對已是壓縮過的圖片格式如jpg,音樂檔案如mp三、壓縮文件如zip之類的,就不必再壓縮了。

4、mod_gzip 和mod_deflate的主要區別是什麼?使用哪一個更好呢?

  • 第一個區別是安裝它們的Apache Web服務器版本的差別:

Apache 1.x系列沒有內建網頁壓縮技術,因此纔去用額外的第三方mod_gzip 模塊來執行壓縮。而Apache 2.x官方在開發的時候,就把網頁壓縮考慮進去,內建了mod_deflate 這個模塊,用以取代mod_gzip。雖然二者都是使用的Gzip壓縮算法,它們的運做原理是相似的。

  • 第二個區別是壓縮質量:

mod_deflate 壓縮速度略快而mod_gzip 的壓縮比略高。通常默認狀況下,mod_gzip 會比mod_deflate 多出4%~6%的壓縮量。 那麼,爲何使用mod_deflate?

  • 第三個區別是對服務器資源的佔用:

通常來講mod_gzip 對服務器CPU的佔用要高一些。mod_deflate 是專門爲確保服務器的性能而使用的一個壓縮模塊,mod_deflate 須要較少的資源來壓縮文件。這意味着在高流量的服務器,使用mod_deflate 可能會比mod_gzip 加載速度更快。

不太明白?簡而言之,若是你的網站,天天不到1000獨立訪客,想要加快網頁的加載速度,就使用mod_gzip。雖然會額外耗費一些服務器資源, 但也是值得的。若是你的網站天天超過1000獨立訪客,而且使用的是共享的虛擬主機,所分配系統資源有限的話,使用mod_deflate 將會是更好的選擇。

另外,從Apache 2.0.45開始,mod_deflate 可以使用DeflateCompressionLevel 指令來設置壓縮級別。該指令的值可爲1(壓縮速度最快,最低的壓縮質量)至9(最慢的壓縮速度,壓縮率最高)之間的整數,其默認值爲6(壓縮速度和壓縮質 量較爲平衡的值)。這個簡單的變化更是使得mod_deflate 能夠輕鬆媲美mod_gzip 的壓縮。

  • P.S. 對於沒有啓用以上兩種Gzip模塊的虛擬空間,還能夠退而求其次使用php的zlib函數庫(一樣須要查看服務器是否支持)來壓縮文件,只是這種方法使用起來比較麻煩,並且通常會比較耗費服務器資源,請根據狀況慎重使用。

5、zlib.output_compression和ob_gzhandler編碼方式壓縮

服務器不支持mod_gzip、mod_deflate模塊,若想經過GZIP壓縮網頁內容,能夠考慮兩種方式,開啓zlib.output_compression或者經過ob_gzhandler編碼的方式。

  • 1)zlib.output_compression是在對網頁內容壓縮的同時發送數據至客戶端。

  • 2)ob_gzhandler是等待網頁內容壓縮完畢後才進行發送,相比之下前者效率更高,但須要注意的是,二者不能同時使用,只能選其一,不然將出現錯誤。

二者的實現方式作簡單描述:

1. zlib.output_compression實現方式

在默認狀況下,zlib.output_compression是關閉:

代碼以下:

; Transparent output compression using the zlib library  
    ; Valid values for this option are 'off', 'on', or a specific buffer size  
    ; to be used for compression (default is 4KB)  
    ; Note: Resulting chunk size may vary due to nature of compression. PHP  
    ;   outputs chunks that are few hundreds bytes each as a result of  
    ;   compression. If you prefer a larger chunk size for better  
    ;   performance, enable output_buffering in addition.  
    ; Note: You need to use zlib.output_handler instead of the standard  
    ;   output_handler, or otherwise the output will be corrupted.  
    ; http://php.net/zlib.output-compression  
    zlib.output_compression = Off  

    ; http://php.net/zlib.output-compression-level  
    ;zlib.output_compression_level = -1

如需開啓需編輯php.ini文件,加入如下內容:

代碼以下:

zlib.output_compression = On  
    zlib.output_compression_level = 6

能夠經過phpinfo()函數檢測結果。 當zlib.output_compression的Local Value和MasterValue的值同爲On時,表示已經生效,這時候訪問的PHP頁面(包括僞靜態頁面)已經GZIP壓縮了,經過Firebug或 者在線網頁GZIP壓縮檢測工具可檢測到壓縮的效果。

2. ob_gzhandler的實現方式

若是須要使用ob_gzhandler,則需關閉zlib.output_compression,把php.ini文件內容更改成:

zlib.output_compression = Off  
zlib.output_compression_level = -1

經過在PHP文件中插入相關代碼實現GZIP壓縮P壓縮:

代碼以下:

if (extension_loaded('zlib')) {  
        if (  !headers_sent() AND isset($_SERVER['HTTP_ACCEPT_ENCODING']) &&  
              strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)  
        //頁面沒有輸出且瀏覽器能夠接受GZIP的頁面  
        {  
            ob_start('ob_gzhandler');  
        }  
    }  
    //待壓縮的內容  
    echo $context;  
    ob_end_flush();

不論是zlib.output_compression仍是ob_gzhandler,都僅能對PHP文件進行GZIP壓縮,對於HTML、CSS、JS等靜態文件只能經過調用PHP的方式實現。

最後想說的是,如今主流的瀏覽器默認使用的是HTTP1.1協議,基本都支持GZIP壓縮,對於IE而言,假如你沒有選中其菜單欄工具-》Internet 選項-》高級-》HTTP 1.1 設置-》使用 HTTP1.1,那麼,你將感覺不到網頁壓縮後的速度提高所帶來的快感!

相關文章
相關標籤/搜索