gzip でネットワーク ペイロードを最小化して圧縮する

この Codelab では、JavaScript の圧縮と圧縮を使用して、 次のアプリケーションのバンドルは、 アプリのリクエスト サイズ。

アプリのスクリーンショット

測定

最適化の追加に入る前に、まず分析を行ってから、 現在の状態を把握できます。

  • サイトをプレビューするには、[アプリを表示] を押します。[ 全画面表示 全画面表示

このアプリについては、「未使用のアプリを削除する」 Codelab のようにコードを使用して、お気に入りの言語に投票できます。 検出します。🐈

次に、このアプリケーションの大きさを見てみましょう。

  1. Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
  2. [ネットワーク] タブをクリックします。
  3. [キャッシュを無効にする] チェックボックスをオンにします。
  4. アプリを再読み込みします。

[ネットワーク] パネルの元のバンドルサイズ

未使用のコードを削除する」は多くの進歩を遂げましたが、 Codelab を使用すると、このバンドルサイズを縮小できます。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 バイトになります。リスクを減らしてさらに被害を 変数名の長さの変更と式の変更により、最終的なコードが このようになります。

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

ファイルサイズが 62 B に達した。

段階を追うごとにコードが読みにくくなります。ただし、ブラウザの JavaScript エンジンはこれらをまったく同じように解釈します。「 このようにコードを難読化するメリットは、 あります。112 B もそもそもそれほど多くはありませんでしたが、 小さくなります。

このアプリケーションでは、webpack バージョン 4 が モジュール バンドラを使用します。具体的なバージョンは package.json で確認できます。

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

バージョン 4 では、本番環境モードではデフォルトでバンドルが圧縮されています。使用される TerserWebpackPlugin: Terser のプラグイン。 Terser は、JavaScript コードの圧縮によく使用されるツールです。

圧縮されたコードがどのようなものか確認するには main.bundle.js: DevTools の [Network] パネルから移動します。[ [Response] タブ。

圧縮されたレスポンス

圧縮およびマングリングされた最終的な形式のコードが、レスポンスの本文に表示されます。 バンドルが圧縮されていない場合にどれくらいのサイズになったかを確認するには、 webpack.config.js を実行し、mode 構成を更新します。

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

アプリケーションを再読み込みし、 DevTools の [Network] パネル

バンドル サイズ: 767 KB

かなり大きな違いです。😅

続行する前に、必ずここで変更を元に戻してください。

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

コードを圧縮するプロセスをアプリケーションに含めるかどうかは、 以下を使用します。

  • webpack v4 以降を使用している場合は、追加の作業は必要ありません 本番環境ではコードがデフォルトで圧縮されるためです👍
  • 古いバージョンの webpack を使用している場合は、TerserWebpackPlugin をインストールして含めます。 webpack のビルドプロセスに 組み込まれますドキュメント 詳しく説明します。
  • 他の圧縮プラグインも存在しており、代わりに使用できます。 BabelMinifyWebpackPlugin など ClosureCompilerPlugin を使っていました。
  • モジュール バンドラをまったく使用しない場合は、Terser を使用します。 直接依存関係として組み込みます。

圧縮

「圧縮」という用語はコードがどのように使用されるかを説明するために、 圧縮されずに圧縮され、実際の あります

圧縮は通常、データを使用して変更されたコードを指します。 構成されます。最終的に完璧な動作が実現する軽量化とは異なり、 圧縮済みコードは、使用する前に解凍しておく必要があります。

HTTP リクエストとレスポンスごとに、ブラウザとウェブサーバーは HTTP リクエストやレスポンスを ヘッダー 取得または受信するアセットに関する追加情報。これは次のいずれかです。 DevTools の [Network] パネルの [Headers] タブに表示される 3 種類の 表示されます。

  • General は、リクエスト / レスポンス全体に関連する一般的なヘッダーを表します。 です。
  • [レスポンス ヘッダー] には、実際のレスポンスに固有のヘッダーのリストが表示されます。 取得します。
  • [Request Headers] には、リクエストに添付されたヘッダーのリストが できます。

Request Headersaccept-encoding ヘッダーをご覧ください。

エンコード ヘッダーを受け入れる

accept-encoding は、ブラウザがコンテンツを指定するために使用されます。 圧縮アルゴリズムなど、さまざまな方式があります。Google の テキスト圧縮アルゴリズムが存在しますが、 HTTP ネットワーク リクエストの圧縮(および解凍)については、以下がサポートされています。

  • Gzipgzip): 最も広く使用されている圧縮方法 形式をサポートしています。Deflate を基盤としており、 アルゴリズムをサポートし、現在のすべてのブラウザでサポートされています。
  • Deflate(deflate): あまり使用されません。
  • Brotlibr): 比較的新しい圧縮 圧縮率の改善を目的としたアルゴリズムです。これにより、 ページの読み込みを高速化できますサポートされている ほとんどのブラウザの最新バージョン

このチュートリアルのサンプル アプリケーションは、 Codelab「使用されていないコードの削除」を サーバー フレームワークとして Express が使用されるようになりました。次の いくつかのセクションでは、静的圧縮と動的圧縮の両方について見ていきます。

動的圧縮

動的圧縮では、アセットを取得したときにその場で圧縮する ブラウザによってリクエストされます。

長所

  • アセットの圧縮バージョンの作成と更新は、 できます。
  • オンザフライでの圧縮は、次のようなウェブページで特に効果的です。 動的に生成されます。

短所

  • 圧縮率を高めるためにファイルを高いレベルで圧縮する 時間がかかります。アセットがアップロードされるまで待っていると、パフォーマンスが低下する可能性があります。 サーバーに送信される前に圧縮されます。

Node/Express による動的圧縮

server.js ファイルは、ホストするノードサーバーを設定します。 確認します。

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 によって作成されます)。

リクエストされるたびにすべてのアセットが圧縮されるように、 compression ミドルウェア ライブラリによって、 使用できます。まず、これを devDependency として package.json に追加します。

"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 使用できます。

まず、これを devDependency として package.json に追加します。

"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

公開ディレクトリ内の最終出力ファイル

gzip で圧縮されたバンドルの main.bundle.js.gz が、ここに あります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 がリクエストの URL にアタッチされ、 Content-Encoding レスポンス ヘッダーが gzip に設定されます。
  • 最後に、next() はシーケンスが任意のコールバックに続くようにします。 説明します。

アプリが再読み込みされたら、もう一度 Network パネルを確認します。

静的圧縮によるバンドル サイズの削減

以前と同様に、バンドルサイズが大幅に削減されています。

まとめ

この Codelab では、ソースコードを圧縮して圧縮するプロセスを説明しました。 これらの手法は、どちらも多くのツールでデフォルトになってきています。 ご使用のツールチェーンが サポートされているか、自分で両方のプロセスを適用すべきか判断できます。