Django Template Rendering Speed

I have a performance problem when rendering a django template with a prefetch fetch request that is not very large (~ 1000 objects in the production environment / ~ 200 objects in the development environment), but has several levels of nesting.

Here is the prefetch:

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 runs smoothly, this is not a problem.

The problem is that I am trying to make my template very simple.

 {% 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 %} 

It takes about 10 seconds to display a page in a production environment.

I profiled it in my development environment with django-template-timing ( https://github.com/orf/django-debug-toolbar-template-timings ) and really:

 name Times Tot Time Queries Queries Time stories.html 1 2814,1 ms 0 0 ms 

3 seconds for 3 cycles with 200 data (in development environment)? It seems a lot.

Any ideas on improving the speed of rendering templates?

Thanks a lot!

+5
source share
2 answers

Although django-template-timing reports that the rendering time is 2.8 s, I suspect that most of the time is consumed when executing a complex SQL query.

In Django, QuerySets are evaluated lazily . This means that you sent a message to Story.objects.select_related(...).distinct() does NOT execute the query in the database. SQL will be executed later . Since you did not submit all the code before rendering the template, I am not sure if QuerySet gets an estimate before rendering. If not, this can be done by repeating stories in the template:

 {% for story in stories %} 

If so, then possibly improving your SQL can shorten the time.

You can check if SQL execution is the culprit by pasting this before displaying the template:

 stories = [story for story in stories] 

This iteration runs SQL before rendering. After that, if django-template-timing reports a much shorter rendering time, you know the SQL problem.

If this is a template rendering performance issue, there are several alternatives:

+5
source

Use your own tag and generate output outside the template. This will help avoid the overhead of the django template.

0
source

All Articles