亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

gzip壓縮簡介

什么是gzip壓縮,gzip壓縮是基于deflate中的算法進行壓縮的,gzip會產(chǎn)生自己的數(shù)據(jù)格式,gzip壓縮對于所需要壓縮的文件,首先使用LZ77算法進行壓縮,再對得到的結(jié)果進行huffman編碼,根據(jù)實際情況判斷是要用動態(tài)huffman編碼還是靜態(tài)huffman編碼,最后生成相應的gz壓縮文件。

gzip和deflate的區(qū)別

大家可能注意到了,在我們的HTTP請求頭中,會存在accept-encoding字段,其實就是在告訴服務器,客戶端所能接受的文件的壓縮格式,其中包括gzip、deflate和br等。

那么常見的gzip和deflate有什么區(qū)別呢?

1、GZIP,好像是一個不透明的或原子的功能。事實上,HTTP定義了一種機制,一個Web客戶機和Web服務器同意一壓縮方案可以用來發(fā)送內(nèi)容,這由使用Accept-Encoding和Content-Encoding標頭完成。有兩種常用的HTTP壓縮:DEFLATE和GZIP。

2、DEFLATE是一個無專利的壓縮算法,它可以實現(xiàn)無損數(shù)據(jù)壓縮,有眾多開源的實現(xiàn)算法。該標準的實施庫大多數(shù)人用的是zlib的。zlib庫提供用于壓縮和解壓縮使用DEFLATE/INFLATE的數(shù)據(jù)。zlib庫還提供了一種數(shù)據(jù)格式,混淆的命名ZLIB,它包裝DEFLATE壓縮數(shù)據(jù),具有報頭和校驗和。

總而言之,GZIP是使用DEFLATE進行壓縮數(shù)據(jù)的另一個壓縮庫。事實上,GZIP的大多數(shù)實現(xiàn)實際使用zlib庫的內(nèi)部進行DEFLATE/ INFLATE壓縮操作。GZIP產(chǎn)生其自己的數(shù)據(jù)格式,混淆的命名GZIP,它包裝DEFLATE壓縮數(shù)據(jù),具有報頭和校驗和。而由于最初的規(guī)定不統(tǒng)一問題,大多數(shù)情況下已經(jīng)啟用deflate壓縮。

gzip壓縮原理

接下來進入本文的正題之一,gzip壓縮的流程是怎么樣的?

其實gzip壓縮一般都是針對文本文件進行壓縮,至于原因后面會介紹到,首先LZ77算法基于文本文件對文本內(nèi)容,即文件中的字符串進行首次壓縮,接下來,利用哈夫曼編碼,轉(zhuǎn)換為010111..等2進制進行存儲。那么具體的算法是怎樣的呢?

1、LZ77算法

LZ77算法的核心思想,是對字符串的重復利用,在掃描整個文本的過程中,判斷之前的字符串中,有沒有出現(xiàn)過類似的字符串或子字符串,通過這樣的方式來壓縮你的文本長度,舉個簡單的栗子:

文本內(nèi)容如下:

http://www.qq.com

http://www.paipai.com

我們把相同的內(nèi)容括起來

http://www.qq.com

http://www.)paipai(.com)

用信息對替換之后的結(jié)果是

http://www.qq.com

(18,11)paipai(22,4)

其中

(18,11)中,18(起點到下一個起點,包含換行)為相同內(nèi)容塊與當前位置之間的距離,11為相同內(nèi)容的長度。

(22,4)中,22為相同內(nèi)容塊與當前位置之間的距離,4為相同內(nèi)容的長度。

由于信息對的大小,小于被替換內(nèi)容的大小,所以文件得到了壓縮。

算法具體實現(xiàn),首先你要明確幾個名詞概念:

1.前向緩沖區(qū)

每次讀取數(shù)據(jù)的時候,先把一部分數(shù)據(jù)預載入前向緩沖區(qū)。為移入滑動窗口做準備

2.滑動窗口

一旦數(shù)據(jù)通過緩沖區(qū),那么它將移動到滑動窗口中,并變成字典的一部分。

3.短語字典

從字符序列S1...Sn,組成n個短語。比如字符(A,B,D) ,可以組合的短語為{(A),(A,B),(A,B,D),(B),(B,D),(D)},如果這些字符在滑動窗口里面,就可以記為當前的短語字典,因為滑動窗口不斷的向前滑動,所以短語字典也是不斷的變化。

在遍歷整個文本的字符串的過程中,算法通過判斷前向緩沖區(qū)中,是否存在滑動窗口中的最長子字符串,實現(xiàn)字符串的“復用”,具體可以看下圖:

HTTP請求之gzip壓縮知多少

 

目前滑動窗口中存在的字符串,除去單字符的,則有AB、BD、ABD,而前向緩沖區(qū)中,存在AB、ABC、BC,最長的子字符串為AB,則可以將ABC壓縮為(0,2,C),其中0表示在滑動窗口中的偏移量,2表示讀取兩個字符,C表示未匹配的字符。接下來我們看一個完整的壓縮案例你就懂了:(圖片引自: https://www.jb51.net/article/... )

HTTP請求之gzip壓縮知多少

 

那么解壓過程呢?其實解壓過程是非常快速的,如下:

HTTP請求之gzip壓縮知多少

 

可以看出,LZ77算法的耗時,主要在于壓縮階段中,判斷前向緩沖區(qū)和滑動窗口中的最長字符串匹配,也就是說,選擇滑動窗口大小,以及前向緩沖區(qū)大小,對你的LZ77算法的時間復雜度有著關鍵的影響,其次,合適的滑動窗口大小、緩沖區(qū)大小能幫助你對文件進行更好的壓縮,提高壓縮率。

而在整個解壓的過程,只需要通過簡單的字符讀取,根據(jù)偏移量復用子字符串,就完成了解壓過程,整個過程沒有復雜的算法耗時,這也正符合了我們在網(wǎng)絡請求中的適用場景,通過在服務端對文件的一次壓縮,提供給所有的用戶使用,在客戶端對數(shù)據(jù)進行解壓,而解壓基本沒有什么耗時,因此能大大提高我們的頁面資源加載速度。

2、huffman編碼

當你對文件中的文本進行壓縮后,接下來其實就是文本的存儲了,ASCII編碼中,一個字符對應一個字節(jié),通過8位來表示,但是我們真的不能在優(yōu)化了嗎?huffman編碼告訴我們,我們還能再壓縮!huffman的原理,本質(zhì)是通過判斷字符在文本中的出現(xiàn)頻次,規(guī)定每個字符的編碼,而非固定8位編碼,舉個簡單的栗子:

字符串:AAABCB

按照以往的存儲方式 需要6個字節(jié),48bits。

但是我們可以看到,A出現(xiàn)了3次,B出現(xiàn)了2次,C僅僅出現(xiàn)了1次,于是我們換一種存儲方式,

用0來表示A,10來表示B,11來表示C

最后的壓縮結(jié)果是000101110 ,最后我們只用了9個bits來存儲了這個字符串!

這就是huffman的根本原理。

可以看到我們的關鍵在于,為字符生成相應的編碼,所以這個過程需要我們構(gòu)造一個哈弗曼樹,什么是哈夫曼樹呢?哈弗曼樹是通過一系列值,將這些值作為葉子節(jié)點,注意是葉子節(jié)點,構(gòu)造成一個樹,這個樹要求,( 葉子節(jié)點的權(quán)重 葉子節(jié)點的深度 ) 所有葉子節(jié)點總數(shù)n 的值達到最小。具體的構(gòu)造過程如下:(圖片引自 http://www.360doc.com/content... )

HTTP請求之gzip壓縮知多少

 

其中,節(jié)點值表示字符出現(xiàn)的頻次,葉子節(jié)點的層級變相意味著 字符編碼的長度,其實這也很好理解,我們希望出現(xiàn)頻次越多的字符,編碼越短越好,頻次較少的字符,編碼長度較長也無所謂。這也和哈夫曼樹的定義完美契合。

可以看到字符串:

abbbbccccddde

a b c d e

1 4 4 3 1

經(jīng)過我們的huffman編碼后,分別表示如下:

a 為 110

b 為 00

c 為 01

d 為 10

e 為 111

聰明的你可能還留意到了,通過huffman編碼后的二進制字符,是沒有二義性的。

可以看到我們上述的案例,動態(tài)生成了huffman編碼,所以最后傳輸數(shù)據(jù)的時候,還需要把huffman樹的信息一起傳遞過去,當然,這里還存在 靜態(tài)huffman和動態(tài)huffman的區(qū)別 :

靜態(tài)Huffman編碼就是使用gzip自己預先定義好了一套編碼進行壓縮,解壓縮的時候也使用這套編碼,這樣不需要傳遞用來生成樹的信息。

動態(tài)Huffman編碼就是使用統(tǒng)計好的各個符號的出現(xiàn)次數(shù),建立Huffman樹,產(chǎn)生各個符號的Huffman編碼,用這產(chǎn)生的Huffman編碼進行壓縮,這樣需要傳遞生成樹的信息。

Gzip 在為一塊進行Huffman編碼之前,會同時建立靜態(tài)Huffman樹,和動態(tài)Huffman樹,然后根據(jù)要輸出的內(nèi)容和生成的Huffman樹,計算使用靜態(tài)Huffman樹編碼,生成的塊的大小,以及計算使用動態(tài)Huffman樹編碼,生成塊的大小。然后進行比較,使用生成塊較小的方法進行Huffman編碼。

對于靜態(tài)樹來說,不需要傳遞用來生成樹的那部分信息。動態(tài)樹需要傳遞這個信息。而當文件比較小的時候,傳遞生成樹的信息得不償失,反而會使壓縮文件變大。也就是說對于文件比較小的時候,就可能會出現(xiàn)使用靜態(tài)Huffman編碼比使用動態(tài)Huffman編碼,

生成的塊小。

如何開啟gzip

竟然gzip這么棒,趕緊在我們的項目中用起來吧!

express和koa默認都沒有開啟gzip壓縮,所以需要自行引入中間件的形式開啟壓縮,針對text文件進行文本壓縮。

const Koa = require("koa");
const path = require("path")
var compress = require('koa-compress')
const App = new Koa();

const static = require('koa-static')


app.use(compress({
  filter: function (content_type) {
   return /text/g.test(content_type)
  },
  threshold: 1,
  flush: require('zlib').Z_SYNC_FLUSH
}))

app.use(async(ctx, next) => {
  //ctx 代表響應 ctx.compress = trus 代表允許壓縮
  // ctx.compress = true
  // ctx.body = "hello"
  await next()
})


app.use(static(
  path.join( __dirname, 'public'),{
    gzip:true
  }
))
//可以配置一個或多個
// app.use(static(__dirname + '/static')))

app.listen(3000);

需要注意 koa 的中間件使用 和express是不一樣的。

其次,通過filter 函數(shù)來判斷是否要進行gzip壓縮。

除了Nginx或server層做gzip壓縮。

也可以在構(gòu)建的時候壓縮,生成相應的gz文件。

const CompressionWebpackPlugin = require('compression-webpack-plugin');

webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp('\.(js|css)$'),
      threshold: 10240,
      minRatio: 0.8
    })
)

關于gzip的Q & A

Q:gzip是否僅限制于文本文件,對于二進制文件呢?音頻?圖片等資源呢?

A:gzip壓縮不僅適用于文本文件,其實也可以對圖片等二進制文件進行壓縮,但是不推薦這么做,由于gzip的壓縮過程首先基于字符串進行LZ77處理,接下里再通過huffman編碼,然而,大多數(shù)的二進制文件,已經(jīng)有自己的編碼和壓縮方式了,對二進制文件進行在壓縮,可能導致文件更大,同時,會增大客戶端解壓縮的壓力,帶來不必要的CPU損耗。

一些開發(fā)者使用HTTP壓縮那些已經(jīng)本地已經(jīng)壓縮過的文件,而這些已經(jīng)壓縮過的文件再次被GZip壓縮時,是不能提高性能的,表現(xiàn)在如下兩個方面。

首先,HTTP壓縮需要成本。Web服務器獲得需要的內(nèi)容,然后壓縮它,最后將它發(fā)送到客戶端。如果內(nèi)容不能被進一步壓縮,你只是在浪費CPU做無意義的任務。

其次,采用HTTP壓縮已經(jīng)被過壓縮的東西并不能使它更小。事實上,添加標頭,壓縮字典,并校驗響應體實際上使它變得更大,如下圖所示:

HTTP請求之gzip壓縮知多少

 

Q:gzip壓縮過得文件,可以再進行一次gzip壓縮嗎?多次呢?

A:可以進行再壓縮,但是gzip首次壓縮過后的文件,本身已經(jīng)是二進制文件,對文件進行再壓縮只會帶來沒必要的性能損耗,同時可能導致文件增大。

Q:需要對所有文本內(nèi)容都進行GZIP壓縮嗎?

A:答案是否定的,可以看到我們的壓縮過程中,需要執(zhí)行算法,假如傳輸?shù)淖址畠H僅幾十個字符,那么執(zhí)行算法是完全沒有必要的,并且,對過短的字符進行壓縮,可能反而導致傳輸數(shù)據(jù)量增大,例如可能要傳輸動態(tài)構(gòu)造的huffman樹信息等。

Q:在哪個階段對文件進行gzip壓縮比較合適?

A:在本地構(gòu)建部署的時候,通過webpack生成最終的gz壓縮文件部署上服務器,是最高效的,假如通過引入中間件,在請求到來時再對文本文件進行壓縮,只會讓用戶的等待時間更長,所以筆者認為,在webpack打包構(gòu)建的時候做這件事是最合理的。

分享到:
標簽:壓縮 gzip
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定