我正在渲染一个模板,它需要 2-3 秒的时间来完成。页面上有很多元素(10k 个复选框会改变每个查询),我想知道是否有人知道任何有用的技巧来减少加载时间。
网站链接:http://18.207.127.123/search/
仅供参考:此应用程序中没有 Django 表单或表单集! :-) 我正在处理名为 Lemmas 的对象,这些对象将 Forms 作为他们的孩子......如果这引起混淆,抱歉。
无论需要多长时间,它都在这里:
<li class="form-item" data-lemma="{{lemma.id}}" data-group="{{group}}" style="display:none">
<input type="checkbox" name="{{lemma.name}}@{{lemma.latin}}@{{lemma.homonym_id}}@{{group}}@{{form}}" onchange="countCheckboxes(this)" id="{{lemma.id}}@{{group}}@{{form}}" checked>
<label for="{{lemma.id}}@{{group}}@{{form}}">{{ form }}</label>
</li>
点方法会减慢速度吗?
显然,对 10k 项中的每一项进行的所有 {{ var }}
调用都需要花费这么长时间。每个花费约 50-200 毫秒。
autoescape
关闭<input id="x"...
<label for="x">
可以替换为
<label>
<input ...>
</label>
保存六个变量调用。
添加
{% autoescape off %}
# body text
{% endautoescape %}
消除了使每个变量安全的需要。
这两个变化使渲染时间减少了大约 50%。
在检查了我的 django connections
并进行了分析之后,据我所知,我只进行了两次数据库调用。
我的数据结构是一个字典,看起来像:
results_dict = { LemmaObj1 : [form11, form12, form13, ...],
LemmaObj2 : [form21, form22, form33, ...],
...
其中 LemmaObj
是 Queryset
对象。生成这个 dict 只需要 0.5
秒。我通过将 formij
放入列表推导式中来强制对惰性查询集进行评估。
views.py
lemma_qs = Lemma.objects.prefetch_related('form_set')
# ...
# some logic goes here
# ...
for lemma in lemma_qs:
form_qs = lemma.form_set.all()
form_list = [form.name for form in form_qs if some_condition(form)]
if form_list:
results_dict[lemma] = form_list
context['results_dict'] = results_dict
return render(request, "query.html", context)
所有这些都是说我很确定减速不是来自数据库命中。
在我的 query.html
中,我有两个 for 循环。
query.html
<div class="lemma-box">
<ol>
<li class="lemma-title">
<div class="lemma-col-1">
lemma [{{results_dict|length}}] (group {{group}})
</div>
<div class="lemma-col-2">
latin
</div>
<div class="lemma-col-3">
homonym id.
</div>
<div class="lemma-col-4">
<input type="button" class="pushable" value="all" onclick="checkAllLemmas('{{group}}', true)"></input>
<input type="button" class="pushable" value="none" onclick="checkAllLemmas('{{group}}', false)"></input>
</div>
</li>
{% for lemma, form_list in results_dict.items %}
<li class="lemma-item" data-lemma="{{lemma.id}}" data-group="{{group}}" onclick="activateLemma(this)">
<div class="lemma-col-1">
<input type="checkbox" onchange="countCheckboxes(this)" onclick="lemmaToggleAll(this)" id="{{lemma.id}}@{{group}}" checked></input>
<label for="{{lemma.id}}@{{group}}">
{{ lemma.name }}
</label>
</div>
<div class="lemma-col-2">
{{ lemma.latin }}
</div>
<div class="lemma-col-3">
{{ lemma.homonym_id }}
</div>
<div class="lemma-col-4">
{% with form_list|length as total %}
<span class="counter">(<span class="total">{{ total }}</span>/<span>{{ total }}</span>)</span>
{% endwith %}
</div>
</li>
{% endfor %}
{% for item in not_found_items_set %}
<li class="lemma-item-not-found">
{{ item }} not found
</li>
{% endfor %}
</ol>
</div>
<div class="form-box">
<ol>
<li class="form-title">
<div class="form-col-1">
forms (group {{group}})
</div>
<div class="form-col-2" data-group="{{group}}">
<input type="button" class="pushable" value="all" onclick="checkAllForms('{{group}}', true)"></input>
<input type="button" class="pushable" value="none" onclick="checkAllForms('{{group}}', false)"></input>
</div>
</li>
{% for lemma, form_list in results_dict.items %}
{% for form in form_list %}
<li class="form-item" data-lemma="{{lemma.id}}" data-group="{{group}}" style="display:none">
<input type="checkbox" name="{{lemma.name}}@{{lemma.latin}}@{{lemma.homonym_id}}@{{group}}@{{form}}" onchange="countCheckboxes(this)" id="{{lemma.id}}@{{group}}@{{form}}" checked>
<label for="{{lemma.id}}@{{group}}@{{form}}">{{ form }}</label>
</li>
{% endfor %}
{% endfor %}
</ol>
</div>
这和我要得到的一样快吗?
我通过将 jinja2
转换为 query.html
来简单地尝试 query.jinja
,它似乎几乎没有任何区别。我是否需要额外的步骤来利用 jinja2?
最后,为了检查,我的models.py
。
models.py
class Form(models.Model):
name = models.CharField(max_length=100, db_index = True)
lemma = models.ForeignKey("Lemma", on_delete = models.CASCADE)
def __str__(self):
return self.name
class Lemma(models.Model):
name = models.CharField(max_length=100, db_index = True)
latin = models.CharField(max_length=100, db_index = True, blank = True, null = True)
homonym_id = models.IntegerField(null = True)
def __str__(self):
return self.name
答案 0 :(得分:0)
<input id="x"...
<label for="x">
被替换为
<label>
<input ...>
</label>
并保存一系列模板标签。
{% autoescape off %}
# body text
{% endautoescape %}
我现在要寻找解决方案 (3)。