使用 gzip 壓縮網路酬載並壓縮

本程式碼研究室會探討如何壓縮及壓縮 JavaScript 下列應用程式的套裝組合可減少網頁效能 應用程式要求大小

應用程式螢幕截圖

測量

著手新增最佳化項目之前,最好先進行分析 應用程式目前狀態

  • 如要預覽網站,請按下「查看應用程式」。然後按下 全螢幕 全螢幕

該應用程式也列載於「移除未使用的應用程式 code"程式碼研究室,讓您可以票選出最喜歡的 小貓。🐈

現在來看看這個應用程式的大小:

  1. 按下 Control+Shift+J 鍵 (或在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  2. 按一下 [網路] 分頁標籤。
  3. 勾選「停用快取」核取方塊。
  4. 重新載入應用程式。

「網路」面板中的原始套件大小

雖然「移除未使用的程式碼」一節中有許多進展 程式碼研究室說明如何縮減這個套件大小,225 KB 仍是相當大的。

壓縮

請考慮使用以下程式碼區塊。

function soNice() {
  let counter = 0;

  while (counter < 100) {
    console.log('nice');
    counter++;
  }
}

如果這個函式是儲存在本身的檔案中,其檔案大小約 112 B (位元組)。

如果移除所有空白字元,產生的程式碼如下所示:

function soNice(){let counter=0;while(counter<100){console.log("nice");counter++;}}

檔案大小現在約為 83 B。如果目標遭受進一步損害 例如變數名稱長度並修改某些運算式 看起來會像這樣:

function soNice(){for(let i=0;i<100;)console.log("nice"),i++}

檔案大小現在達到 62 B

每加入一個步驟,程式碼就會越難閱讀。不過,瀏覽器的 JavaScript 引擎會以完全相同的方式解讀每個選項。 以這種方式模糊處理程式碼,有助於製作更小的檔案 大小。112 B 剛開始是不是很辛苦,但還是有 50% 縮減大小!

在這個應用程式中,webpack 第 4 版是以 模組組合工具您可以在 package.json 中查看特定版本。

"devDependencies": {
  //...
  "webpack": "^4.16.4",
  //...
}

第 4 版已在實際工作環境模式中預設壓縮套件。使用 TerserWebpackPlugin 適用於 Terser 的外掛程式。 Terser 是用來壓縮 JavaScript 程式碼的熱門工具。

如要瞭解經過壓縮的程式碼格式,請按一下 main.bundle.js,位於開發人員工具的「Network」面板中。現在點選 「Response」分頁。

壓縮回應

最終格式的程式碼會經過壓縮並破壞,顯示在回應主體中。 如要確認套裝組合未壓縮時的尺寸,請開啟 webpack.config.js 並更新 mode 設定。

module.exports = {
  mode: 'production',
  mode: 'none',
  //...

請重新載入應用程式,然後再次透過 開發人員工具「網路」面板

套件大小 (767 KB)

比以前有點不同!😅

繼續操作前,請務必先還原這裡的變更。

module.exports = {
  mode: 'production',
  mode: 'none',
  //...

在應用程式中加入壓縮程式碼的程序會因工具而異 您使用的工具:

  • 如果使用的是 webpack v4 以上版本,則無須進行額外作業 因為程式碼在生產模式中預設會壓縮👍
  • 如果使用的是舊版 Webpack,請安裝並納入 TerserWebpackPlugin 嵌入至 webpack 建構程序說明文件 詳細說明。
  • 另外,您也可以使用其他壓縮外掛程式 例如 BabelMinifyWebpackPlugin。 和 ClosureCompilerPlugin 之間。
  • 如果完全沒有使用模組組合工具,請使用 Terser 做為 CLI 工具或直接加入為依附元件。

壓縮

雖然「壓縮」一詞有時會解釋為何會濫用 壓縮程序減少,實際上並未壓縮成 顧名思義,

壓縮通常是指透過資料修改的程式碼 壓縮演算法反之,壓縮後 有效的程式碼,且壓縮後的程式碼必須先解壓縮才能使用。

針對每個 HTTP 要求和回應,瀏覽器和網路伺服器 要加入的 headers 有關擷取或接收資產的其他資訊。可用的值包括 「開發人員工具網路」面板中的「Headers」分頁,其中三種類型 顯示:

  • General 代表與整個要求/回應相關的一般標頭 互動。
  • 「回應標頭」會顯示實際回應的專屬標頭清單 。
  • 「要求標頭」會顯示 用戶端。

查看 Request Headers 中的 accept-encoding 標頭。

接受編碼標頭

瀏覽器會使用 accept-encoding 指定哪些內容 編碼格式或壓縮演算法等有許多 文字壓縮演算法 這裡支援 HTTP 網路要求的壓縮 (及解壓縮) 方法:

  • Gzip (gzip):最常用的壓縮格式 伺服器和用戶端互動的格式。建構在防禦措施之上 演算法,且適用於所有目前的瀏覽器。
  • 延遲 (deflate):不常用。
  • Brotli (br):較新的壓縮 演算法的目標是進一步改善壓縮率,因此 加快網頁載入速度您可以在 大多數瀏覽器的最新版本

本教學課程中的範例應用程式與 「移除未使用的程式碼」程式碼研究室: Express 現已成為伺服器架構。未來 這堂課將探討靜態和動態壓縮

動態壓縮

動態壓縮是指在資產時即時壓縮 瀏覽器要求。

優點

  • 即使沒有建立或更新資產的壓縮版本 完成。
  • 即時壓縮功能特別適用於 動態產生。

缺點

  • 以較高的層級壓縮檔案來提高壓縮率 但會需要較長的時間使用者等待素材資源執行完畢,可能會發生成效命中 伺服器傳送檔案之前先行壓縮

使用 Node/Express 動態壓縮

server.js 檔案負責設定託管的 Node 伺服器 應用程式

const express = require('express');

const app = express();

app.use(express.static('public'));

const listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

目前這項操作是匯入 express 並使用 express.static 中介軟體會將所有靜態 HTML、JS 和 CSS 檔案 public/ 目錄 (而這些檔案是由 webpack 與每個版本建立)。

為了確保所有資產都經過壓縮,且每次發出請求時都會壓縮, 壓縮中介軟體程式庫 。第一步,是將其新增為 package.json 中的 devDependency

"devDependencies": {
  //...
  "compression": "^1.7.3"
},

並匯入伺服器檔案 server.js

const express = require('express');
const compression = require('compression');

並在掛接 express.static「之前」將其新增為中介軟體:

//...

const app = express();

app.use(compression());

app.use(express.static('public'));

//...

現在,請重新載入應用程式,然後查看「Network」面板中的套件大小。

包含動態壓縮的軟體包大小

從 225 KB 到 61.6 KB!現在 Response Headers 中的 content-encoding 標頭顯示伺服器傳送這個使用 gzip 編碼的檔案。

內容編碼標頭

靜態壓縮

「靜態」壓縮的功用是將資產壓縮並儲存 這樣就大功告成了

優點

  • 再也不用擔心因為壓縮等級造成延遲的問題。 現在可以直接擷取檔案,不需要採取任何行動。

缺點

  • 每個版本都需要壓縮資產。建構時間可能會增加 如果使用高壓縮率,成效會相當顯著

使用 Node/Express 和 webpack 進行靜態壓縮

靜態壓縮涉及事先壓縮檔案 在建構步驟中,您可以修改設定來壓縮資產。 CompressionPlugin敬上 這也能派上用場

第一步,是將其新增為 package.json 中的 devDependency

"devDependencies": {
  //...
  "compression-webpack-plugin": "^1.1.11"
},

就像任何其他 webpack 外掛程式一樣 請匯入設定檔 webpack.config.js:

const path = require("path");

//...

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

並在 plugins 陣列中加入這個字串:

module.exports = {
  //...
  plugins: [
    //...
    new CompressionPlugin()
  ]
}

根據預設,外掛程式會使用 gzip 壓縮建構檔案。一探究竟 說明文件 瞭解如何新增選項以使用其他演算法,或納入/排除 特定檔案

應用程式重新載入並重新建構時,主套件的壓縮版本會變為 建立完成開啟 Glitch 控制台,看看內部是什麼 由節點伺服器提供的最終 public/ 目錄。

  • 按一下「工具」按鈕。
  • 按一下「Console」按鈕。
  • 在控制台中執行下列指令,切換至 public 目錄並查看其所有檔案:
cd public
ls

公開目錄中的最終輸出檔案

套件「main.bundle.js.gz」的 gZIP 版本現在儲存在這裡: 根據預設,CompressionPlugin 也會壓縮 index.html

接著,您必須指示伺服器將 gzip 壓縮 。都可以 ,先在 server.js 中定義新路徑,再透過 express.static

const express = require('express');
const app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.gz';
  res.set('Content-Encoding', 'gzip');
  next();
});

app.use(express.static('public'));

//...

app.get 是用於指示伺服器如何回應 GET 要求 特定端點接著,回呼函式會用於定義處理方式 請求。路線的運作方式如下:

  • '*.js' 指定為第一個引數,表示這個引數適用於 端點,用於擷取 JS 檔案。
  • 在回呼中,.gz 會附加至要求的網址, Content-Encoding 回應標頭已設為 gzip
  • 最後,next() 可確保序列繼續執行任何回呼 可能會遇到下一個問題

應用程式重新載入後,請再次查看 Network 面板。

使用靜態壓縮來縮減套件大小

和先前一樣,套裝組合的套裝組合有大幅縮減!

結論

本程式碼研究室涵蓋了壓縮及壓縮原始碼的程序。 這兩種技術已成為許多工具的預設方式 因此請務必確認您的工具鍊是否已提供 或應該自行開始應用這兩種程序。