Включение сжатия на Heroku с помощью python

Google теперь наказывает из-за того, что он не так удобен для мобильных устройств. Поэтому, чтобы улучшить ситуацию, он рекомендует сжимать большую часть моего Javascript с помощью Gzip или Deflate. Я видел несколько старых рекомендаций по переполнению стека, но там нет ничего готового, и я попытался найти надстройки, но пока не нашел ничего, что помогло бы. Что является наименее болезненным и надежным из сжатия или включения gzip?

Вот что Google предлагает мне сделать:

Включить сжатие Сжатие ресурсов с помощью gzip или deflate может уменьшить количество байтов, отправляемых по сети. Включите сжатие для следующих ресурсов, чтобы уменьшить размер их передачи на 420 КБ (уменьшение на 74 %).

Я использую Django, если это упрощает задачу.


person disruptive    schedule 17.05.2015    source источник


Ответы (1)


Практический результат. Это будет зависеть от деталей вашего приложения... Flask? Джанго? uWSGI? whitenoise и gunicorn кажутся "переходными" фреймворками на Heroku, поэтому я использовал их в приведенном ниже примере. Это должно быть переведено на другие фреймворки.

Объяснение. Суть рекомендации Google заключается в минимизации количества байтов, физически передаваемых с сервера. Есть несколько способов сделать это, но среди наиболее эффективных, в произвольном порядке -

  • Минимизируйте JavaScript и CSS
  • Объедините эти файлы вместе
  • Управление поведением кэша
  • Сжать тело ответа HTTP

Приведенная рекомендация относится к этому последнему моменту, и важно понимать, что сжатие тела ответа является частью «согласования контента» в спецификации HTTP — браузер не просто запрашивает конкретный ресурс через URL-адрес; он также предоставляет подсказки о предпочтительном представлении этого ресурса, например, какой тип контента, как он закодирован, может ли он быть отправлен несколькими «фрагментами» и т. д.

Таким образом, в идеале эту конкретную задачу должен выполнять уровень приложения, который обрабатывает HTTP. В типичном стеке приложений это будет означать веб-сервер, такой как Apache или nginx, в котором веб-сервер будет проксировать запросы на определенные динамические пути к вашей веб-инфраструктуре и напрямую обрабатывать «статический» контент.

Однако в Heroku уровень HTTP разделен между самой платформой и вашим приложением — «сетка маршрутизации» действует как обратный прокси-сервер, обрабатывая базовые HTTP и HTTPS и улучшая запросы, например, вводя заголовки с информацией о прокси-сервере; все остальное зависит от вашего приложения. Однако ваше «приложение» довольно ограничено, поскольку у вас нет права на установку nginx и т. д.

Большинство веб-фреймворков (Django, Flask, Rails, Play! и т. д. и т. д.) являются весьма обобщенными и могут работать совместно с внешним веб-сервером (рекомендуется для производства) или могут работать независимо, предоставляя свои собственные, обычно легковесные веб-серверы. (рекомендуется к разработке). Фреймворки также хорошо сочетаются с «контейнерами», которые обеспечивают как среду выполнения для приложения, так и тяжелую работу на уровне HTTP (uWSGI, Gunicorn, Rack и т. д.).

Это вариант, который можно использовать с Heroku. Хотя у меня больше всего опыта работы с uWSGI, приведенный ниже пример относится к Flask + Gunicorn + WhiteNoise (предпочтительная библиотека для обслуживания статических файлов на Heroku в Python). Обратите внимание, что WhiteNoise также работает с Django, поэтому его адаптация должна быть тривиальной, если вы выбрали Django. Итак, все это изложение приводит к двум довольно простым шагам для начала:

  • Добавьте whitenoise к своему requirements.txt
  • Измените приложение WSGI, чтобы WhiteNoise «обертывал» ваше приложение.

Например:

from flask import Flask
from whitenoise import WhiteNoise

flapp = Flask(__name__)
#use a subdirectory for root, otherwise, the actual .py files can be served...
app = WhiteNoise(flap, root='./static/')

#define your routes:
@flapp.route('/')
def home_page():
    #etc. etc.

Это даст вам gzip-контент, если клиент отправит заголовок «Accept-Encoding: gzip». Есть много, много других рычагов и ручек, которые нужно тянуть и настраивать, но это отправная точка. В конце концов, вы будете беспокоиться о нагрузке на ЦП и захотите предварительно сжать файлы; или вы можете решить, что лучше всего разгрузить статические файлы.

Чтобы проверить, используйте такой инструмент, как cURL, чтобы получить статический файл:

curl -i -H "Accept-Encoding: gzip" http://yourapp.herokuapp.com/path/to/static

Флаг -i должен выводить заголовки, которые покажут вам подробности того, как был обслужен запрос. Обратите внимание на `Content-Encoding

HTTP/1.1 200 OK
Connection: keep-alive
Server: gunicorn/19.3.0
Date: Wed, 20 May 2015 15:33:35 GMT
Last-Modified: Wed, 20 May 2015 15:26:06 GMT
Content-Type: text/html; charset="utf-8"
Cache-Control: public, max-age=60
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 662
Via: 1.1 vegur

Надеюсь это поможет...

person bimsapi    schedule 20.05.2015
comment
Отличный ответ. WhiteNoise кажется отличной идеей — предоставление лучших практик, не полагаясь на конфигурацию, которая может быть не в ваших руках или (в моем случае) за пределами вашего опыта. - person bsa; 22.05.2015