Под аудитом сайта как правило понимают комплексный анализ факторов, влияющих на его видимость в поисковых системах, то есть, SEO-аудит. Также начинают набирать популярность UX-аудиты, которые оценивают эффективность, удобство и логику пользовательских интерфейсов.
Для проверки скорости работы сайта и выявления причин задержек существует технический аудит. Провести его рекомендуется, даже если система с виду работает исправно, и нет замечаний к производительности. Дело в том, что её все равно можно улучшить: оптимизация инфраструктуры ускорит доставку кода, а рефакторинг кодовой базы поможет сократить расходы на техническое сопровождение.
В этом материале мы покажем, как проходит технический аудит сайта на примере популярного новостного ресурса, который посещают десятки тысяч пользователей в час. Рассмотрим независимые друг от друга этапы проверок и анализа, в результате которых наглядно покажем, как можно улучшить проект и устранить тормозящие загрузку страниц бутылочные горлышки.
Обязательно соберите метрики и замерьте всё, что можно с помощью готовых инструментов вроде Google Page Speed, Lighthouse и Web.dev. Это самый быстрый способ получить показатели, которые послужат для вас отправной точкой при исследовании. С их помощью вы поймете, на что стоит обратить внимание в первую очередь, что можно оптимизировать.
Мы советуем проводить анализ со включенным и выключенным блокировщиком рекламы. В итоге вы узнаете, как быстро происходит первая отрисовка контента, а сколько сторонних скриптов подключено на сайте.
![](https://habrastorage.org/r/w780q1/webt/1u/v6/8x/1uv68x1xyngvz0zbafcehb2j_yw.jpeg)
На этом этапе вы также увидите, сколько основных операций происходит при отрисовке сайта:
![](https://habrastorage.org/r/w780q1/webt/zl/gy/iw/zlgyiwgums9q-jjtdk4i2_fzepg.jpeg)
Собранные метрики скорее всего укажут на пространство для улучшения статических ресурсов сайта: изображения, видео, скрипты, стили и шрифты. Проанализируйте эти данные и убедитесь, что соблюдены общие практики работы со статическими ресурсами. При этом помните, что это только рекомендации, а не строгие требования.
В нашем примере все изображения хранятся в формате jpg. Если использовать webp, который прекрасно поддерживают браузеры, размер файлов сократится в среднем на 20%. Можно настроить автоматическую компрессию в webp только для изображений с высоким разрешением. Видео с высоким разрешением рекомендуется конвертировать в webm для браузеров, которые поддерживают этот формат. Чтобы снизить нагрузку на сеть, желательно отключить автовоспроизведение видео, которого не видно. Сделать это можно с помощью Intersection Observer API.
Следите, чтобы на сайте были прогрессивные загрузки, и по возможности везде добавьте сжатия. Убедитесь, что используете современные методы компрессии скриптов вроде brotli, gzip и deflate.
Не подгружайте то, что не используется. Это может относится к коду, стилям, символам, изображениям. Если, например, на сайте есть кнопка, которая появляется в одном из тысячи случаев, то скрипт который ее обрабатывает, следует подключать только по требованию.
![](https://habrastorage.org/r/w780q1/webt/3t/wm/gj/3twmgjywmxv1z4pjzueyhqkjghg.jpeg)
На примере выше видно, что не используется ~ 93% всего кода (~340 кб.) Бандл с кодом считается идеальным, если его coverage равен 100% при покрытии всех кейсов без перезагрузки страницы. Такое может происходить, если код вообще не используется или неверно настроен code splitting, либо используется, но на других страницах, или при достижении определенного сценария.
Решение этой проблемы — вынесение переиспользуемых компонентов в отдельные файлы (чанки), которые затем подключаются только в местах, где они нужны.
Как мы сказали, эти требования не обязательны, но оптимизация статических ресурсов важна, так как пользователь замечает их в первую очередь.
Возьмем для примера шрифты — на данном проекте они грузились слишком долго. Так как мы не хотим, чтобы пользователь видел стандартные шрифты, то подгружаем их в самом начале, в секции critical-css. Как решить эту проблему? Можно оптимизировать шрифты на уровне кода, изменить порядок подключения, заменить ttf на woff2.
Можно также попробовать сократить количество используемых шрифтов, что повлечет переработку дизайна, но это не всегда оправданно. Если на сайте используется библиотека Google Fonts, то уберите неиспользуемые символы из файлов, это не запрещено авторским правом.
Но иногда проще оставить всё как есть и сосредоточиться на других возможностях.
Исследование HTTP-запросов
На этом этапе проверяем, правильно ли фронтенд взаимодействует с бэкэндом, а именно:
![](https://habrastorage.org/r/w780q1/webt/yd/44/dc/yd44dcuk2a-qp9tc75net-vzfxi.jpeg)
Красным выделены запросы, которые заблокированы, но сайт продолжает работать
Также при анализе запросов вы возможно обнаружите баги. Так мы столкнулись с неправильной работой фронтенд приложения, которое могло отправлять более 100 запросов в секунду, что сильно нагружало сервер. Экран при этом мигал, бесконечно крутился лоадер и т.д. Причина скрывалась в некорректно реализованном скролле. Браузер сохранял его положение внизу страницы при появлении новых элементов. То есть, при долистывании страницы запускался лоадер, из-за которого страница отодвигалась вниз. Javascript-обработчик повторно отправлял запрос, что в свою очередь снова вызывало анимацию лоадера, из-за который менялся размер страницы, и так до бесконечности.
![](https://habrastorage.org/r/w780q1/webt/yd/44/dc/yd44dcuk2a-qp9tc75net-vzfxi.jpeg)
Из-за некорректной работы лоадера число запросов бесконечно растет
Анализ внешних скриптов и ресурсов
На этом этапе следует определить, какие ресурсы со сторонних сайтов загружаются дольше всего.
Современный веб позволяет определять очередность любых загрузок. Часто метрики и реклама грузятся до того, как отобразится страница, что само по себе лишено смысла, так как пользователь рекламу увидеть все равно не сможет, а вот грузиться сайт будет дольше. Мы рекомендуем выводить рекламу сразу после отрисовки сайта, что никак не отразится на статистике — в противном случае пользователь будет какое-то время наблюдать белый экран.
Профилирование страниц
C помощью chrome dev tools проведите профилирование страниц сайта, чтобы отследить долгие запросы и повышенное использование процессорного времени. В результате увидите, что явно нагружает сайт.
![](https://habrastorage.org/r/w780q1/webt/kz/ql/mq/kzqlmq_skbc5xiszbhbtmniwiym.jpeg)
На скриншоте видно, что 19 миллисекунд грузиться Jquery, который не нужен в данный момент. Лучше загружать jquery после основных ресурсов, желательно после события успешной загрузки (например onload, domcontentloaded.)
Анализ количества и длительности запросов
На этом этапе изучаем, как фронтенд взаимодействует с бэкэндом. Для этого нужно проанализировать количество и длительность всех запросов.Чтобы получить более полную картину, нужно измерить среднее время ответа по одному запросу и по параллельным.
Полученные данные для наглядности объедините в сводный график. Так вы сможете быстро определить, какие запросы выполняются намного дольше других.
Если сайт установлен на мощном сервере, то время выполнения 100 параллельных запросов не должно сильно превышать время выполнения по одному запросу. В примере мы видим разницу в 30 раз. Самые долгие запросы нужно исследовать в первую очередь.
![](https://habrastorage.org/r/w780q1/webt/rk/qn/nq/rkqnnqhmdxofsv64hscudxal7ha.jpeg)
В данном проекте по некоторым запросам происходил gateway timeout, то есть, ответ от сервера вообще не приходил.
Накладные расходы в высоконагруженных проектах это нормально. Но по возможности нужно попытаться разбить запросы на составные части в тех случаях, когда один запрос отвечает за несколько действий. Эти части выполнять в параллельных потоках.
Что можно сделать, чтобы улучшить сервер? Подключите библиотеку для мониторинга сервера и перезапусков приложения ( в случае с node.js это pm2). Также рекомендуется подключить средство мониторинга ошибок, например, Sentry. Настройте вывод ошибок и логирование экстренных завершений работы. Так вы сможете отслеживать сбои в работе вашего приложения.
В идеале настройте асинхронный логгер для мониторинга любой активности на сайте (API-запросы, запросы к базе данных, внешним API, к файловой системе или сервисам для работы с файловой системой), который будет заносить их в отдельную базу.
Статический анализ исходного кода
Этот анализ выполняется утилитами, которые укажут на неправильный код и помогут избавиться от «мертвого кода». Стоит отметить, что эти средства должны использоваться автоматически в ходе разработки, но не всегда приходится рассчитывать на добросовестность разработчиков, поэтому лучше не пропускать эту проверку.
Чтобы провести статический анализ, нужно использовать линтеры eslint и другие утилиты для форматирования кода, вроде prettier и sonar, которые отслеживают нарушение правил по оформлению кода.
В итоге на основе выявленных нарушений можно составить документ:
![](https://habrastorage.org/r/w780q1/webt/2r/d2/t7/2rd2t7j7yy_3wnq0ntsn9uk90ka.jpeg)
Обычно такие нарушения не влияют на производительность сайта, но усложняют чтение и написание кода, а значит, его сопровождение будет обходиться дороже. Например, на этом проекте мы обнаружили функцию, в которой было три аргумента, один из которых не использовался — такие мелочи в совокупности и увеличивают технический долг проекта.
Семантический анализ исходного кода
На этом этапе программисту потребуется вручную изучить файлы проекта. Стоит отметить, что оценить получится только явные ошибки в поведении исходного кода, для более глубокого анализа нужно хорошо знать логику проекта.На этом этапе можно найти повторяющийся код, который можно вынести в одно место (класс, функцию или константу), чтобы уменьшить количество строк и сократить возможность багов.
Иногда такой анализ поможет определить, есть ли проблемы у команды разработки. По строкам кода из Git можно установить, кто является их автором и определить производительность отдельных сотрудников. Может обнаружиться, что больше половины замечаний относятся к одному разработчику.
Например, здесь мы выявили десять асинхронных операций, которые обновляют базу, но выполнялись они поочередно, будучи не связанными друг с другом. Это значит, что их производительность можно улучшить в два раза, если выполнять их параллельно.Используйте параллельность при любой возможности, ведь даже в PHP нынешних версий можно настроить искусственную параллельность, которая улучшит производительность системы.
Разработка ПО связана с большим количеством рисков, и в реальности часто приходится идти на компромиссы, чтобы вовремя запустить проект. Поэтому документацию обычно составляют задним числом, а оптимизацию работы сайта откладывают на самый последний момент.
Но никогда не поздно занятся улучшением производительности. Ускорение работы сайта улучшит пользовательский опыт и даст положительный отклик аудитории. С помощью технического аудита можно определить, что вызывает задержки в работе сайта — фронтенд- или бекенд-приложение. Здесь были собраны рекомендации о том, как провести аудит фронтенда. Они носят общий характер и подходят для проверки любого сайта.
О том, как проводить технический аудит бекенда, скоро расскажем в нашей следующей публикации.
Для проверки скорости работы сайта и выявления причин задержек существует технический аудит. Провести его рекомендуется, даже если система с виду работает исправно, и нет замечаний к производительности. Дело в том, что её все равно можно улучшить: оптимизация инфраструктуры ускорит доставку кода, а рефакторинг кодовой базы поможет сократить расходы на техническое сопровождение.
В этом материале мы покажем, как проходит технический аудит сайта на примере популярного новостного ресурса, который посещают десятки тысяч пользователей в час. Рассмотрим независимые друг от друга этапы проверок и анализа, в результате которых наглядно покажем, как можно улучшить проект и устранить тормозящие загрузку страниц бутылочные горлышки.
Сбор метрик и анализ статических ресурсов сайта
Обязательно соберите метрики и замерьте всё, что можно с помощью готовых инструментов вроде Google Page Speed, Lighthouse и Web.dev. Это самый быстрый способ получить показатели, которые послужат для вас отправной точкой при исследовании. С их помощью вы поймете, на что стоит обратить внимание в первую очередь, что можно оптимизировать.
Мы советуем проводить анализ со включенным и выключенным блокировщиком рекламы. В итоге вы узнаете, как быстро происходит первая отрисовка контента, а сколько сторонних скриптов подключено на сайте.
![](https://habrastorage.org/webt/1u/v6/8x/1uv68x1xyngvz0zbafcehb2j_yw.jpeg)
На этом этапе вы также увидите, сколько основных операций происходит при отрисовке сайта:
![](https://habrastorage.org/webt/zl/gy/iw/zlgyiwgums9q-jjtdk4i2_fzepg.jpeg)
Собранные метрики скорее всего укажут на пространство для улучшения статических ресурсов сайта: изображения, видео, скрипты, стили и шрифты. Проанализируйте эти данные и убедитесь, что соблюдены общие практики работы со статическими ресурсами. При этом помните, что это только рекомендации, а не строгие требования.
В нашем примере все изображения хранятся в формате jpg. Если использовать webp, который прекрасно поддерживают браузеры, размер файлов сократится в среднем на 20%. Можно настроить автоматическую компрессию в webp только для изображений с высоким разрешением. Видео с высоким разрешением рекомендуется конвертировать в webm для браузеров, которые поддерживают этот формат. Чтобы снизить нагрузку на сеть, желательно отключить автовоспроизведение видео, которого не видно. Сделать это можно с помощью Intersection Observer API.
Следите, чтобы на сайте были прогрессивные загрузки, и по возможности везде добавьте сжатия. Убедитесь, что используете современные методы компрессии скриптов вроде brotli, gzip и deflate.
Не подгружайте то, что не используется. Это может относится к коду, стилям, символам, изображениям. Если, например, на сайте есть кнопка, которая появляется в одном из тысячи случаев, то скрипт который ее обрабатывает, следует подключать только по требованию.
![](https://habrastorage.org/webt/3t/wm/gj/3twmgjywmxv1z4pjzueyhqkjghg.jpeg)
На примере выше видно, что не используется ~ 93% всего кода (~340 кб.) Бандл с кодом считается идеальным, если его coverage равен 100% при покрытии всех кейсов без перезагрузки страницы. Такое может происходить, если код вообще не используется или неверно настроен code splitting, либо используется, но на других страницах, или при достижении определенного сценария.
Решение этой проблемы — вынесение переиспользуемых компонентов в отдельные файлы (чанки), которые затем подключаются только в местах, где они нужны.
Как мы сказали, эти требования не обязательны, но оптимизация статических ресурсов важна, так как пользователь замечает их в первую очередь.
Возьмем для примера шрифты — на данном проекте они грузились слишком долго. Так как мы не хотим, чтобы пользователь видел стандартные шрифты, то подгружаем их в самом начале, в секции critical-css. Как решить эту проблему? Можно оптимизировать шрифты на уровне кода, изменить порядок подключения, заменить ttf на woff2.
Можно также попробовать сократить количество используемых шрифтов, что повлечет переработку дизайна, но это не всегда оправданно. Если на сайте используется библиотека Google Fonts, то уберите неиспользуемые символы из файлов, это не запрещено авторским правом.
Но иногда проще оставить всё как есть и сосредоточиться на других возможностях.
Исследование HTTP-запросов
На этом этапе проверяем, правильно ли фронтенд взаимодействует с бэкэндом, а именно:
- настроено сжатие для запросов к API;
- отсутствуют нагружающие соединение паразитные запросы, результаты которых нигде не используются;
- отсутствуют запросы, которые возвращаются с ошибкой без выполнения пользователем определенного бизнес кейса;
- при первоначальной загрузке страницы браузер не отправляет запросы к API (если на сайте используется server side rendering, как в нашем примере);
- отсутствуют дублирующие запросы. Если при переходе на любую страницу делается запрос, лучше отправить его один раз и сохранить данные для повторного использования;
- долго пребывающие в статусе pending запросы отсутствуют, или их число несущественно. Если такие запросы обнаружились, то узнайте, за что они отвечают, что отдают пользователю. Некоторые запросы невозможно выполнять быстрее, поэтому их рекомендуется делать независимыми — нарисуйте спиннер, чтобы не заставлять браузер ждать ответ.
![](https://habrastorage.org/webt/yd/44/dc/yd44dcuk2a-qp9tc75net-vzfxi.jpeg)
Красным выделены запросы, которые заблокированы, но сайт продолжает работать
Также при анализе запросов вы возможно обнаружите баги. Так мы столкнулись с неправильной работой фронтенд приложения, которое могло отправлять более 100 запросов в секунду, что сильно нагружало сервер. Экран при этом мигал, бесконечно крутился лоадер и т.д. Причина скрывалась в некорректно реализованном скролле. Браузер сохранял его положение внизу страницы при появлении новых элементов. То есть, при долистывании страницы запускался лоадер, из-за которого страница отодвигалась вниз. Javascript-обработчик повторно отправлял запрос, что в свою очередь снова вызывало анимацию лоадера, из-за который менялся размер страницы, и так до бесконечности.
![](https://habrastorage.org/webt/yd/44/dc/yd44dcuk2a-qp9tc75net-vzfxi.jpeg)
Из-за некорректной работы лоадера число запросов бесконечно растет
Анализ внешних скриптов и ресурсов
На этом этапе следует определить, какие ресурсы со сторонних сайтов загружаются дольше всего.
Современный веб позволяет определять очередность любых загрузок. Часто метрики и реклама грузятся до того, как отобразится страница, что само по себе лишено смысла, так как пользователь рекламу увидеть все равно не сможет, а вот грузиться сайт будет дольше. Мы рекомендуем выводить рекламу сразу после отрисовки сайта, что никак не отразится на статистике — в противном случае пользователь будет какое-то время наблюдать белый экран.
Профилирование страниц
C помощью chrome dev tools проведите профилирование страниц сайта, чтобы отследить долгие запросы и повышенное использование процессорного времени. В результате увидите, что явно нагружает сайт.
![](https://habrastorage.org/webt/kz/ql/mq/kzqlmq_skbc5xiszbhbtmniwiym.jpeg)
На скриншоте видно, что 19 миллисекунд грузиться Jquery, который не нужен в данный момент. Лучше загружать jquery после основных ресурсов, желательно после события успешной загрузки (например onload, domcontentloaded.)
Анализ количества и длительности запросов
На этом этапе изучаем, как фронтенд взаимодействует с бэкэндом. Для этого нужно проанализировать количество и длительность всех запросов.Чтобы получить более полную картину, нужно измерить среднее время ответа по одному запросу и по параллельным.
Полученные данные для наглядности объедините в сводный график. Так вы сможете быстро определить, какие запросы выполняются намного дольше других.
Если сайт установлен на мощном сервере, то время выполнения 100 параллельных запросов не должно сильно превышать время выполнения по одному запросу. В примере мы видим разницу в 30 раз. Самые долгие запросы нужно исследовать в первую очередь.
![](https://habrastorage.org/webt/rk/qn/nq/rkqnnqhmdxofsv64hscudxal7ha.jpeg)
В данном проекте по некоторым запросам происходил gateway timeout, то есть, ответ от сервера вообще не приходил.
Накладные расходы в высоконагруженных проектах это нормально. Но по возможности нужно попытаться разбить запросы на составные части в тех случаях, когда один запрос отвечает за несколько действий. Эти части выполнять в параллельных потоках.
Что можно сделать, чтобы улучшить сервер? Подключите библиотеку для мониторинга сервера и перезапусков приложения ( в случае с node.js это pm2). Также рекомендуется подключить средство мониторинга ошибок, например, Sentry. Настройте вывод ошибок и логирование экстренных завершений работы. Так вы сможете отслеживать сбои в работе вашего приложения.
В идеале настройте асинхронный логгер для мониторинга любой активности на сайте (API-запросы, запросы к базе данных, внешним API, к файловой системе или сервисам для работы с файловой системой), который будет заносить их в отдельную базу.
Статический анализ исходного кода
Этот анализ выполняется утилитами, которые укажут на неправильный код и помогут избавиться от «мертвого кода». Стоит отметить, что эти средства должны использоваться автоматически в ходе разработки, но не всегда приходится рассчитывать на добросовестность разработчиков, поэтому лучше не пропускать эту проверку.
Чтобы провести статический анализ, нужно использовать линтеры eslint и другие утилиты для форматирования кода, вроде prettier и sonar, которые отслеживают нарушение правил по оформлению кода.
В итоге на основе выявленных нарушений можно составить документ:
![](https://habrastorage.org/webt/2r/d2/t7/2rd2t7j7yy_3wnq0ntsn9uk90ka.jpeg)
Обычно такие нарушения не влияют на производительность сайта, но усложняют чтение и написание кода, а значит, его сопровождение будет обходиться дороже. Например, на этом проекте мы обнаружили функцию, в которой было три аргумента, один из которых не использовался — такие мелочи в совокупности и увеличивают технический долг проекта.
Семантический анализ исходного кода
На этом этапе программисту потребуется вручную изучить файлы проекта. Стоит отметить, что оценить получится только явные ошибки в поведении исходного кода, для более глубокого анализа нужно хорошо знать логику проекта.На этом этапе можно найти повторяющийся код, который можно вынести в одно место (класс, функцию или константу), чтобы уменьшить количество строк и сократить возможность багов.
Иногда такой анализ поможет определить, есть ли проблемы у команды разработки. По строкам кода из Git можно установить, кто является их автором и определить производительность отдельных сотрудников. Может обнаружиться, что больше половины замечаний относятся к одному разработчику.
Например, здесь мы выявили десять асинхронных операций, которые обновляют базу, но выполнялись они поочередно, будучи не связанными друг с другом. Это значит, что их производительность можно улучшить в два раза, если выполнять их параллельно.Используйте параллельность при любой возможности, ведь даже в PHP нынешних версий можно настроить искусственную параллельность, которая улучшит производительность системы.
Итог
Разработка ПО связана с большим количеством рисков, и в реальности часто приходится идти на компромиссы, чтобы вовремя запустить проект. Поэтому документацию обычно составляют задним числом, а оптимизацию работы сайта откладывают на самый последний момент.
Но никогда не поздно занятся улучшением производительности. Ускорение работы сайта улучшит пользовательский опыт и даст положительный отклик аудитории. С помощью технического аудита можно определить, что вызывает задержки в работе сайта — фронтенд- или бекенд-приложение. Здесь были собраны рекомендации о том, как провести аудит фронтенда. Они носят общий характер и подходят для проверки любого сайта.
О том, как проводить технический аудит бекенда, скоро расскажем в нашей следующей публикации.