3

我正在尝试将 CSS 媒体查询与 Jinja 和 Flask 一起使用来确定设备类型并根据设备提供适当大小的图像。来自手机的请求将获得比台式机、平板电脑等更小的图像。

问题是{{ post|get_image(post, 480) }}独立于媒体查询进行评估,从而触发get_image每个实例的自定义模板过滤器。 get_image也是为设备呈现正确图像的地方,因此多次(可能是不必要的)调用会对性能产生负面影响。

理想情况下,一次调用只执行一个媒体查询get_image,但挑战在于媒体查询和 Jinja 完全相互独立,因为一个对另一个一无所知。

我非常感谢改进我的方法的替代方法或建议。提前致谢!

这是媒体查询的示例:

  @media only screen and (max-device-width: 480px) {
    .post {
      background: url("{{ post|get_image(post, 480) }}") no-repeat center center fixed; 
    }
  }

  @media only screen and (max-device-width: 1224px) {
    .post {
      background: url("{{ post|get_image(post, 1224) }}") no-repeat center center fixed; 
    }
  }
4

1 回答 1

1

将您的设置更改为如下所示:

.post {
    background: none no-repeat center center fixed;
}

@media only screen and (max-device-width: 480px) {
    .post {
      background-image: url("{{ get_image_url(post, 480) }}"); 
    }
}

@media only screen and (max-device-width: 1224px) {
    .post {
      background-image: url("{{ get_image_url(post, 1224) }}"); 
    }
}

您生成的 URL 可能如下所示:

/posts/<int:post_id>/background?s=NNNN

然后,设置您的代理服务器以从缓存目录中提供此类图像,并在图像不存在时将它们转发到图像生成控制器:

# Fake server configuration
# for no server known to man
location /posts/(:post-id:\d+)/background {
    try_files /cache/:post-id:_\d+\.png or @flask-server  
}

最后,在您的 Flask 控制器中生成图像,将其保存到您的缓存目录,然后将其返回给请求者:

@app.route("/posts/<int:post_id>/background")
def generate_image(post_id):
    # Assume that if we got here the image does not yet exist
    dimensions = int(request.args.get("s", 800), 10)

    image_data = generate_image(post_id, dimensions)

    image_name = "{}_{}.png".format(post_id, dimensions)
    image_path = os.path.join("/cache", image_name)

    with open(image_path, "wb") as image:
        image.write(image_data)

    return Response(image_data, content_type="image/png")

如果图像生成部分太昂贵,甚至无法考虑在控制器中执行,您可以改为返回 204 No-Content 并将 Cache-Control 设置为 private 和 Expires 设置为过去,并将图像生成任务放入进程外队列. 然后只需在您的 JavaScript 代码中轮询该端点,直到图像准备好由您的代理服务器提供。

于 2013-10-19T20:27:01.417 回答