Как разместить статический контент, предварительно сжатый в apache?
У меня есть игра JavaScript, которая в основном состоит из файла .html и .data. Если я сжимаю их с помощью gzip, их размер уменьшается до 25%. Поэтому я хочу это сделать.
Я не уверен на 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
Redirect работает, я могу запросить game.html и получить deliviered game.html.gz. Однако браузер не просто отображает его. Вместо этого он спрашивает, где сохранить файл. Как я могу это исправить? Или, может быть, есть еще один способ достичь моей цели?
Ответы
Ответ 1
Вот как я исправил одну и ту же проблему.
Добавить новые типы в .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]
Ответ 2
Первый вопрос, который вы должны задать себе, есть ли смысл в этом? Из-за этого вы заметили слишком высокую загрузку процессора и/или разницу в производительности? Я предполагаю, что вы, вероятно, не столкнулись с этой проблемой:)
Несмотря на это, существует несколько способов устранения вашей проблемы.
-
Вероятно, лучший вариант для вас, используйте CDN. Они предназначены для быстрой доставки статических файлов и ускоряются для людей в другом географическом районе, а также для людей, находящихся рядом с вашим сервером. Кроме того, по моему опыту CDN обычно намного дешевле, чем ваша собственная полоса пропускания.
-
Используйте Nginx. Для более быстрого размещения статических файлов намного и имеет поддержку предварительного создания статического контента, как вы делаете прямо сейчас. Он автоматически определит, есть ли файл .gz
и служит, если это необходимо,
-
Используйте один из механизмов кэширования Apache, например mod_mem_cache
или mod_disk_cache
, чтобы каждый регулярно используемый файл находился в кеше. Учебник: http://webdirect.no/linux/apache-caching-with-gzip-enabled/
-
Используйте прокси-сервер кэширования, такой как Varnish перед этим, эти типы серверов имеют гораздо более умный механизм кэширования и фактически кэшируют файлы, которые наиболее важны.
Для вашей текущей версии, однако, что-то вроде этого (untested) должно сделать трюк:
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
Ответ 3
Принятый ответ кажется довольно болезненным. Ответ на Wolph кажется лучше, но по-прежнему требуется отдельная настройка для каждого расширения файла и отсутствует поддержка более продвинутых переговоров (q-values , статус 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 или другие кодировки.
У него есть один главный недостаток, так как обсуждаются только запросы на файлы, которые не существуют файл named foo.js
выполнил бы запросы для /foo.js
(но не /foo
), чтобы вернуть несжатую версию. Этого можно избежать, используя решение François Marier о переименовании несжатых файлов с двойным расширением, поэтому foo.js
используется как foo.js.js
.
Ответ 4
Как насчет решения, описанного здесь: http://feeding.cloud.geek.nz/posts/serving-pre-compressed-files-using/. Используйте встроенные MultiViews Apache...