如何冲洗<;头>;早期使用Flask/Python/Jinja

如何冲洗<;头>;早期使用Flask/Python/Jinja,flask,jinja2,Flask,Jinja2,通过立即发送HTML响应的第一部分(例如,包含JS/CSS链接的。),同时计算响应的其余部分,可以使网站看起来快得多。(见附件) 在烧瓶里做这个的好方法是什么 我看到Flask支持streaming(),所以我认为这应该是可能的,但我想知道是否有人找到了一种干净的方法来将所有的片段缝合在一起。例如,如何构造Jinja模板,以便能够尽早提取/刷新文档片段?这并不完美,但我正在尝试以下方法。我有一个装饰师: def early_flush_of_head(template_name): de

通过立即发送HTML响应的第一部分(例如,包含JS/CSS链接的
),同时计算响应的其余部分,可以使网站看起来快得多。(见附件)

在烧瓶里做这个的好方法是什么


我看到Flask支持streaming(),所以我认为这应该是可能的,但我想知道是否有人找到了一种干净的方法来将所有的片段缝合在一起。例如,如何构造Jinja模板,以便能够尽早提取/刷新文档片段?

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

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)
{% 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 %}
{% 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 %}
每个template.html如下所示:

@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)
{% 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 %}
{% 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 %}
{%extends“base.html”%}
{%block pre_flush_head%}
{%endblock%}
{%block post\u flush\u head%}
{{page_name}}
{%endblock%}
{%block content%}
实际页面。
{%endblock%}
base.html如下所示:

@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)
{% 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 %}
{% 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 %}
{%if head_only%}
{%else%}
{%block post_flush_head%}{%endblock%}
{%block content%}{%endblock%}
{%endif%}
每个模板实际上渲染两次。在decorator中使用head_only=True,然后再次使用real view函数中未定义的值。还要注意的是,我没有刷新整个头部,头部中有一些东西,但仍然需要来自real view函数的数据。如果您是基于数据命名页面,那么Title就是一个很好的例子


这里有一些改进的空间(我不喜欢你必须两次输入模板的名称,总体来说有点麻烦),但它确实让你受益于早期刷新(确保你的部署环境不会在你不知情的情况下进行缓冲)。

刷新
显然没有多大用处。我说包括JS/CSS链接。