如何為項(xiàng)目開啟gzip壓縮及實(shí)現(xiàn)原理

項(xiàng)目的線上版本我們一般都會(huì)結(jié)合構(gòu)建工具(webpack)插件和服務(wù)端配置(nginx)來實(shí)現(xiàn) http 傳輸 的 gzip 壓縮盲厌,目的就是把服務(wù)端響應(yīng)的文件的體積盡量減小坚俗,優(yōu)化返回速度。那這件事具體是怎么實(shí)現(xiàn)的呢尸昧?

http 傳輸中 gzip 壓縮的原理

客戶端(瀏覽器)在請求靜態(tài)資源(js揩页、css等)的時(shí)候,在請求頭 Request Header 里帶上 accept-encoding字段來表明接受哪些壓縮方法烹俗, 如accept-encoding: gzip, deflate爆侣;服務(wù)端在接收到請求時(shí)如果發(fā)現(xiàn)有這個(gè)配置,則發(fā)送gzip壓縮版本的文件幢妄,并在響應(yīng)頭 Response Headers 配置一個(gè) content-encoding 字段兔仰,用于說明服務(wù)端數(shù)據(jù)的壓縮方法(可選值是gzip、compress蕉鸳、deflate)乎赴,否則(沒有accept-encoding)就發(fā)送源文件;客戶端再根據(jù)返回響應(yīng)頭里 content-encoding 對應(yīng)的格式去做相應(yīng)的解碼/解壓縮潮尝;沒有content-encoding項(xiàng)則不進(jìn)行解壓縮榕吼。
accept-encodingcontent-encoding字段都非常語義化,就是傳輸?shù)奈募栽鯓拥母袷骄幋a/解碼勉失,所以當(dāng)響應(yīng)頭有content-encoding: gzip出現(xiàn)友题,就能說明我們服務(wù)端的gzip壓縮成功開啟了。如下:

同時(shí)我們還能看到壓縮后的文件 size戴质,記得先在Chrome瀏覽器的 Network 下勾選 ??Use large request rows

誰來壓縮文件度宦?

(1) 服務(wù)端響應(yīng)請求時(shí)壓縮
如果我們在服務(wù)器用Nginx代理部署項(xiàng)目,就直接讓 nginx 來處理壓縮告匠,它有專門為此構(gòu)建的內(nèi)容戈抄,可以更好地利用緩存并減少開銷。我們要做的只是在服務(wù)端的 nginx.conf做好配置后专,其他就不需要我們操心了划鸽。

配置參數(shù)可參考:Nginx的gzip配置文檔

    # 開啟gzip壓縮
    gzip on;
    gzip_buffers 4 16k; # 置用于壓縮響應(yīng)的緩沖區(qū)的數(shù)量和大小
    gzip_comp_level 9;  # 對響應(yīng)壓縮的級別,可選范圍:1到9戚哎,數(shù)字越大壓縮得越好裸诽,但也越占用CPU時(shí)間
    gzip_http_version 1.1; # 默認(rèn) 1.1,請求壓縮響應(yīng)所需的最小HTTP版本
    gzip_min_length  1k;  # 設(shè)置被gzip的響應(yīng)的最小長度型凳,小于該值的文件不會(huì)被壓縮
    # 追加啟用gzip壓縮的MIME類型丈冬,默認(rèn)已有text/html
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
gzip_disable "MSIE [1-6]\.";
    gzip_vary on; # 默認(rèn)off,如果指令gzip甘畅、gzip_static或gunzip是active的埂蕊,啟用插入" Vary: Accept-Encoding "響應(yīng)報(bào)頭字段

具體配置位置展示

(2) 項(xiàng)目打包構(gòu)建生產(chǎn)版本時(shí)壓縮
既然服務(wù)端都可以做壓縮往弓,為什么在 webpack 打包應(yīng)用時(shí)還要多此一舉呢?我們可以看上面 nginx 配置中 gzip_comp_level 這個(gè)配置項(xiàng)蓄氧,數(shù)字越大壓縮效果越好函似,但是會(huì)耗費(fèi)更多的CPU和時(shí)間,我們壓縮文件主要是為了減少傳輸時(shí)間喉童,如果每次請求靜態(tài)資源服務(wù)端都要壓縮很久才會(huì)返回信息撇寞,不僅本末倒置嗎?況且服務(wù)器開銷也會(huì)增大很多堂氯。既然現(xiàn)在的 spa 應(yīng)用文件都是打包生成的重抖,我們在打包的時(shí)候就直接生成高壓縮等級的文件,作為靜態(tài)資源放在服務(wù)器上祖灰,接收到請求后直接把這些壓縮版文件返回回去不就好了?

webpack 的 compression-webpack-plugin 就是專門做這件事情的:

tip:我bulid的時(shí)候報(bào)了Cannot read property 'tapPromise' of undefined的錯(cuò)畔规,其實(shí)就是版本和vue-cli的某些包不兼容局扶,把 compression-webpack-plugin 的版本降低到6.1.1就可以了。

先安裝npm install compression-webpack-plugin -D叁扫,然后到vue.config.js配置:

const CompressionPlugin = require("compression-webpack-plugin");

configureWebpack: config => {
    config.name = name
    const plugins = []
    if (IS_PROD) { // 生產(chǎn)環(huán)境
      plugins.push( 
        // 為靜態(tài)資源準(zhǔn)備壓縮版本三妈,在服務(wù)器也要開啟相應(yīng)配置
        new CompressionWebpackPlugin({
          test: /\.(js|css|json|ico|svg)$/,// 匹配文件格式
          algorithm: 'gzip',
          threshold: 10240, // 對超過10k的數(shù)據(jù)壓縮
          minRatio: 0.8, // 壓縮比
          // filename: "[path][base].gz", // 壓縮后的文件名,默認(rèn)值是 [path][base].gz
          filename(pathData) {
            // `pathData` 參數(shù)包含很多可以獲取到文件路徑相關(guān)數(shù)據(jù)的屬性 - `path`/`name`/`ext`/等等
            // 如果路徑中包含svg莫绣,則放到svg/目錄下
            // 只是演示畴蒲,一般都用字符串默認(rèn)值就好
            if (/\.svg$/.test(pathData.ext)) {
              return 'static/svg/[base].gz'
            }
            return '[path][base].gz'
          },
          deleteOriginalAssets: false, // 不刪除源文件,true 則只保留壓縮后的文件
        })
      )
    } else {
      // 為開發(fā)環(huán)境修改配置
    }
    config.plugins = [...config.plugins, ...plugins]
  },

其中 filename 參數(shù)就是定義文件編碼壓縮后的路徑和文件名对室,格式除了字符串也可以是Function(基本沒啥必要)模燥。
默認(rèn)值是"[path][base].gz",一般保持默認(rèn)值就好掩宜。
gz是文件后綴蔫骂,那[path][base] 是啥呢

比如我們有這么個(gè)靜態(tài)資源:static/images/image.png?foo=bar#hash (static是我打包目錄下自定義的靜態(tài)資源目錄),然后若我們給插件 filename 的值里配置如下參數(shù)牺汤,完成壓縮后輸出的文件名中:

  • [path] 會(huì)被替換為源靜態(tài)資源的目錄, 包括末尾的 / (static/images/)
  • [file] 為源靜態(tài)資源的路徑 (static/images/image.png)
  • [name] 為源文件的文件名 (image)
  • [ext] 為源文件(包含.)的擴(kuò)展名 (.png)
  • [base] 會(huì)被替換為 ([name] + [ext]) 的內(nèi)容 (image.png)
  • [query] 為源文件的查詢參數(shù)辽旋,包括 ? (?foo=bar)
  • [fragment] 為源文件的 fragment (在URL的概念里叫做hash)(#hash)
在filename給svg單獨(dú)配文件名的效果
打完包大部分文件會(huì)多出一個(gè)gz版本,
根據(jù)我們的配置檐迟,size小于threshold數(shù)值的文件不會(huì)生成gz版本

參考文章:探索HTTP傳輸中g(shù)zip壓縮

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末补胚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子追迟,更是在濱河造成了極大的恐慌溶其,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敦间,死亡現(xiàn)場離奇詭異握联,居然都是意外死亡桦沉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門金闽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纯露,“玉大人,你說我怎么就攤上這事代芜〔和剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵挤庇,是天一觀的道長钞速。 經(jīng)常有香客問我,道長嫡秕,這世上最難降的妖魔是什么渴语? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮昆咽,結(jié)果婚禮上驾凶,老公的妹妹穿的比我還像新娘。我一直安慰自己掷酗,他們只是感情好调违,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泻轰,像睡著了一般技肩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浮声,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天虚婿,我揣著相機(jī)與錄音,去河邊找鬼泳挥。 笑死雳锋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羡洁。 我是一名探鬼主播玷过,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筑煮!你這毒婦竟也來了辛蚊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤真仲,失蹤者是張志新(化名)和其女友劉穎袋马,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秸应,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虑凛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年碑宴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桑谍。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡延柠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锣披,到底是詐尸還是另有隱情贞间,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布雹仿,位于F島的核電站增热,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胧辽。R本人自食惡果不足惜峻仇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邑商。 院中可真熱鬧摄咆,春花似錦、人聲如沸奠骄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽含鳞。三九已至,卻和暖如春芹务,著一層夾襖步出監(jiān)牢的瞬間蝉绷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工枣抱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熔吗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓佳晶,卻偏偏與公主長得像桅狠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子轿秧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容