gzip圧縮の仕組み

画像 すべての人の生活の中で、トラフィックが増加し、 サーバーが死に絶えているときが来ます 。最適化について考える必要があります。 最新のPHPダイジェスト( No. 40 )では、記事「How GZIP Compression Works」が参照されました。 統計に基づいて、ウェブサイトの56%がGZIPを使用しています。 この記事がこのテクノロジーのメリットを読者に明らかにすることを願っています。





テキストにエラーが発生する可能性があるため(校正を数回行いましたが、突然)、翻訳の一部が間違っているように思われる場合は、事前に謝罪し、プライベートメッセージですべての問題をお知らせください。



高速インターネット接続と情報の無制限のストレージを備えた現代の世界でさえ、特にインターネット接続の遅いモバイル機器や国では、データ圧縮が依然として重要です。 この投稿では、Webサイト上のテキストデータを圧縮するための事実上のロスレス圧縮方法、GZIPについて説明します。



Gzip圧縮



GZIPはロスレス圧縮を提供します。つまり、元のデータは解凍中に完全に復元できます。 これは、LZ77アルゴリズムとハフマンアルゴリズムの組み合わせを使用するDEFLATEアルゴリズムに基づいています。



アルゴリズムLZ77


LZ77アルゴリズムは、繰り返し発生するデータを「リンク」に置き換えます。 つまり 利用可能なデータ内で要素のチェーンが複数回発生した場合、その後のすべての発生は、最初のインスタンスへの「リンク」に置き換えられます。 このアルゴリズムは、 horror_xによって十分にレビューされておりここで説明されています 。 このような各リンクには、オフセットと長さの2つの意味があります。



例を見てみましょう:

元のテキスト:「PHPホスティング会社であるServerGroveは、PHPプロジェクトのホスティングソリューションを提供します」(81バイト)

LZ77:「サーバーグローブ、PHPホスティング会社、p <3.32> ides <9.26>の<5.52> <3.35>件のソリューション」(73バイト、各参照が3バイトであると仮定)




ご覧のとおり、「ホスティング」と「PHP」という言葉が繰り返されているため、2回目に部分文字列が見つかると、リンクに置き換えられます。 「er」など、他の一致もありますが、 それは重要ではありませ(この場合-「er」は言い換えれば) 、元のテキストは残ります。



ハフマンコーディング


ハフマン符号化は、より短いコードをより頻繁な「文字」に割り当てる可変長符号化方式です。 可変コード長の問題は、通常、コードを解読するためにコードがいつ終了し、新しいコードが開始したかを知る方法が必要なことです。



ハフマンコーディングは、コードワードが別のプレフィックスではないプレフィックスコードを作成することにより、この問題を解決します。 これは例を使用してより明確になる場合があります。



>元のテキスト:「ServerGrove」

ASCIIコード: "01010011 01100101 01110010 01110110 01100101 01110010 01000111 01110010 01101111 01110110 01100101"(88ビット)


ASCIIは固定長の文字エンコードシステムであるため、3回繰り返され、英語でも最も一般的な文字である「e」という文字は、「G」という1回だけ現れる文字と同じサイズです。 この統計情報を使用して、ハフマンは最も最適化されたシステムを作成できます。



ハフマン:「1110 00 01 10 00 01 1111 01 110 10 00」(27ビット)


ハフマン法では、「e」、「r」、「v」のコードを短くすることができますが、「S」と「G」は長くなります。 Huffmanメソッドの使用方法の説明はこの投稿の範囲外ですが、興味がある場合は、 Computerphileの優れたビデオ(またはHabréの記事)に精通することをお勧めします。



DEFLATEは、GZIP圧縮で使用されるアルゴリズムとして、これらの両方のアルゴリズムの組み合わせです。



gzipは最適な圧縮方法ですか?


答えはノーです。 より高い圧縮率を与える他の方法がありますが、これを使用するいくつかの正当な理由があります。



第一に、GZIPは最良の圧縮方法ではありませんが、速度と圧縮率のバランスが取れています。 GZIPの圧縮と解凍は高速で、圧縮率は高くなっています。

第二に、誰もが使用できる新しいグローバルデータ圧縮方法を実装するのは簡単ではありません。 ブラウザには更新が必要になりますが、今日は自動更新によりはるかに簡単になっています。 ブラウザーだけが問題ではないかもしれません。 Chromiumは、Burroughs-Wheeler変換に基づくより良い方法であるBZIP2のサポートを追加しようとしましたが、それを放棄しなければなりませんでした。 いくつかの中間プロキシがデータを歪めた bzip2ヘッダーを認識できず、gzipコンテンツを処理しようとしました。 バグレポートはこちらから入手できます



Gzip + http


クライアント(ブラウザ)とサーバー間で圧縮されたコンテンツを取得するプロセスは非常に簡単です。 ブラウザがGZIP / DEFLATEをサポートしている場合、サーバーは「Accept-Encoding」ヘッダーのおかげでこれを理解します。 次に、サーバーはコンテンツを圧縮形式で送信するか、元の形式で送信するかを選択できます。











実装


DEFLATE仕様は、結果のストリームが仕様と互換性がある限り、開発者がさまざまなアプローチを使用してアルゴリズムを実装する自由を提供します。



GNU GZIP


GNU実装は最も一般的であり、独自のアルゴリズムを含まないアーカイブユーティリティの代わりになるように設計されています。 GNU GZIPユーティリティを使用してファイルを圧縮するには:

$ gzip -c file.txt> file.txt.gz


「1」(最低の圧縮率で最速)から「9」(最高の圧縮率で最低速)まで、9つの圧縮レベルがあります。 デフォルトでは、「6」が使用されます。 より多くのメモリと時間を使用して最大の圧縮が必要な場合は、「-9」(または「-best」)フラグを使用します。

$ gzip -9 -c file.txt> file.txt.gz




7-zip


7-zipはDELFATEアルゴリズムの実装方法が異なり、通常より高い圧縮率でアーカイブします。 ファイルを可能な限り圧縮するには:

7z a -mx9 file.txt.gz file.txt


7-zipはWindowsでも使用でき、7z、xz、bzip2、zipなどの他の圧縮方法の実装を提供します。



ゾフリ


Zopfliは、たとえば、ファイルが一度圧縮されて再利用される状況など、1回限りの圧縮に最適です。 100倍遅いですが、圧縮率は他の5倍です。 ハブラポスト



gzipを有効にする


アパッチ


mod_deflateモジュールはGZIPサポートを提供するため、サーバーの応答はネットワーク経由でクライアントに送信される前にオンザフライで圧縮されます。 テキストファイルの圧縮を有効にするには、次の行に.htaccessを追加する必要があります。

AddOutputFilterByType DEFLATEテキスト/プレーン

AddOutputFilterByType DEFLATE text / html

AddOutputFilterByType DEFLATE text / xml

AddOutputFilterByType DEFLATE text / css

AddOutputFilterByType DEFLATEアプリケーション/ xml

AddOutputFilterByType DEFLATEアプリケーション/ xhtml + xml

AddOutputFilterByType DEFLATEアプリケーション/ rss + xml

AddOutputFilterByType DEFLATEアプリケーション/ javascript

AddOutputFilterByType DEFLATEアプリケーション/ x-javascript




ブラウザの一部のバージョンにはいくつかの既知のバグがあるため、追加することをお勧めします*

BrowserMatch ^ Mozilla / 4 gzip-only-text / html

BrowserMatch ^ Mozilla / 4 \ .0 [678] no-gzip

BrowserMatch \ bMSIE!no-gzip!Gzip-only-text / html

ヘッダー付加Vary User-Agent
*このソリューションは、上記のブラウザと同様にすでに関連性を失っているので、この情報は情報目的で取得することができます



さらに、毎回圧縮する代わりに、事前に圧縮されたファイルを使用できます。 これは、遅いアルゴリズムを使用して圧縮できるCSSやJavaScriptなど、リクエストごとに変化しないファイルに特に役立ちます。 これを行うには:

Rewriteengine on

AddEncoding gzip .gz

RewriteCond%{HTTP:Accept-encoding} gzip

RewriteCond%{REQUEST_FILENAME} .gz -f

RewriteRule ^(。*)$ $ 1.gz [QSA、L]



これにより、Apacheは.gz拡張子のファイルが圧縮されて提供される必要があることを理解し(2行目)、ブラウザーがgzipを受け入れられるかどうかを確認する必要があり(3行目)、圧縮ファイルが存在する場合は(4行目)、要求されたファイルに.gzを追加します。



Nginx


ngx_http_gzip_moduleモジュールを使用すると、GZIPを使用してその場でファイルを圧縮できます。一方、 ngx_http_gzip_static_moduleを使用すると、通常のファイルではなく「.gz」拡張子の事前圧縮ファイルを送信できます。

設定例は次のとおりです。

gzip on;

gzip_min_length 1000;

gzip_types text / plain application / xml;




Gzip + PHP


通常、PHPを使用してデータを圧縮することは推奨されませんが、かなり遅いため、 zlibモジュールを使用してこれを行うことができます。 たとえば、jQuery.minライブラリで最大圧縮を使用します。



$originalFile = __DIR__ . '/jquery-1.11.0.min.js'; $gzipFile = __DIR__ . '/jquery-1.11.0.min.js.gz'; $originalData = file_get_contents($originalFile); $gzipData = gzencode($originalData, 9); file_put_contents($gzipFile, $gzipData); var_dump(filesize($originalFile)); // int(96380) var_dump(filesize($gzipFile)); // int(33305)
      
      







出力の代わりに(翻訳者のメモ)


アルゴリズム、統計、および比較テストの結果についての独自の説明を著者の記事に追加するのがいかに手間がかかったとしても、翻訳は実際には翻訳者の干渉なしに行われました。 この記事は 、著者およびServerGroveポータルの許可を得て翻訳されました。



All Articles