您可以通过立即发送HTML响应的第一部分(例如包含JS / CSS链接的<head>..</head>
)来使网站看起来更快,同时计算其余的响应。 (见http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/)
在Flask中执行此操作的好方法是什么?
我看到Flask支持流媒体(http://flask.pocoo.org/docs/0.10/patterns/streaming/),所以我认为它应该是可能的,但我想知道是否有人找到了一种干净的方法将所有部分拼接在一起。例如,如何构建Jinja模板以便可以提前提取/刷新文档片段?
答案 0 :(得分:0)
这并不完美,但我正在尝试以下方面。我有一个装饰师:
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,那么再次在实际视图函数中没有定义。还要注意,我没有冲洗整个头部,有一些东西在头部,但仍然需要来自真实视图功能的数据。如果您根据数据命名页面,标题就是一个很好的例子。
这里有一些改进空间(我不喜欢你必须将模板的名称放两次,而且它总体上有点干扰),但它确实可以让你获得早期冲洗的好处(make确保您的部署环境在您不知情的情况下不会缓冲。)