jinja2模板渲染需要10多秒,如何优化?
jinja2 template takes over 10 secs to render, how to optimize?
在我的 flask web 应用程序中,有一条路线显示所有名字以 'A, B, C, etc..' 开头的成员,或者显示所有已注册成员的显示全部按钮。现在它总共有大约 750 个用户。问题是显示 'show all' 列表需要超过 10 秒。对数据库本身的请求很快,渲染花费了所有这些秒。我想知道是否有办法加快速度?我是 python、flask 和 jinja2 的新手,所以我还不知道优化路径。
这里是 views.py,当我点击网页上的“全部显示”按钮时,它会调用 url 并将字母参数设置为“0”:
@main.route('/all-members')
@login_required
@admin_required
def all_members():
alphabet = list(string.ascii_lowercase)
first_letter = request.args.get('letter')
if first_letter == '0':
user_ = User.query.order_by(User.fullname.asc()).all()
else:
user_ = User.query.filter(User.username.startswith(first_letter)).order_by(User.fullname.asc()).all()
return render_template('all_members.html', all_members = user_, alphabet = alphabet)
它return 750 个用户对象。然后我将该结果传递给模板:
return render_template('all_members.html', all_members = user_, alphabet = alphabet)
和模板:
{% extends "base.html" %}
{% block title %}Zata - members list{% endblock %}
{% block page_content %}
<div class="page-header" xmlns="http://www.w3.org/1999/html">
<h1>Tribe members list</h1>
<p></p>
{% for letter in alphabet %}
<a class="btn btn-success" href="{{ url_for('.all_members', letter = letter) }}">{{ letter }}</a>
{% endfor %}
<a class="btn btn-info" href="{{ url_for('.all_members', letter = 0) }}">Show All</a>
</div>
{% for member in all_members %}
<div class="row">
<p>
<div class="col-md-2">
<a href="{{ url_for('main.member',username=member.username) }}">{{ member.fullname }}</a>
</div>
<div class="col-md-1">
<a class="btn btn-warning btn-xs" href="{{ url_for('.edit_profile_admin', id=member.id) }}"> Edit Profile</a>
</div>
<div class="col-md-3">
<a class="btn btn-info btn-xs" href="{{ url_for('.add_punchcard', id=member.id, next=request.url) }}"> Manage Punchcard</a>
{% if member.punchcard_gold %}<span class="btn btn-xs" style="background-color:gold">G:{{ member.punchcard_gold }}</span>{% endif %}
{% if member.punchcard_normal %}<span class="btn btn-xs" style="background-color:#c0c0c0">R:{{ member.punchcard_normal }}</span>{% endif %}
</div>
<div class="col-md-4">
<a class="btn btn-info btn-xs" href="{{ url_for('.add_seasonpass', id=member.id, next=request.url) }}"> Manage Season pass</a>
{% if member.season_pass_gold %}<span class="btn btn-xs" style="background-color:gold">G:{{ member.season_pass_gold }}</span>{% endif %}
{% if member.season_pass_normal %}<span class="btn btn-xs" style="background-color:#c0c0c0">R:{{ member.season_pass_normal }}</span>{% endif %}
</div>
<div class="col-md-2">
<span class="btn btn-xs" style="background-color:yellowgreen">Class attended: {{ member.class_attended|length }}
</div>
</p>
</div>
{% endfor %}
{% endblock %}
缓慢的部分显然是 {% for member in all_members %} 但是否有另一种方法来遍历用户列表并构建页面?
问题不在于您的 Jinja 模板,而在于您的 Python 代码。您同时返回所有记录,这会减慢执行速度。您需要执行某种 pagination/lazy 加载。如果您使用的是 Flask-SQLAlchemy,那么它有一个分页方法可以为您完成所有工作。例如,您的查询看起来像这样
user_ = User.query.order_by(User.fullname.asc()).paginate(1, 10, True)
您可以找到更多信息here
在我的 flask web 应用程序中,有一条路线显示所有名字以 'A, B, C, etc..' 开头的成员,或者显示所有已注册成员的显示全部按钮。现在它总共有大约 750 个用户。问题是显示 'show all' 列表需要超过 10 秒。对数据库本身的请求很快,渲染花费了所有这些秒。我想知道是否有办法加快速度?我是 python、flask 和 jinja2 的新手,所以我还不知道优化路径。
这里是 views.py,当我点击网页上的“全部显示”按钮时,它会调用 url 并将字母参数设置为“0”:
@main.route('/all-members')
@login_required
@admin_required
def all_members():
alphabet = list(string.ascii_lowercase)
first_letter = request.args.get('letter')
if first_letter == '0':
user_ = User.query.order_by(User.fullname.asc()).all()
else:
user_ = User.query.filter(User.username.startswith(first_letter)).order_by(User.fullname.asc()).all()
return render_template('all_members.html', all_members = user_, alphabet = alphabet)
它return 750 个用户对象。然后我将该结果传递给模板:
return render_template('all_members.html', all_members = user_, alphabet = alphabet)
和模板:
{% extends "base.html" %}
{% block title %}Zata - members list{% endblock %}
{% block page_content %}
<div class="page-header" xmlns="http://www.w3.org/1999/html">
<h1>Tribe members list</h1>
<p></p>
{% for letter in alphabet %}
<a class="btn btn-success" href="{{ url_for('.all_members', letter = letter) }}">{{ letter }}</a>
{% endfor %}
<a class="btn btn-info" href="{{ url_for('.all_members', letter = 0) }}">Show All</a>
</div>
{% for member in all_members %}
<div class="row">
<p>
<div class="col-md-2">
<a href="{{ url_for('main.member',username=member.username) }}">{{ member.fullname }}</a>
</div>
<div class="col-md-1">
<a class="btn btn-warning btn-xs" href="{{ url_for('.edit_profile_admin', id=member.id) }}"> Edit Profile</a>
</div>
<div class="col-md-3">
<a class="btn btn-info btn-xs" href="{{ url_for('.add_punchcard', id=member.id, next=request.url) }}"> Manage Punchcard</a>
{% if member.punchcard_gold %}<span class="btn btn-xs" style="background-color:gold">G:{{ member.punchcard_gold }}</span>{% endif %}
{% if member.punchcard_normal %}<span class="btn btn-xs" style="background-color:#c0c0c0">R:{{ member.punchcard_normal }}</span>{% endif %}
</div>
<div class="col-md-4">
<a class="btn btn-info btn-xs" href="{{ url_for('.add_seasonpass', id=member.id, next=request.url) }}"> Manage Season pass</a>
{% if member.season_pass_gold %}<span class="btn btn-xs" style="background-color:gold">G:{{ member.season_pass_gold }}</span>{% endif %}
{% if member.season_pass_normal %}<span class="btn btn-xs" style="background-color:#c0c0c0">R:{{ member.season_pass_normal }}</span>{% endif %}
</div>
<div class="col-md-2">
<span class="btn btn-xs" style="background-color:yellowgreen">Class attended: {{ member.class_attended|length }}
</div>
</p>
</div>
{% endfor %}
{% endblock %}
缓慢的部分显然是 {% for member in all_members %} 但是否有另一种方法来遍历用户列表并构建页面?
问题不在于您的 Jinja 模板,而在于您的 Python 代码。您同时返回所有记录,这会减慢执行速度。您需要执行某种 pagination/lazy 加载。如果您使用的是 Flask-SQLAlchemy,那么它有一个分页方法可以为您完成所有工作。例如,您的查询看起来像这样
user_ = User.query.order_by(User.fullname.asc()).paginate(1, 10, True)
您可以找到更多信息here