Django:即使使用缓存中的数据,模板加载也很慢

Posted

技术标签:

【中文标题】Django:即使使用缓存中的数据,模板加载也很慢【英文标题】:Django: template loading slowly even using data from cache 【发布时间】:2021-10-22 18:51:38 【问题描述】:

我有一个托管在 heroku 上的 django 应用程序,并且我有一个“家庭相册”页面,该页面加载了一组图像缩略图,这些缩略图链接到一个更大的图像详细信息页面。 (并且每个用户的图片集可能不同)。

每个缩略图都使用一个 image_link.html 模板。家庭相册页面上最多可以有大约 1100 个这样的缩略图,并且它在生产中加载非常好。

问题:现在我添加了一个小的悬停叠加层(从 w3schools here 获取),这样当您将鼠标悬停在缩略图上时,您可以看到图片包含的叠加层。此列表由 Image 类上的方法返回 - 它不是属性,因此不会与 Image 对象一起返回。

添加这使得模板加载速度非常慢:本地 4-5 秒,生产中约 22 秒(Heroku,使用 1 个专业 Dyno)。我认为通常这种事情会通过分页变得更好,但在这种情况下,我喜欢有一个长页面。 (虽然我可以先加载顶部,然后再填充其余部分)。

所以我做了一些事情:

在views.py 中添加了一个'get_image_index_data' 函数来循环,获取pictured_list 结果,用我需要的东西创建一个数组,然后缓存它。我在接收器函数中调用它(监听用户登录的信号),所以它会在用户点击家庭相册链接时设置,views.py 从缓存中获取它 我在家庭相册页面添加了模板片段缓存

问题:即使缓存了数据(并且我确认没有遗漏),这仍然可能加载缓慢(直到模板片段缓存开始?正在调查...)

代码如下:

我有一个调用此代码来保存数据的接收器函数:

def get_image_index_data(accessible_branches, profile):
    image_list = Image.objects.none()
    for branch in accessible_branches:
        name = branch.display_name
        image_list = image_list.union(Image.objects.filter(branches__display_name__contains=name).order_by('year'))
    sorted_list = image_list.order_by('year')

    # Save time on Family album page (aka image_index) by calling ahead for pictured_list. Elsewhere the template will retrieve it
    family_album_data = []

    for image in sorted_list:
        family_album_data.append([image, image.pictured_list])

    image_cache_name = 'images_' + str(profile.user)
    cache.set(image_cache_name, family_album_data, 60 * 30)  # save this for 30 minutes
    return family_album_data

然后是家庭相册的渲染函数:

@login_required(login_url=login_url)
def image_index(request):
    profile = get_display_profile(request).first()
    accessible_branches = get_valid_branches(request)

    image_cache_name = 'images_' + str(profile.user)
    family_album_data = cache.get(image_cache_name)
    if not family_album_data:
        family_album_data = get_image_index_data(accessible_branches, profile)

    context = 'image_list': family_album_data, 'accessible_branches': accessible_branches, 'branch2_name': branch2_name,
                'profile': profile, 'user_person': profile.person, 'media_server': media_server, 'user': profile.user
    return render(request, 'familytree/image_index.html', context)

这是家庭相册模板 (image_index.html):

% extends 'familytree/base.html' %
% block title % - family album% endblock title %
% block content %
% load cache %

% cache 1800 album profile %

<h1>Family Album</h1>
% if image_list %
    % for image in image_list %
        % include "familytree/image_link.html" with image=image height=150 show_hover=True pictured_list=pictured_list%
    % endfor %
% else %
    <p>No images are available.</p>
% endif %


% endcache %
% endblock content %

image_link.html(新位是 'if show_hover' 块中的覆盖范围):

    <div style="display: inline-block; margin-bottom:10px"; class="image_container">
    <a href="% url 'image_detail' image.id  %">
        %  if image.little_name %
            <img src=" media_server /image/upload/h_ height ,r_20/ image.little_name " class="image"/>
        %  else %
            <img src=" media_server /image/upload/h_ height ,r_20/ image.big_name " class="image"/>
        %  endif %

        % if show_hover %
            <span class="overlay">
                <span class="text">Pictured: pictured_list</span>
            </span>
        %  endif %

        <div style="padding-left: 8px">
        %  if image.year %
            ( image.year )
        %  endif %
        </div>
    </a>
</div>

【问题讨论】:

你使用像 celery 这样的任务队列吗?您可能可以在那里委派缓存构建,这样您的请求就不会被中断 but in this case I like having one long page -- 你也可以看看做一个类似facebook的无限滚动分页,给人一种你有一个长页面但仍在后台分页的错觉 谢谢!在用户登录后,我将缓存构建移动到接收器函数中,这使主页再次变得更快(呸)。无限滚动分页是个好主意-我会查一下! 谢谢,bdbd!我添加了带有 Waypoints 的无限滚动 - 随意变成一个答案,我会给它一个 *** 点的复选标记:) imakewebthings.com/waypoints/guides/getting-started 没问题!很高兴帮助:) 【参考方案1】:

一些建议:

    在后台进程处理程序(如celery)上委托缓存构建 如果你想显示一个长页面,看看做一个类似facebook的无限滚动分页,给人一种你有一个长页面但仍在后台分页的错觉。

【讨论】:

感谢您的帮助!!用户登录后,我将缓存构建移动到接收器函数中,这使主页再次变得更快。然后我结合使用他们的“入门”步骤和教程添加了带有 Waypoints 的无限滚动。现在一切都在快速加载! \o/

以上是关于Django:即使使用缓存中的数据,模板加载也很慢的主要内容,如果未能解决你的问题,请参考以下文章

具有百万条记录的表中的Count即使有parallel提示也很慢

Swift Dictionary 即使优化也很慢:做不必要的保留/释放?

即使没有任何更改,Android 多模块 Gradle 构建也很慢

带有缓存加载器的 Jinja2 与 django 模板 - 性能比较如何?

使用 PyCharm 分析 Django

无法加载 Django 模板