Django模板渲染速度

时间:2015-06-30 09:38:35

标签: python django django-templates

我在使用预取查询集渲染django模板时遇到性能问题并不是很大(生产环境中约1000个对象/开发环境中约200个对象)但是有几个嵌套级别。

这是预取:

stories = Story.objects.select_related(
            'commande',
            'commande__societe',
            'commande__plateforme',
            'client',).prefetch_related(
            Prefetch('crm_message_related',
                     queryset=Message.objects.select_related(
                         'societe',
                         'plateforme',
                         'type_message').order_by('-date_received')),
            Prefetch('commande__crm_feedback_related'),
            Prefetch('commande__crm_guarantee_related'),
            Prefetch('commande__soyouz_item_related',
                     queryset=Item.objects.select_related(
                         'etat', 'produit', 'produit__produit_enhanced', )),
            Prefetch('commande__tagged_items__tag'),
            Prefetch('commande__soyouz_item_related__tagged_items__tag'),
            Prefetch('commande__soyouz_item_related__soyouz_annulationclient_related'),
            Prefetch('commande__soyouz_item_related__soyouz_achat_related'),
            Prefetch('commande__soyouz_item_related__soyouz_achat_related__soyouz_receptionachat_related'),
            Prefetch('commande__soyouz_item_related__soyouz_achat_related__soyouz_annulationachat_related'),
            Prefetch('soyouz_action_related'),
            Prefetch('soyouz_action_related__receptionmessage__message',
                     to_attr='receptionmessages',
                     queryset=Message.objects.order_by(
                         '-date_received').select_related(
                         'societe', 'type_message', 'plateforme'))
        ).order_by(
            '-commande__date_commande',
            '-date_created'
        ).all().distinct()

SQL运行顺利,这不是问题。

问题是,当我尝试渲染我的模板时,女巫是基本的

{% for story in stories %}
    {% with items=story.commande.soyouz_item_related.all %}
    {% for item in items %}
        {% for tag in item.tagged_items.all %}
            <button>{{ tag.tag }}</button>
        {% endfor %}
        {{ item.titre|safe|truncatechars:50 }}
    {% endfor %}
{% endfor %}

在生产环境中显示页面大约需要10秒。

我使用django-template-timing(https://github.com/orf/django-debug-toolbar-template-timings)在我的开发环境中对其进行了分析,确实:

name            Times  Tot Time    Queries   Queries Time
stories.html    1      2814,1 ms   0         0 ms
对于具有200个数据的3个循环(在开发环境中),

3秒?看起来很多。

提高模板渲染速度的想法吗?

非常感谢!

2 个答案:

答案 0 :(得分:5)

虽然django-template-timing将渲染时间报告为2.8秒,但我怀疑大部分时间是在执行复杂的SQL查询时消耗的。

在Django,QuerySets are evaluated lazily。这意味着,您发布的语句Story.objects.select_related(...).distinct()不会在数据库中执行查询。 SQL被执行later。由于在渲染模板之前没有发布所有代码,我不确定QuerySet是否在渲染之前得到了evalueted。如果没有,则可以在模板中迭代stories时执行:

{% for story in stories %}

如果是这种情况,那么改进SQL可能会缩短时间。

您可以通过在呈现模板之前插入SQL来检查SQL执行是否是罪魁祸首:

stories = [story for story in stories]

此迭代获取在呈现之前执行的SQL。在此之后,如果django-template-timing报告的渲染时间要短得多,那么就知道SQL就是问题。

如果它确实是模板渲染性能问题,那么有一些替代方案:

  1. 使用性能更高的模板引擎,例如Jinja2。
  2. 使用Django模板可以提高渲染性能:https://stackoverflow.com/a/26592207/954376

答案 1 :(得分:0)

使用自定义标记并在模板外生成输出。这将有助于避免django模板开销。