首页 > 解决方案 > Django - 如何减少页面加载时间?获取 1000 个对象的列表并使用页面分页

问题描述

在我的 django 项目中,我的一个页面components.html需要大约 7-8 秒才能加载。在我components_view看来,我确实调用了所有对象(总数小于 2,000),然后使用页面分页在单个页面上仅显示 12 个组件,但是加载页面仍然需要 7-8 秒...

特别是如何减少此页面的加载时间 - 我认为页面分页会解决这个问题。我可以在用户访问主页时预加载数据吗?服务器是付费的 heroku 服务器。

视图.py

def components_view(request):
    # get objects from models
    subsystems          = Subsystem.objects.all()
    subsystems          = subsystems.order_by('name')
    component_types     = ComponentType.objects.all()
    components          = Component.objects.all()  # gets around 1500 objects
    form_factors        = FormFactor.objects.all()
    vendors             = Vendor.objects.order_by('name').all()  # gets 300 objects
    
    # page pagination
    COMPONENTS_PER_PAGE = 12
    component_paginator = Paginator(components, COMPONENTS_PER_PAGE)
    page_number = request.GET.get('page')
    page_components = component_paginator.get_page(page_number)

    context = {
        'subsystems': subsystems, 
        'component_types': component_types, 
        'components': page_components, 
        'form_factors': form_factors,
        'vendors': vendors,
        }

    return render(request, 'main/components.html', context)

额外的测试,看看它在哪里/为什么需要这么长时间:

页面组件大小 加载时间
使用分页器 61.9 KB ~7 到 8 秒
没有分页器 1.1 MB ~7 到 8 秒

使用页面分页器时,即使我没有将 1000 多个项目加载到 DOM,页面加载仍需要 7-8 秒。这也在付费的 Heroku 服务器上。

页面分页器的页面加载时间

在此处输入图像描述


附加信息:

class Component(models.Model):
    STATUS = (('In Production', 'In Production'), ('Retired', 'Retired'))

    # required inputs
    name                    = models.CharField(max_length=255, null=True)
    component_type          = models.ForeignKey(ComponentType, null=True, on_delete=models.SET_NULL)
    form_factor             = models.ForeignKey(FormFactor, null=True, on_delete=models.SET_NULL)
    vendor                  = models.ForeignKey(Vendor, null=True, on_delete=models.SET_NULL)
    slug                    = models.SlugField(unique=True)

    # optional inputs
    heritage                = models.BooleanField(max_length=255, null=True, default="")
    status                  = models.CharField(max_length=255, blank=True, choices=STATUS, null=True, )
    mass_dry                = models.FloatField(null=True, default=0, blank=True)
    power_average           = models.FloatField(null=True, default=0, blank=True)
    cost_min                = models.IntegerField(null=True, default=0, blank=True)
    cost_max                = models.IntegerField(null=True, default=0, blank=True)
    fiscal_year             = models.IntegerField(null=True, default=0, blank=True)
    lead_time_min_months    = models.IntegerField(null=True, default=0, blank=True)
    lead_time_max_months    = models.IntegerField(null=True, default=0, blank=True)
    description             = models.TextField(max_length=3000, null=True, blank=True)

    # files
    featured_image          = models.ImageField(max_length=255, null=True, blank=True, upload_to='temp/components')
    file_datasheet          = models.FileField(max_length=255, null=True, blank=True, upload_to='temp/components')
    file_icd                = models.FileField(max_length=255, null=True, blank=True, upload_to='temp/components')
    file_cad                = models.FileField(max_length=255, null=True, blank=True, upload_to='temp/components')

    show_component          = models.BooleanField(null=True, default=True)
    date_created            = models.DateTimeField(verbose_name="date_created", auto_now_add=True)
    date_modified           = models.DateTimeField(verbose_name="date_modified", auto_now=True)

    def get_absolute_url(self):
        return reverse("component:detail", kwargs={"slug": self.slug})

    def __str__(self):
        # this sets the name that is displayed in the django admin panel
        return self.name


class Vendor(models.Model):
    STATUS = (
        ('Active', 'Active'),
        ('Not Active', 'Not Active'),
        ('Unknown', 'Unknown'),
    )

    name            = models.CharField(max_length=255, null=True)
    website         = models.CharField(max_length=1020, null=True)
    contact_email   = models.CharField(max_length=255, null=True, blank=True)
    contact_phone   = models.CharField(max_length=255, null=True, blank=True)
    description     = models.TextField(max_length=3000, null=True, blank=True)
    year_founded    = models.IntegerField(null=True, blank=True)
    status          = models.CharField(max_length=255, null=True, blank=True, choices=STATUS)

    date_created    = models.DateTimeField(verbose_name="date_created", auto_now_add=True)
    date_modified   = models.DateTimeField(verbose_name="date_modified", auto_now=True)

    class Meta:
        ordering = ('name',)

    def __str__(self):
        # this sets the name that is displayed in the django admin panel
        return self.name

标签: djangoviewpagination

解决方案


推荐阅读