【问题标题】:How to flush <head> early with Flask / Python / Jinja如何使用 Flask / Python / Jinja 及早刷新 <head>
【发布时间】:2014-11-26 23:18:49
【问题描述】:

您可以通过立即发送 HTML 响应的第一部分(例如,包含 JS/CSS 链接的 &lt;head&gt;..&lt;/head&gt;)来使网站看起来更快,同时计算响应的其余部分。 (见http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/

在 Flask 中有什么好的方法来做到这一点?

我看到 Flask 支持流式传输 (http://flask.pocoo.org/docs/0.10/patterns/streaming/),所以我认为这应该是可能的,但我想知道是否有人找到了一种将所有部分拼接在一起的干净方法。例如,您如何构建 Jinja 模板以便尽早提取/刷新文档片段?

【问题讨论】:

  • Flushing &lt;head&gt; 只是用处不大...
  • 显然。我说包括 JS/CSS 链接。

标签: flask jinja2


【解决方案1】:

这并不完美,但我正在尝试以下方法。我有一个装饰器:

def early_flush_of_head(template_name):
    def wrapper(original_view_function):

        @wraps(original_view_function)
        def new_view_function(*args, **kwargs):
            def streamer():
                yield render_template(template_name, head_only=True)
                yield original_view_function(*args, **kwargs)

            return Response(stream_with_context(streamer()))
        return new_view_function
    return wrapper

您可以使用它来装饰给定的视图,如下所示:

@app.route('/')
@early_flush_of_head('template.html')
def index():
    data = something_time_consuming()  # DB traffic or maybe some crazy calculations

    return render_template('template.html', data=data)

每个 template.html 看起来像这样:

{% extends "base.html" %}

{% block pre_flush_head %}
    <link href="static/css/page.min.css" rel="stylesheet">
    <script src="static/js/page.min.js"></script>
{% endblock %}

{% block post_flush_head %}
    <title>{{ page_name }}</title>
{% endblock %}

{% block content %}
    The actual page.
{% endblock %}

base.html 看起来像这样:

{% if head_only %}
<!DOCTYPE html>
<html lang="en">
<head>
        <link href="static/css/common.min.css" rel="stylesheet">
        <script src="static/js/common.min.js"></script>
{% else %}
    {% block post_flush_head %}{% endblock %}
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>
{% endif %}

每个模板实际上被渲染两次。一次在 head_only=True 的装饰器中,然后在真实视图函数中再次没有定义。另请注意,我没有冲洗整个头部,头部有一些东西但仍然需要来自真实视图功能的数据。如果您根据数据命名页面,标题就是一个很好的例子。

这里有一些改进的余地(我不喜欢你必须两次输入模板的名称,这总体上有点侵入性),但它确实让你受益于提前冲洗(使确保您的部署环境不会在您不知情的情况下缓冲)。

【讨论】:

    猜你喜欢
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多