Spec-Zone.ru › Django 4.2

Производительность и оптимизация

В этом документе приведены общие сведения о методах и инструментах, которые помогут сделать ваш код Django более эффективным — быстрее и с меньшим использованием системных ресурсов.

Введение

Обычно первостепенной задачей является создание работающего кода, логика которого функционирует в соответствии с требованиями для получения ожидаемого результата. Однако иногда этого недостаточно для обеспечения эффективной работы кода.

В этом случае требуется что-то — а на практике, часто набор вещей — для повышения производительности кода без или с минимальным влиянием на его поведение.

Общие подходы

Для чего вы оптимизируете?

Важно четко понимать, что вы имеете в виду под «производительностью». Нет единственного показателя производительности.

Повышение скорости может быть наиболее очевидной целью программы, но иногда могут потребоваться и другие улучшения производительности, такие как снижение потребления памяти или меньшая нагрузка на базу данных или сеть.

Улучшения в одной области часто приводят к улучшению производительности в другой, но не всегда; иногда одно даже может ухудшить другое. Например, повышение скорости программы может привести к увеличению использования памяти. Хуже того, это может оказаться контрпродуктивным — если улучшение скорости настолько зависит от памяти, что система начинает испытывать нехватку памяти, то вы нанесёте больше вреда, чем пользы.

Следует учитывать и другие компромиссы. Ваше время — ценный ресурс, более ценный, чем время процессора. Некоторые улучшения могут оказаться слишком сложными, чтобы оправдать их внедрение, или могут повлиять на переносимость или поддерживаемость кода. Не все улучшения производительности стоят усилий.

Таким образом, вы должны знать, какие улучшения производительности вы хотите получить, а также вы должны знать, что у вас есть веские причины для этого — и для этого вам нужно:

Тестирование производительности

Не стоит просто предполагать или догадываться, где находятся неэффективные места в вашем коде.

Инструменты Django

django-debug-toolbar — очень полезный инструмент, который предоставляет информацию о том, что делает ваш код и сколько времени он тратит на выполнение. В частности, он может показать все SQL-запросы, генерируемые вашей страницей, и время выполнения каждого из них.

Для панели также доступны сторонние плагины, которые (например) могут сообщать о производительности кэша и времени рендеринга шаблонов.

Сервисы третьих сторон

Существует ряд бесплатных сервисов, которые анализируют и сообщают о производительности страниц вашего сайта с точки зрения удалённого HTTP-клиента, фактически моделируя опыт реального пользователя.

Они не могут сообщить о внутреннем устройстве вашего кода, но могут предоставить полезную информацию о общей производительности вашего сайта, включая аспекты, которые нельзя адекватно измерить из среды Django. Примеры включают:

  • Yslow от Yahoo
  • PageSpeed от Google

Также существуют платные сервисы, которые выполняют аналогичный анализ, включая некоторые, которые учитывают Django и могут интегрироваться с вашей кодовой базой для более всестороннего профилирования производительности.

Делайте все правильно с самого начала

Некоторые работы по оптимизации включают устранение недостатков производительности, но некоторые работы можно интегрировать в то, что вы делаете и так, как часть хороших практик, которые вы должны использовать даже до того, как подумаете об улучшении производительности.

В этом отношении Python — превосходный язык для работы, потому что решения, которые выглядят элегантно и правильны, как правило, являются наиболее эффективными. Как и в большинстве навыков, понимание того, что «выглядит правильно», требует практики, но одним из самых полезных руководств является:

Работайте на соответствующем уровне

Django предоставляет множество способов решения задач, но то, что можно сделать определённым способом, не означает, что это самый подходящий способ. Например, вы можете обнаружить, что можете вычислить одно и то же — количество элементов в коллекции, возможно — в QuerySet, на Python или в шаблоне.

Однако, в почти всех случаях быстрее выполнить эту работу на более низком, а не на более высоком уровне. На более высоких уровнях система должна обрабатывать объекты через несколько уровней абстракции и слоёв механизмов.

То есть, база данных обычно может выполнять вещи быстрее, чем Python, который может выполнять их быстрее, чем язык шаблонов:

# QuerySet operation on the database
# fast, because that's what databases are good at
my_bicycles.count()

# counting Python objects
# slower, because it requires a database query anyway, and processing
# of the Python objects
len(my_bicycles)
<!--
Django template filter
slower still, because it will have to count them in Python anyway,
and because of template language overheads
-->
{{ my_bicycles|length }}

В общем случае, наиболее подходящий уровень для задачи — это самый низкий уровень, для которого комфортно писать код.

Примечание

Приведённый пример является лишь иллюстративным.

Во-первых, в реальном случае вам нужно рассмотреть, что происходит до и после подсчёта, чтобы определить, как оптимально сделать это в данном конкретном контексте. Документация по оптимизации базы данных описывает случай, когда подсчёт в шаблоне будет лучше.

Во-вторых, существуют другие варианты: в реальном случае {{ my_bicycles.count }}, что вызывает QuerySet count() метод напрямую из шаблона, может быть наиболее подходящим выбором.

Кэширование

Часто вычисление значения является дорогим (то есть, ресурсоёмким и медленным), поэтому использование быстродоступного кэша для хранения значения может быть очень полезным, когда оно нужно в следующий раз.

Это достаточно значительный и мощный метод, поэтому Django включает в себя комплексный фреймворк кэширования, а также другие небольшие функции кэширования.

Фреймворк кэширования

Фреймворк кэширования Django предоставляет значительные возможности для повышения производительности, сохраняя динамическое содержимое, чтобы оно не нуждалось в вычислении для каждого запроса.

Для удобства Django предлагает различные уровни гранулярности кэширования: вы можете кэшировать выходные данные конкретных представлений или только те части, которые сложно получить, или даже весь сайт.

Внедрение кэширования не следует рассматривать как альтернативу улучшению кода, работающего плохо из-за плохого написания. Это один из заключительных шагов к созданию высокопроизводительного кода, а не обходной путь.

cached_property

Часто приходится вызывать метод экземпляра класса более одного раза. Если эта функция является дорогостоящей, то это может быть пустой тратой ресурсов.

Использование декоратора cached_property сохраняет возвращаемое значение свойства; при следующем вызове функции для этого экземпляра будет возвращено сохранённое значение, а не пересчитываться. Обратите внимание, что это работает только для методов, которые принимают self в качестве единственного аргумента, и что это изменяет метод на свойство.

Некоторые компоненты Django также имеют свои функции кэширования; они обсуждаются ниже в разделах, относящихся к этим компонентам.

Понимание лени

Лени — стратегия, дополняющая кэширование. Кэширование избегает пересчёта, сохраняя результаты; лени откладывает вычисления до фактической необходимости.

Лени позволяет ссылаться на вещи до их инициализации или даже до момента, когда их можно инициализировать. Это имеет множество применений.

Например, ленивый перевод может быть использован, прежде чем целевой язык будет известен, потому что он не выполняется, пока переведённая строка фактически не потребуется, например, в рендеринг шаблона.

Ленивость также является способом сэкономить усилия, пытаясь избежать работы в первую очередь. То есть, один из аспектов лени заключается в том, чтобы ничего не делать, пока это не требуется, потому что это может оказаться не нужным. Таким образом, ленивость может иметь последствия для производительности, и чем дороже работа, тем больше выигрыша можно получить благодаря лени.

Python предоставляет ряд инструментов для ленивого вычисления, в частности, с помощью конструкций генератор и генераторное выражение. Стоит изучить ленивость в Python, чтобы узнать возможности использования ленивых шаблонов в вашем коде.

Ленивость в Django

Сам Django достаточно ленивый. Хорошим примером этого является оценка QuerySets. QuerySets ленивые. Таким образом, можно создать QuerySet, передавать его и комбинировать с другими QuerySets, фактически не производя никаких обращений к базе данных для извлечения описанных элементов. Передаваемым объектом является QuerySet объект, а не коллекция элементов, которые — в конечном итоге — потребуются из базы данных.

С другой стороны, некоторые операции приведут к принудительной оценке QuerySet. Избегание преждевременной оценки QuerySet может сэкономить дорогостоящее и ненужное обращение к базе данных.

Django также предлагает декоратор keep_lazy(). Это позволяет функции, которая была вызвана с ленивым аргументом, вести себя лениво, вычисляясь только тогда, когда это необходимо. Таким образом, ленивый аргумент — который мог быть дорогостоящим — не будет вызван для вычисления до тех пор, пока это строго не потребуется.

Базы данных

Оптимизация базы данных

Уровень базы данных Django предоставляет различные способы помочь разработчикам получить наилучшую производительность от своих баз данных. Документация по оптимизации баз данных собирает ссылки на соответствующую документацию и добавляет различные советы, которые описывают шаги, которые необходимо предпринять при попытке оптимизировать использование вашей базы данных.

Дополнительные советы по работе с базой данных

Включение постоянных соединений может ускорить подключение к базам данных, что является значительной частью времени обработки запросов.

Это очень полезно на виртуальных хостах с ограниченной производительностью сети, например.

Производительность HTTP

Средства промежуточного ПО

Django поставляется с несколькими полезными средствами промежуточного ПО средства промежуточного ПО, которые могут помочь оптимизировать производительность вашего сайта. Они включают:

ConditionalGetMiddleware

Добавляет поддержку современным браузерам для условного получения ответов на основе заголовков ETag и Last-Modified. Также вычисляет и устанавливает тег ETag при необходимости.

GZipMiddleware

Сжимает ответы для всех современных браузеров, экономя пропускную способность и время передачи. Обратите внимание, что GZipMiddleware в настоящее время считается риском для безопасности и уязвим для атак, которые сводят на нет защиту, предоставляемую TLS/SSL. См. Предупреждение в GZipMiddleware для получения дополнительной информации.

Сессии

Использование кэшированных сессий

Использование кэшированных сессий может быть способом повышения производительности, устраняя необходимость в загрузке данных сессий из медленного источника хранения, такого как база данных, и вместо этого хранение часто используемых данных сессий в памяти.

Статические файлы

Статические файлы, которые по определению не являются динамическими, являются отличной целью для оптимизации.

ManifestStaticFilesStorage

Используя возможности кэширования веб-браузеров, вы можете полностью устранить сетевые запросы для данного файла после первоначальной загрузки.

ManifestStaticFilesStorage добавляет тег, зависящий от содержимого, в имена файлов статических файлов, чтобы сделать их безопасными для кэширования браузерами в долгосрочной перспективе без пропуска будущих изменений - при изменении файла меняется и тег, поэтому браузеры автоматически перезагрузят ресурс.

“Минификация”

Некоторые сторонние инструменты и пакеты Django предоставляют возможность «минификации» HTML, CSS и JavaScript. Они удаляют нежелательные пробелы, новые строки и комментарии, а также сокращают имена переменных, тем самым уменьшая размер документов, публикуемых вашим сайтом.

Производительность шаблонов

Обратите внимание, что:

  • использование {% block %} быстрее, чем использование {% include %}
  • сильно фрагментированные шаблоны, собранные из многих мелких элементов, могут влиять на производительность

Кэшированный загрузчик шаблонов

Включение cached template loader часто значительно улучшает производительность, так как это предотвращает компиляцию каждого шаблона каждый раз, когда он должен быть отображен.

Использование различных версий доступного ПО

Иногда стоит проверить, доступны ли разные и более производительные версии программного обеспечения, которое вы используете.

Эти методы ориентированы на более продвинутых пользователей, которые хотят расширить границы производительности уже хорошо оптимизированного сайта Django.

Однако, они не являются волшебным решением проблем с производительностью, и они вряд ли принесут больше, чем незначительные улучшения сайтам, которые не выполняют более базовые вещи правильным образом.

Примечание

Стоит повторить: поиск альтернатив используемому программному обеспечению — это никогда не первое решение проблем с производительностью. Когда вы достигаете этого уровня оптимизации, вам нужна формальная система измерения производительности.

Новое часто, но не всегда, лучше

Вполне редко, чтобы новая версия хорошо поддерживаемого программного обеспечения была менее эффективной, но разработчики не могут предусмотреть каждый возможный случай использования — поэтому, хотя следует понимать, что новые версии, вероятно, будут работать лучше, не следует предполагать, что они всегда будут.

Это относится и к Django. Последовательные релизы предлагали ряд улучшений в системе, но вы по-прежнему должны проверять реальную производительность своего приложения, потому что в некоторых случаях вы можете обнаружить, что изменения ухудшают его производительность, а не улучшают.

Новые версии Python и пакетов Python также часто будут работать лучше — но измеряйте, а не предполагайте.

Примечание

Если вы не столкнулись с необычной проблемой производительности в какой-то конкретной версии, как правило, вы найдете лучшие функции, надежность и безопасность в новой версии, и эти преимущества намного значительнее, чем любая производительность, которую вы можете получить или потерять.

Альтернативы языку шаблонов Django

Практически во всех случаях встроенный язык шаблонов Django вполне достаточен. Однако, если узкие места в вашем проекте Django связаны с системой шаблонов, и вы исчерпали другие возможности для их исправления, сторонняя альтернатива может быть ответом.

Jinja2 может предложить улучшения производительности, особенно в плане скорости.

Альтернативные системы шаблонов различаются по степени их соответствия языку шаблонов Django.

Примечание

Если у вас возникают проблемы с производительностью в шаблонах, в первую очередь нужно понять, почему. Использование альтернативной системы шаблонов может оказаться быстрее, но те же улучшения также могут быть достигнуты без особых усилий — например, трудоемкая обработка и логика в ваших шаблонах могут быть реализованы более эффективно в ваших представлениях.

Альтернативные реализации программного обеспечения

Стоит проверить, не существует ли другой реализации программного обеспечения Python, которое вы используете, что может выполнять тот же код быстрее.

Однако большинство проблем с производительностью на хорошо написанных сайтах Django не связаны с уровнем выполнения Python, а скорее с неэффективными запросами к базе данных, кэшированием и шаблонами. Если вы полагаетесь на плохо написанный код Python, проблемы с производительностью вряд ли будут решены за счет его более быстрого выполнения.

Использование альтернативной реализации может привести к проблемам совместимости, развертывания, портируемости или сопровождения. Само собой разумеется, что перед принятием нестандартной реализации необходимо убедиться, что она обеспечивает достаточный прирост производительности для вашего приложения, чтобы перевесить потенциальные риски.

С учетом этих оговорок вы должны знать о:

PyPy

PyPy — это реализация Python на самом Python (стандартная реализация Python — на C). PyPy может предложить существенные улучшения производительности, как правило, для ресурсоемких приложений.

Ключевой целью проекта PyPy является совместимость с существующими API и библиотеками Python. Django совместим, но вам нужно проверить совместимость других библиотек, на которые вы полагаетесь.

Реализации Python-библиотек на C

Некоторые библиотеки Python также реализованы на C и могут быть намного быстрее. Они стремятся предоставить те же API. Обратите внимание, что проблемы совместимости и различия в поведении не исключены (и не всегда сразу очевидны).

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.2/topics/performance/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API