Django — Как уменьшить время загрузки страницы? Получение списка из 1000 объектов и использование разбивки на страницы

#django #view #pagination

Вопрос:

В моем проекте django загрузка одной из моих страниц components.html занимает около 7-8 секунд. На мой components_view взгляд, я выполняю вызовы, чтобы получить все объекты (общее количество меньше 2000), а затем использую разбиение страниц на страницы, чтобы отображать только 12 компонентов на одной странице, однако загрузка страницы по-прежнему занимает 7-8 секунд…

Как я могу уменьшить время загрузки этой страницы, в частности — я думал, что разбиение на страницы решило бы эту проблему. Могу ли я предварительно загрузить данные, когда пользователь переходит на домашнюю страницу? Сервер-это платный сервер heroku.

views.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 кБ ~7-8 сек
Без Пагинатора Страниц 1.1 МБ ~7-8 сек

При использовании page paginator, даже если я не загружаю более 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
 

Комментарии:

1. Скорее order_by всего, как это часто бывает дорого. Вы также можете изучить возможность использования классов ListView и использования Djangos, встроенных в функцию «paginate_by».

2. @Anthony являются ли классы ListView менее дорогими? Все order_by еще облагается налогом/дорого, если он живет в классе?