September 7, 2023

Что делать для оптимизации приложения на Django и как ускорить его работу?

Оглавление

1 - Кеширование

2 - Сжатие

Кэширование

  • Используйте Redis или Memcached для кэширования запросов к БД, результатов вычислений, фрагментов шаблонов. Это избавит от повторных запросов к БД.
  • Кэшируйте также результаты работы вьюх. Например, с помощью django-cache-machine.
  • Настройте срок жизни кеша под конкретные данные.

Установка Redis или Memcached

Для начала нужно установить выбранный кеш с помощью pip:

pip install redis
# или
pip install pymemcache

Настройка кэша в settings.py

Далее необходимо настроить backend кэша и соединение с сервером в настройках Django:

# Для Redis
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"
        }
    }
}

# Для Memcached
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}

Кэширование запросов к БД

Чтобы кэшировать запросы к БД можно воспользоваться методом .cache() у QuerySet:

queryset = Posts.objects.all()
cached_posts = queryset.cache(timeout=60) python

Кэширование фрагментов шаблонов

Для этого в шаблоне используется тег cache:

{% load cache %}

{% cache 600 sidebar %}
   .. sidebar content .. 
{% endcache %}

Кэширование вьюх

Через декоратор @cache_page(timeout) можно кэшировать вьюхи целиком:

from django.views.decorators.cache import cache_page

@cache_page(60*15)
def my_view(request):
   ...

Настройка времени жизни кэша

Время жизни кэша указывается в секундах или можно использовать timedelta. Например, для кэширования на 15 минут:

Время кэширования нужно подбирать индивидуально для разных данных.

from datetime import timedelta  
@cache_page(timedelta(minutes=15))


Сжатие

  • Используйте в middleware сжатие с помощью gzip для уменьшения размера ответов сервера.
  • Сжимайте также статические файлы на стороне сервера.

Использование gzip сжатия в middleware

Чтобы включить сжатие ответов сервера с помощью gzip, нужно добавить в settings.py middleware:

MIDDLEWARE = [
    #...
    'django.middleware.gzip.GZipMiddleware',
    #...
]

Это прозрачно сожмет ответы сервера перед отправкой клиенту.

Настройка Nginx для сжатия статики

Чтобы сжимать статические файлы (css, js, изображения) на стороне Nginx, нужна такая конфигурация:

# Включаем gzip 
gzip on;

# Указываем типы сжимаемых файлов  
gzip_types text/plain text/css application/json application/javascript application/x-javascript image/svg+xml;

# Уровень сжатия от 1 до 9
gzip_comp_level 5;

Это позволит сократить размер файлов перед отправкой в браузер.

Сжатие файлов в Django

Также можно настроить сжатие статических файлов непосредственно в Django с помощью компрессоров:

# Сжатие CSS 
COMPRESS_CSS_FILTERS = [  
    'compressor.filters.css_default.CssAbsoluteFilter',
]

# Сжатие JavaScript
COMPRESS_JS_FILTERS = [  
    'compressor.filters.jsmin.JSMinFilter',
]

Это позволит минимизировать CSS и JS перед подготовкой к отправке браузеру


Асинхронность

  • Используйте асинхронные вьюхи, Celery для фоновых задач, чтобы ускорить выполнение.
  • Применяйте асинхронный веб-сервер, например Gunicorn с eventlet.