Декоратор gzip_page
Декоратор gzip_page применяется к представлениям и автоматически сжимает
HTTP-ответы с использованием алгоритма gzip, если клиент поддерживает
этот метод сжатия. Декоратор проверяет заголовок Accept-Encoding
запроса и, если в нём присутствует значение gzip, сжимает содержимое
ответа. Это позволяет значительно уменьшить объём передаваемых данных,
особенно для больших HTML-страниц, JSON-ответов или статических файлов.
Декоратор не сжимает ответы, размер которых меньше 200 байт, а также
ответы, которые уже были сжаты.
Синтаксис
from django.views.decorators.gzip import gzip_page
@gzip_page
def my_view(request):
# Код представления
return render(request, 'template.html')
Параметры
Декоратор gzip_page не принимает никаких аргументов.
Он применяется к функции представления и автоматически
обрабатывает сжатие ответа при выполнении определённых условий.
Пример . С обычным представлением
Применим декоратор gzip_page к представлению,
которое возвращает большую HTML-страницу:
from django.views.decorators.gzip import gzip_page
from django.shortcuts import render
@gzip_page
def large_page_view(request):
context = {
'content': 'Большой текст...' * 1000,
}
return render(request, 'large_page.html', context)
Теперь при обращении к этому представлению, если браузер поддерживает gzip, ответ будет автоматически сжат:
# Заголовки запроса браузера:
"Accept-Encoding: gzip, deflate"
# Заголовки ответа сервера:
"Content-Encoding: gzip"
"Content-Length: 1523" # Сжатый размер
Пример . С классом-представлением
Декоратор можно применить к классу-представлению
с помощью метода dispatch или декоратора method_decorator:
from django.views.decorators.gzip import gzip_page
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
@method_decorator(gzip_page, name='dispatch')
class LargePageView(TemplateView):
template_name = 'large_page.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content'] = 'Большой текст...' * 1000
return context
Пример . С JSON-ответом
Сжатие особенно эффективно для JSON-данных, которые содержат повторяющиеся структуры:
from django.views.decorators.gzip import gzip_page
from django.http import JsonResponse
@gzip_page
def json_data_view(request):
data = {
'users': [
{'id': i, 'name': f'User_{i}', 'email': f'user_{i}@example.com'}
for i in range(1000)
]
}
return JsonResponse(data)
Результат выполнения кода:
# Обычный размер ответа: 98765 байт
# Сжатый размер ответа: 12345 байт
"Экономия трафика: 87.5%"
Ограничения декоратора
Декоратор gzip_page имеет следующие ограничения:
Не сжимает ответы размером менее 200 байт, так как
накладные расходы на сжатие могут превышать выгоду:
from django.views.decorators.gzip import gzip_page
from django.http import HttpResponse
@gzip_page
def small_page_view(request):
# Ответ меньше 200 байт, сжатие не будет применено
return HttpResponse("<p>Hello</p>")
Не сжимает ответы, которые уже имеют заголовок
Content-Encoding или являются потоковыми:
from django.views.decorators.gzip import gzip_page
from django.http import StreamingHttpResponse
@gzip_page
def streaming_view(request):
# Потоковые ответы не сжимаются
def generate():
for i in range(1000):
yield f"Line {i}\n"
return StreamingHttpResponse(generate())
Комбинирование с другими декораторами
Декоратор gzip_page можно комбинировать с другими
декораторами, например, для ограничения методов запроса:
from django.views.decorators.gzip import gzip_page
from django.views.decorators.http import require_GET
@gzip_page
@require_GET
def large_data_view(request):
data = {'result': 'Large dataset' * 100}
return JsonResponse(data)
Смотрите также
-
декоратор
require_GET,
который ограничивает доступ к представлению только GET-запросами -
декоратор
require_POST,
который ограничивает доступ к представлению только POST-запросами -
декоратор
csrf_exempt,
который отключает проверку CSRF для представления -
декоратор
require_http_methods,
который ограничивает доступ по списку разрешённых HTTP-методов