Как ускорить загрузку сайта со стороны бэкенда

Kate

Administrator
Команда форума

Фаррух​

тимлид в IT-продакшне Extyl​

Скорость загрузки страниц влияет на ранжирование сайта поисковиками, на процент отказов и на его конверсию. Поэтому при разработке важно измерять и оптимизировать этот показатель. Меня зовут Фаррух, я тимлид в IT-продакшне Extyl. Мы разрабатываем b2b-сервисы, порталы и личные кабинеты для крупного бизнеса. В этом материале я расскажу, какие технологические решения мы используем, чтобы ускорить загрузку своих проектов.

***

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

Если мы говорим о сайтах, написанных на PHP, то скорость генерации страницы при хорошей архитектуре будет 100 мс, но допустима и более медленная загрузка — до 400 мс с последующей оптимизацией кешированием с помощью cache-buster’а, который увеличит скорость до 20-30 мс. С одного домена можно параллельно загружать только шесть файлов. Поэтому файлы нужно не только уменьшать в размере, но и сокращать их количество. Например, элементы дизайна — стрелки, кнопки и прочее — рекомендуется объединять в один файл (технология CSS-спрайтов).

International Conference on Code Quality
27 марта в 10:00, Онлайн, Беcплатно
tproger.ru

События и курсы на tproger.ru
Также рекомендуем использовать услуги CDN-провайдеров. Они помогают без особых затрат расположить файлы на разных серверах, что увеличит количество параллельно загружаемых файлов.

TTFB — Time to First Byte (время до получения первого байта) — это показатель задержки в передаче данных между браузером и сервером; степени загрузки сервера; и скорости генерации контента движком сайта. Хорошее значение TTFB не обязательно означает то, что демонстрирующий его сайт можно счесть быстрым, но плохой показатель TTFB гарантированно указывает на проблемы с производительностью проекта.

В Extyl мы выбрали для себя предельное время TTFB в 200 мс. Такой показатель вполне достижим для большинства приложений.

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

TIG (Telegraf, Influx, Grafana)​





Мониторинг сайта мы проводим на стеке TIG (Telegraf, Influx, Grafana) — это базовый набор компонентов для быстрого развертывания системы мониторинга. Опытный разработчик может сделать это за час.

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

Яндекс.Танк​

Еще один популярный и доступный инструмент тестирования — это Яндекс.Танк. Он позволяет проводить нагрузочные тестирования и анализ производительности веб-сервисов и приложений. Благодаря данным, которые предоставляет Яндекс.Танк, разработчик видит, как работает его приложение под любой нагрузкой.







Архитектура​

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

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

У нас практически всегда есть свободная ОЗУ на веб-сервере и мы можем разместить кэш-сервер на нем. Связь с ним по сокету дает прирост до 30% относительно обмена c локалхостом, и кратный прирост скорости в сравнении с кэш-сервером, находящимся на другом хосте.

База данных​

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

Основная база данных на наших проектах — это PostgreSQL. У PostgreSQL много сильных сторон, но ее основное преимущество — подход Not-Only-SQL. Для примера возьмём достаточно частый запрос вывода данных по связи many-to-many. В тестовой БД более миллиона записей в таблице news и около 300 тысяч тегов.


Стоит прочитать: обзор книги Маркуса Винанда «SQL Performance explained»
tproger.ru

Сравним выборки по JSONB с индексом GIN и базового алгоритма.

JSONB — разновидность формата JSON. Немного более сложная, но хорошо покрываемая индексами GIN.

Индекс GIN — это обобщенный инвертированный индекс, который содержит записи для всех отдельных слов (лексем) с компактным списком мест их вхождений. При поиске нескольких слов можно найти первое, а затем воспользоваться индексом и исключить строки, в которых дополнительные слова отсутствуют.

Выберем все новости, которые содержат выбранный тег, как мы это делаем обычно.

explain analyze
select * from news
where id in (select news_id from news_tag where tag_id = 14)
limit 20




Теперь посмотрим тоже самое на jsonb и gin индексах:

select * from news
where json_custom_new @> '{"14": "#здоровье"}'
and active = true
limit 20




Мы видим уменьшение времени выборки с 5 мс до 0,6 мс, а это почти в 10 раз быстрее.

Усложним запрос. Теперь мы хотим получить все новости в которых встречаются 2 тега:

explain analyze
select * from "news"
where exists (select * from "tags
inner join "news_tag" on "tags"."id" = "news_tag"."tag_id"
where "news"."id" = "news_tag"."news_id" and "id" in (14,632))
and active = true
limit 20




И тоже самое на jsonb и gin:

explain analyze
select * from news
where json_custom_new @> '{"14": "#здоровье","632": "#партпроект"}'
and active = true
limit 20




Мы видим для jsonb и gin скорость выборки не особенно изменилась. А для оригинального SQL скорость выборки упала еще на порядок, деградация будет еще более заметна под нагрузкой. Даже на относительно простых операциях мы получаем прирост производительности до 3-х порядков.

Также мы рекомендуем дробить индексы на отдельные более мелкие. Например, поделить каталог товаров по разделам. На запросах типа exists, как в предыдущем примере, мы можем уменьшить время выборки с 600 мс до 50 мс

Покрывающие индексы​

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

CREATE INDEX news_id_index_section_11_news
ON public.news USING btree
(start_date DESC NULLS LAST)
INCLUDE(end_date, section_id)
TABLESPACE pg_default
WHERE section_id = 11 AND active = true AND deleted_at IS NULL;
Таким образом, можно выиграть еще 30-40% на выборках.

Денормализация​

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



Это упрощает код и ускоряет выборки из БД.

Итог​

  • Нужно следить за показателями скорости.
  • Проверять их динамику под нагрузкой.
  • Оптимизировать базу данных.
  • Сокращать количество одновременно загружаемых файлов.

Источник статьи: https://tproger.ru/articles/kak-uskorit-zagruzku-sajta-so-storony-bjekenda/
 
Сверху