Как повысить скорость загрузки сайта. Часть 2

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

text

Дайте достаточно ресурсов

Скорость загрузки может провисать банально из-за того, что сайту не хватает объёма памяти или мощности процессора. Есть специальные средства мониторинга, которые показывают потребление ресурсов: от простых утилит bash до специализированных комбайнов вроде Zabbix, Nagious.

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

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

- вертикальное масштабирование, когда вы переезжаете на более мощное железо;

- горизонтальное, то есть балансировка нагрузки при помощи нескольких нод-серверов.

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

Исправьте медленные запросы к БД

Проблема не столько базы данных, сколько кода. Бэкенд запрашивает информацию у БД на языке SQL, обрабатывает её и отдаёт пользователю. От того, как составлен этот запрос, зависит, как быстро он будет выполняться. Если код оптимален, он не заставляет машину совершать лишние действия и всё проходит быстро. Если же кто-то наговнокодил, скорость загрузки сайта снизится.

У БД есть свой планировщик запросов, который до какой-то степени сам их оптимизирует. Но это не искусственный интеллект и до конца исправить ситуацию он не сможет. Поэтому нужно лезть ручками и проводить рефакторинг.

Базы данных имеют специальный арсенал средств, позволяющих оптимизировать нагрузку. В MySQL есть slow log, который отлавливает медленные запросы по определённому критерию, например, которые выполняются дольше секунды. В большинстве других БД есть аналогичные инструменты. А ещё полно замечательных сторонних решений: присмотритесь, например, к продуктам Percona.

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

Уберите лишние запросы к БД

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

Но бывает, что и и кэш используется, и запросы делаются только самые необходимые, но их всё равно слишком много. Такое обычно случается на хайлоад проектах с высокой посещаемостью. И тут есть два стула: шардинг и репликация.

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

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

Исключите синхронные запросы на фронтенде

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

При синхронном JavaScript в клиентской части ждёт, пока на уровне бэкенда запрос обработается и придёт отклик. Прочие действия на сайте «замораживаются», пока не завершился запрос. Формально это не совсем про скорость загрузки, но если на бэке возникают какие-то задержки, со стороны пользователя это выглядит как лаги.

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

Нет никакой веской причины, чтобы в современном мире использовать синхронные запросы в клиентской части (за исключением редких  сценариев), но их, к сожалению, используют. Как правило, они встречаются на древних сайтах, владельцы которых по какой-то причине привязаны к устаревшей CMS и не хотят её обновлять.

Вылечить это можно только так:

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

Оптимизируйте настройки сервера

У серверов много настроек, которые напрямую влияют на производительность и соответственно скорость загрузки сайта.

Особое внимание надо уделить настройке сервера БД, так как обычно именно база данных является узким местом сайта. Тут всё очень индивидуально и зависит от операций, которые выполняются на сайте.

Отдельный разговор — это сервер приложений. Для типичного стека, на котором работает сайт — это интерпретатор, который используется веб-сервером для исполнения PHP-кода. Настройка памяти здесь обычно самая критичная. Например, CMS Bitrix её потребляет довольно много. Если у вас интернет-магазин с большой посещаемостью, а выделено всего 256 Мбайт, скорость загрузки сайта сильно просядет.

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

Например, веб-сервер может работать в синхронном или асинхронном режиме. При синхронном он выделяет на каждый http-запрос отдельный поток, пока запрос обрабатывается. Но обычно у веб-серверов есть лимит на количество одновременных соединений, так как объём ресурсов ограничен. Все пользователи, которые попытаются подключиться сверх этого порога, получат сообщение, что сервер недоступен.

В асинхронном режиме сервер принимает запрос и помещает его вместе другими запросами от других соединений в специальный быстрый цикл — event-loop. Там он проверяет запрос, обрабатывает его и по готовности отдаёт результат пользователю. Причём всё это время сервер не будет блокироваться и сможет принимать запросы от других пользователей. Этот режим наиболее популярный, но использовать его можно далеко не всегда.

Допустим, у вашего проекта повышенные требования к производительности, поэтому нужен асинхронный режим. Тогда в большинстве случаев подойдет сервер Nginx, который его поддерживает. Но у него возможна только централизованная конфигурация. Если критически важно, чтобы пользователи могли настраивать сервер на уровне директории (на shared-хостинге, например), то вы сможете использовать только Apache. Если нужна NTLM-аутентификация — тоже он. Однако в Apache не предусмотрен асинхронный режим. Круг замкнулся, придётся что-то костылить или вообще пересматривать техническую реализацию проекта (как минимум, уходить с shared-хостинга).

Предусмотрите ошибки внешних сервисов

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

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

Массовый уход и самоизоляция обнажили проблемы с оптимизацией на многих сайтах. Но это не значит, что тема актуальна только в коронавирусный сезон. Скорость загрузки и отказоустойчивость сайта — это свойства, которые важны в любом случае. Всё может выглядеть хорошо в ситуации «по умолчанию», но как только у пользователя просело качество связи или начало подтормаживать устройство, все косяки лезут наружу. Есть много проблем, которые возникают, и вы с этим ничего не можете поделать. Но если всё будет оптимально на вашей стороне, в сумме всё может выйти не так уж плохо. А может, вообще никто ничего не заметит и не расстроится.

Читайте также:

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