ホームページ  >  記事  >  ウェブフロントエンド  >  HTTP での Gzip 圧縮の問題

HTTP での Gzip 圧縮の問題

亚连
亚连オリジナル
2018-06-12 14:39:251537ブラウズ

Gzip は、現在、特に Linux プラットフォームで広く使用されている人気のあるファイル圧縮アルゴリズムです。以下の記事では、HTTP 送信における gzip 圧縮に関する関連情報を中心に紹介しています。必要な方はぜひ参考にしてください。

はじめに

Web ページの読み込みを高速化する利点は、トラフィックを節約し、ユーザーのブラウジング エクスペリエンスを向上させることに加えて、Gzip と検索エンジン クローラーとの関係が改善されることも明らかです。たとえば、Google は gzip ファイルを直接読み取ることで、通常の手動クロールよりも速く Web ページをクロールできます。 Google ウェブマスター ツールでは、sitemap.xml.gz がサイトマップとして直接送信されていることがわかります。

そして、これらの利点は静的コンテンツに限定されません。PHP 動的ページやその他の動的に生成されたコンテンツは、Apache 圧縮モジュールを使用して圧縮でき、他のパフォーマンス調整メカニズムや対応するサーバー側のキャッシュ ルールと組み合わせることで、Web サイトを大幅に改善できます。パフォーマンス。したがって、Linux サーバーにデプロイされた PHP プログラムの場合は、サーバーがサポートしている場合は Gzip Web 圧縮を有効にすることをお勧めします。以下に詳しい紹介を見てみましょう。

なぜ gZip をオンにしなければならないのですか

私たちが誰かに電子メールを送信するとき、送信する前にファイルを圧縮し、受信者は受信後に解凍してファイルを取得します。この操作は私たちにとってすでに当たり前のことです。ファイルを圧縮する目的は、転送されるファイルのサイズを削減し、転送を高速化することです。 http 送信で gZip を有効にする目的にも同じことが当てはまりますが、一般に記事で gZip を紹介する場合、必ずそれをサーバー側の構成 (nginx) またはビルド ツール プラグイン (webpack) と組み合わせて、多くの構成をリストします。あまりにも霧がかかっていたので、結局のところ、なぜそれをどのように使用するのかがわかりませんでした。

http と gZip

これらの問題について以下で議論しましょう

gZip ファイルを通信する方法

圧縮ファイルを他の人に転送するとき、私たちは通常、.rar、.zip などの接尾辞名を使用します。ファイルを取得したら、対応するサフィックス名に従ってさまざまな解凍方法を選択して、ファイルを解凍します。私たちが使用するブラウザは、HTTP通信時にファイルを解凍する役割を担っていますが、ブラウザはファイルがどのような形式であるか、どのような形式で解凍すればよいのかをどのように判断しているのでしょうか。

http/1.0 プロトコルでは、サーバーによって送信されるデータに対して Content-Encoding フィールドを設定できます。このフィールドは、データの圧縮方法を記述するために使用されます。

Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate

クライアントは、対応するフィールドの情報を確認します。返されたデータを受信した後、対応するフォーマットに従って対応するデコードを実行します。リクエストを行うとき、クライアントは Accept-Encoding フィールドを使用して、受け入れる圧縮方法を指定できます。

Accept-Encoding: gzip, deflate

リクエストの関連情報はブラウザのコンソールで確認できます

互換性

フロントエンドとしてのブラウザに関して言えば、私はある疑問を考えずにはいられません。それをサポートしていないブラウザがあります。 HTTP/1.0 は 1996 年 5 月にリリースされました。幸いなことに、基本的に互換性の問題を心配する必要はなく、ほぼすべてのブラウザが互換性をサポートしています。 ie6 の初期バージョンには gZip を破壊するバグがあったことは言及しておく価値があります。その後、ie6 自体が WinXP SP2 でこの問題を修正しましたが、このバージョンを使用しているユーザーの数も非常に少ないです。

ファイルを圧縮するのは誰ですか

これはサーバー側でのみ実行できるようですが、インターネットで最もよく目にするのは gZip 構成を有効にする nginx などの記事ですが、現在、フロントエンドは、react を使用します。vue などのフレームワークには、通常、独自のスキャフォールディング セットが付属しており、圧縮を可能にする Compression-webpack-plugin などのプラグインを設定できます。生成されたファイルを gZip で生成し、対応する圧縮ファイルを生成することもできます。アプリケーションを構築するときは、サービス エリアにノード アプリケーションの層を配置し、インターフェイス認証とファイル転送のためにフロントエンド ファイルを配置することもあります。私たちがよく知っている nodejs の Express フレームワークにも、gZip を有効にする圧縮ミドルウェアがあります。誰がどのように使用すればよいのか、しばらく戸惑っています。

リクエストに応答するときにサーバーが圧縮されます

其实 nginx 压缩和 node 框架中用中间件去压缩都是一样的,当我们点击网页发送一个请求时候,我们的服务端会找到对应的文件,然后对文件进行压缩返回压缩后的内容【当然可以利用缓存减少压缩次数】,并配置好我们上面提到的 Content-Encoding 信息。对于一些应用在构架时候并没有上游代理层,比如服务端就一层 node 就可以直接用自己本身的压缩插件对文件进行压缩,如果上游配有有 nginx 转发处理层,最好交给 nginx 来处理这些,因为它们有专门为此构建的内容,可以更好的利用缓存并减小开销(很多使用c语言编写的)。

我们看一些 nginx 中开启 gZip 压缩的一部分配置

# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript;

应用构建时候压缩

既然服务端都可以做了为什么 webpack 在打包前端应用时候还有这样一个压缩插件呢,我们可以在上面 nginx 配置中看到 gzip_comp_level 2 这个配置项,上面也有注释写道 1-10 数字越大压缩效果越好,但是会耗费更多的CPU和时间,我们压缩文件除了减少文件体积大小外,也是为了减少传输时间,如果我们把压缩等级配置的很高,每次请求服务端都要压缩很久才回返回信息回来,不仅服务器开销会增大很多,请求方也会等的不耐烦。但是现在的 spa 应用既然文件都是打包生成的,那如果我们在打包时候就直接生成高压缩等级的文件,作为静态资源放在服务器上,接收到请求后直接把压缩的文件内容返回回去会怎么样呢?

webpack 的 compression-webpack-plugin 就是做这个事情的,配置起来也很简单只需要在装置中加入对应插件,简单配置如下

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
 })
)

webpack 打包完成后生成打包文件外还会额外生成 .gz 后缀的压缩文件

那么这个插件的压缩等级是多少呢,我们可以在源码中看到默认的 level 是 9

...
const zlib = require('zlib');
this.options.algorithm = zlib[this.options.algorithm];
...
this.options.compressionOptions = {
 level: options.level || 9,
 flush: options.flush
 ...
}

可以看到压缩使用的是 zlib 库,而 zlib 分级来说,默认是 6 ,最高的级别就是9 Best compression (also zlib.Z_BEST_COMPRESSION),因为我们只有在上线项目时候才回去打包构建一次,所以我们在构建时候使用最高级的压缩方式压缩多耗费一些时间对我们来说根本没任何损耗,而我们在服务器上也不用再去压缩文件,只需要找到相应已经压缩过的文件直接返回就可以了。

服务端怎么找到这些文件

在应用层面解决这个问题还是比较简单的,比如上述压缩文件会产生index.css, index.js的压缩文件,在服务端简单处理可以判断这两个请求然后给予相对应的压缩文件。以 node 的 express 为例

...
app.get(['/index.js','/index.css'], function (req, res, next) {
 req.url = req.url + '.gz'
 res.set('Content-Encoding', 'gzip')
 res.setHeader("Content-Type", generateType(req.path)) // 这里要根据请求文件设置content-type
 next()
})

上面我们可以给请求返回 gZip 压缩后的数据了,当然上面的局限性太强也不可取,但是对于处理这个方面需求也已经有很多库存在,express 有 express-static-gzip 插件 koa 的 koa-static 则默认自带对 gZip 文件的检测,基本原理就是对请求先检测 .gz后缀的文件是否存在,再去根据结果返回不同的内容。

哪些文件可以被 gZip 压缩

gZip 可以压缩所有的文件,但是这不代表我们要对所有文件进行压缩,我们写的代码(css,js)之类的文件会有很好的压缩效果,但是图片之类文件则不会被 gzip 压缩太多,因为它们已经内置了一些压缩,一些文件(比如一些已经被压缩的像.zip文件那种)再去压缩可能会让生成的文件体积更大一些。当然已经很小的文件也没有去压缩的必要了。

实践

能开启 gZip 肯定是要开启的,具体使用在请求时候实时压缩还是在构建时候去生成压缩文件,就要看自己具体业务情况。

参考资料

  • How are zlib, gzip and zip related? What do they have in common and how are they different?

  • webpack gzip vs express gzip

  • What is gZip compression?

  • HTTP 协议

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

关于vue2.0中datepicker使用方法

JavaScript调停者模式(详细教程)

在jQuery中有关Dom元素使用方法?

在Vue中如何实现事件响应式进度条组件

JSで2つの変数値の交換メソッドを実装する方法

以上がHTTP での Gzip 圧縮の問題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。