web-dev-qa-db-ja.com

Apacheで事前に圧縮された静的コンテンツをホストする方法は?

基本的に.htmlファイルと.dataファイルで構成されるJavaScriptゲームをホストしています。 gzipで圧縮すると、サイズが25%に縮小します。だからやりたいです。

100%確信はありませんが、mod_gzipまたはmod_deflateを使用すると、オンザフライで圧縮が行われ、コンテンツが変更されないため、常にcpu時間が無駄になると思います。

だから私はコンテンツをプリコンパイルしたいと思います。したがって、非圧縮ファイルの横に.gzを配置し、.htaccessに書き換えルールを配置します。

RewriteEngine on 
# If client accepts compressed files 
RewriteCond %{HTTP:Accept-Encoding} gzip 
# and if compressed file exists 
RewriteCond %{REQUEST_FILENAME}.gz -f 
# send .html.gz instead of .html 
RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2.gz [T=text/$2,E=GZIP:gzip,L] 
Header set Content-Encoding gzip env=GZIP 

リダイレクトは機能しています。game.htmlをリクエストして、実際にgame.html.gzを配信できます。ただし、ブラウザはそれを表示するだけではありません。代わりに、ファイルを保存する場所を尋ねられます。どうすれば修正できますか?それとも、私の目標を達成する別の方法がありますか?

20
marc40000

これは私が同じ問題を一度修正した方法です。

.htaccessに新しいタイプを追加します。

AddEncoding gzip .jsgz .cssgz .htmlgz .datagz
AddType application/javascript .jsgz
AddType text/css .cssgz
AddType text/html .htmlgz       
AddType text/plain .datagz

AddType命令が.html.gz形式の拡張子を受け入れなかったため、これはこの方法で行われました。

次に、書き換えルールを変更します。

RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2gz [L] 

そして最後にファイルの名前を変更します。 .html.gz、.js.gzなどからドットを削除します。

完全な.htaccessは次のようになります。

AddEncoding gzip .jsgz .cssgz .htmlgz .datagz
AddType application/x-javascript .jsgz
AddType text/css .cssgz
AddType text/html .htmlgz       
AddType text/plain .datagz

RewriteEngine on 
# If client accepts compressed files 
RewriteCond %{HTTP:Accept-Encoding} gzip 
# and if compressed file exists 
RewriteCond %{REQUEST_FILENAME}gz -f 
# send .html.gz instead of .html 
RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2gz [L] 
18
claustrofob

あなたが自分自身に尋ねるべき最初の質問は、これをすることに何か意味がありますか?これが原因で、CPU負荷やパフォーマンスの違いが高すぎることに気づきましたか?私の推測では、おそらくこの問題に遭遇していないでしょう:)

それでも、問題を解決するには複数の方法があります。

  1. おそらくあなたにとって最良の選択肢は、CDNを使用することです。これらは静的ファイルの高速配信用に設計されており、地理的に異なる地域の人々だけでなく、サーバーの近くにいる人々にとっても高速になります。また、私の経験では、CDNは通常、自分の帯域幅よりもはるかに安価です。

  2. Nginxを使用します。静的ファイルをはるかに高速にホストするために、現在行っているように静的コンテンツを事前に生成するためのサポートがあります。 .gzファイルがあるかどうかを自動的に検出し、必要に応じて代わりに提供します。

  3. mod_mem_cachemod_disk_cacheなどのApacheキャッシュメカニズムの1つを使用して、定期的に使用されるすべてのファイルがキャッシュにあることを確認します。チュートリアル: http://webdirect.no/linux/Apache-caching-with-gzip-enabled/

  4. その前にVarnishのようなキャッシュプロキシを使用します。これらのタイプのサーバーは、はるかにスマートなキャッシュメカニズムを備えており、実際に最も重要なファイルをキャッシュします。

ただし、現在のバージョンでは、次のような(テストされていない)ものでうまくいくはずです。

RewriteEngine On    
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.(html|css|js|data) $1\.$2\.gz [QSA]

# Prevent double gzip and give the correct mime-type
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=FORCE_GZIP]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=FORCE_GZIP]
RewriteRule \.html\.gz$ - [T=text/html,E=no-gzip:1,E=FORCE_GZIP]
RewriteRule \.data\.gz$ - [T=text/plain,E=no-gzip:1,E=FORCE_GZIP]

Header set Content-Encoding gzip env=FORCE_GZIP
10
Wolph

受け入れられた答えはかなり苦痛のようです。 Wolphの答え は良いようですが、ファイル拡張子ごとに個別の構成が必要であり、より高度なネゴシエーションのサポートがありません( q-valuesstatus 406[〜#〜] tcn [〜#〜] など)。 コンテンツネゴシエーション 自分でmod_rewriteを使用するのではなく、 この質問 で説明されているようにmod_negotiationの使用を検討することをお勧めします。コピー 私の答え そこから:

Options +MultiViews
RemoveType .gz
AddEncoding gzip .gz
<FilesMatch ".+\.tar\.gz$">
    RemoveEncoding .gz
    # Note:  Can use application/x-gzip for backwards-compatibility
    AddType application/gzip .gz
</FilesMatch>

これには、明示的に構成されたファイルだけでなく、すべての.gzファイルで機能し、 brotli または他のエンコーディングで簡単に拡張できるという追加のボーナスがあります。

存在しないファイルのリクエストのみがネゴシエートされるfoo.jsという名前のファイルがリクエストを行うため、これには1つの大きな欠点があります。 /foo.js(ただし、/fooではない)の場合、非圧縮バージョンを返します。これは、 FrançoisMarierのソリューション を使用して回避できます。つまり、圧縮されていないファイルの名前を二重拡張子で変更するため、foo.jsfoo.js.jsとしてデプロイされます。

7
Kevinoid

ここで概説されているソリューションについてはどうですか: http://feeding.cloud.geek.nz/posts/serving-pre-compressed-files-using/ 。 Apacheの組み込みMultiViewを使用します...

3
juicedM3