2013-06-02 4 views
19

У меня есть игра JavaScript, которая в основном состоит из файла .html и .data. Если я сжимаю их с помощью gzip, их размер уменьшается до 25%. Поэтому я хочу это сделать.Как разместить статический контент, предварительно сжатый в apache?

Я не уверен на 100%, но я думаю, что использование mod_gzip или mod_deflate делает сжатие «на лету», постоянно теряя время процессора, потому что контент не изменяется.

Так что я хотел бы прекомпилировать Контент. Поэтому я поставил .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 и фактически получить deliviered game.html.gz. Однако браузер не просто отображает его. Вместо этого он спрашивает, где сохранить файл. Как я могу это исправить? Или, может быть, есть еще один способ достичь моей цели?

+0

Кажется, что apache не уважает модификатор T. Какой тип контента возвращает сервер? – claustrofob

+0

Мне тяжело это узнать. Firebug не сообщает Content-type, когда ff хочет сохранить файл, или я не знаю, как его увидеть. – marc40000

ответ

16

Это, как я установил один раз та же самая проблема.

Добавить новые типы в .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] 
+0

Важно ли иметь расширения, названные так? Поскольку я попробовал ваше решение с заменой .htmlgz на .html.gz и так далее и снова, он просит сохранить файл, а не отображать его. – marc40000

+0

На самом деле это по-настоящему важно по какой-то причине. Если я переименую файлы .html.gz в .htmlgz и т. Д., Используйте ваш предлагаемый .htaccess. – marc40000

+2

Это решение действительно работает в прямом эфире уже несколько лет. Если AddType будет поддерживать сложные расширения, например .html.gz, вы не сможете переименовать файлы. – claustrofob

9

Первый вопрос, который вы должны задать себе, есть ли смысл в этом? Из-за этого вы заметили слишком высокую загрузку процессора и/или разницу в производительности? Я предполагаю, что вы, вероятно, не столкнулись с этой проблемой :)

Несмотря на это, существует несколько способов устранения проблемы.

  1. Возможно, лучший вариант для вас, используйте CDN. Они предназначены для быстрой доставки статических файлов и ускоряются для людей в другом географическом районе, а также для людей, находящихся рядом с вашим сервером. Кроме того, по моему опыту, CDN обычно намного дешевле, чем ваша собственная полоса пропускания.

  2. Использование Nginx. Для хостинга статических файлов намного быстрее и имеет поддержку для предварительного создания статического контента, как вы делаете прямо сейчас. Он автоматически определит, есть ли файл .gz и служит, если это необходимо.

  3. Используйте один из механизмов кэширования Apache, например mod_mem_cache или mod_disk_cache, чтобы убедиться, что каждый регулярно используемый файл будет находиться в кеше. Учебное пособие: 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 
+0

Интересные альтернативы, которые вы там пишете. Хотя nginx и лак, вероятно, не работают, поскольку у меня уже установлена ​​установка Apache и не хочу устанавливать все это для двух файлов. 1 или 3, кажется, интересны. Варианты для меня. Однако просто исправление .htaccess кажется самым быстрым вариантом для меня прямо сейчас. Я попробовал ваше предложение: он больше не просит сохранить файл, но он не распаковывает его перед отображением. Я вижу сжатый файл, много символов. Я тестировал в Firefox и Chrome. – marc40000

+0

Включение браузеров, вероятно, будет достаточно умным, чтобы сделать это правильно, но я действительно забыл передать кодировку. Я буду обновлять ответ :) – Wolph

+0

Я использую этот подобный метод, за исключением того, что я использую его в mod perl-скрипте, который выполняется перед любым CGI. Это позволяет мне также при необходимости извлекать файлы, зависящие от двигателя. то есть файл/file.js -> file.jscript.js.gz для файла file.gecko.js.gz для firefox, file.v8.js.gz для chrome или file.nitro.js.gz для сафари. Работает так же с CSS, но его основано на рендерере вместо js engine, trident, т. Е. Gecko для firefox, webkit для хрома и сафари. Если он не может найти конкретный браузер, он использует файл по умолчанию file.js.gz. Он также учитывает версии программного обеспечения для клиентов. – Rahly

6

Принимаемый ответ кажется довольно болезненным. Wolph's answer кажется лучше, но по-прежнему требуется отдельная конфигурация для каждого расширения файла и отсутствует поддержка более продвинутых переговоров (q-values, status 406, TCN и т. Д.). Вместо того, чтобы выполнять content negotiation самостоятельно, используя mod_rewrite, вы можете рассмотреть возможность использования mod_negotiation, как описано в this question. Копирование my answer оттуда:

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 или других кодировок.

У него есть один существенный недостаток, так как only requests for files which do not exist are negotiated файл с именем foo.js будет делать запросы на /foo.js (но не /foo) возвращает несжатую версию. Этого можно избежать с помощью François Marier's solution переименования несжатых файлов с двойным расширением, поэтому foo.js развернут как foo.js.js.

 Смежные вопросы

  • Нет связанных вопросов^_^