使用 python 在 Heroku 上启用压缩

Enabling compression on Heroku using python

Google 现在由于对移动设备不友好而受到惩罚。因此,为了让事情变得更好,它建议我使用 Gzip 或 Deflate 压缩很多 Javascript。我看过一些关于堆栈溢出的旧建议,但没有开箱即用的东西,我尝试搜索附加组件,但到目前为止似乎还没有任何东西可以解决问题。什么是压缩或启用 gzip 最不痛苦和健壮的?

这是 Google 建议我做的:

启用压缩 使用 gzip 或 deflate 压缩资源可以减少通过网络发送的字节数。 为以下资源启用压缩以将其传输大小减少 420KiB(减少 74%)。

我正在使用 Django,如果这样更容易的话。

前面的底线 - 这将取决于您的应用程序的详细信息...Flask?姜戈? uWSGI? whitenoisegunicorn 似乎是 Heroku 上的 "go to" 框架,所以这就是我在下面的示例中使用的框架。它应该转化为其他框架。

说明 - Google 建议的要点是关于最小化从服务器物理传输的字节数。有几种方法可以做到这一点,但影响最大的方法,排名不分先后 -

  • 缩小 JavaScript 和 CSS
  • 将这些文件合并在一起
  • 操纵缓存行为
  • 压缩 HTTP 响应 body

引用的建议涉及最后一点,重要的是要了解压缩响应 body 是 HTTP 规范中 "content negotiation" 的一部分 - 浏览器不只是要求一个通过 URL 的特定资源;它还提供有关该资源的首选表示的提示,例如,内容类型、编码方式、能否以多个 "chunks" 等方式发送

因此,理想情况下,处理 HTTP 的应用程序层应该处理此特定任务。在典型的应用程序堆栈中,这意味着像 Apache 或 nginx 这样的 Web 服务器,其中 Web 服务器将代理对特定动态路径的请求到您的 Web 框架,并直接处理 "static" 内容。

然而,在 Heroku 中,HTTP 层在平台本身和您的应用程序之间分离 - "routing mesh" 充当反向代理,处理基本的 HTTP 和 HTTPS 并通过注入 headers 与代理信息,例如;其他一切都取决于您的应用程序。但是,您的 "app" 相当受限,因为您没有 free-reign 来安装 nginx 等

大多数 Web 框架(Django、Flask、Rails、Play! 等)都具有高度通用性,可以与外部 Web 服务器(推荐用于生产环境)协同工作,也可以独立工作,提供他们自己的,通常是轻量级的网络服务器(推荐用于开发)。这些框架还与 "containers" 很好地配对,既为应用程序提供了 run-time 环境,又为 HTTP 层(uWSGI、Gunicorn、Rack 等)提供了繁重的工作

这是 Heroku 的选择。尽管我对 uWSGI 的经验最多,但下面的示例是针对 Flask + Gunicorn + WhiteNoise(Python 中在 Heroku 上提供静态文件的首选库)。请注意,WhiteNoise 也适用于 Django,因此如果 Django 是您选择的框架,调整它应该是微不足道的。因此,所有这些说明都可以通过两个非常简单的步骤开始:

  • whitenoise 添加到您的 requirements.txt
  • 修改 WSGI 应用程序使 WhiteNoise "wrap" 您的应用程序。

例如:

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.

如果客户端发送 "Accept-Encoding: gzip" header,这将为您提供 gzip 压缩的内容。还有很多很多其他的杠杆和旋钮可以拉动和调整,但这是一个起点。最终,您会担心 CPU 开销并想要 pre-compress 文件;或者您可以决定 off-loading 静态文件是要走的路。

为了验证,使用cURL之类的工具抓取一个静态文件:

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

-i 标志应该打印出 headers,这将向您显示有关如何处理请求的详细信息。注意`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

希望这对您有所帮助...