Как-то внезапно из каждого утюга доносятся восторги по поводу скорости работы сайта McMaster-Carr: каталога-продажи всяких железяк. Некоторые даже видео с разбором запилили.

Посмотрел-потыкал сайт. Покопался в кишочках. Достаточно шустро: 170ms до отрисовки контента. А в некоторых местах оптимизации позволяют реагировать на действия пользователя мгновенно. Но никаких срывов покровов, а только грамотное использование технологий. Забавно, что просто качественная работа сейчас воспринимается, как какое-то откровение.

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

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

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

  • Использование поверх обычной динамической CMS какого-нибудь reverse-proxy типа Squid. Если сайт использует персонализированную выдачу, придётся предварительно разделить статический и динамический контент. Это сделает возможным моментальную выдачу страницы второму посетителю, ибо она уже была отрендерена и закеширована в процессе подготовки для первого посетителя. И таким образом получится сэкономить на тяжёлых походах в CMS и в базы данных. Сайт McMaster, например, загружает только основной контент страниц, а в шапку (там, где логин и корзина) изменения вносятся динамически, без перезагрузки основного тела страницы.

  • Применяется агрессивное кеширование в браузере: незачем ходить на сервер, если ничего не изменилось. McMaster использует кеш, который легко контролировать: сайт притворяется PWA и использует ServiceWorkers для сохранения уже однажды полученного контента. Приятный побочный эффект: если пользователь зайдёт на сайт повторно, страница откроется мгновенно, даже без отправки запроса в интернет.

  • Используется отдельный хост (или CDN) для картинок и dns-prefetch. Если на сайте много изображений, выделение для них отдельного хоста позволяет не упираться в лимит на подключения к серверу (всего 6 штук для Chrome), параллельно загружать CSS, JS, данные для страниц, и не блокировать их загрузку картинками.

  • Разделение на бандлы: встраивание в страницу критической части CSS, асинхронная подгрузка полного набора стилей уже после отображения страницы с помощью JS. Разделение на части JS и CSS-модулей с тем, чтобы на конкретной странице загружать только те данные, которые требуются именно на ней.

Раньше такое умел делать Webpack 3 из коробки, но потом автоматическое формирование common-бандла убрали из общих плагинов. Поэтому в 2024 такой сборщик придётся написать самостоятельно.

  • Объединение картинок в атласы спрайтов. Причём, похоже, что для этого сайта они подготовлены вручную. Но можно использовать и автоматизированные утилиты, которые есть под любой язык программирования: web sprite generator (добавить в запрос название языка программирования). И не забывать всегда указывать у картинок конкретные размеры, даже у ещё не загруженных.

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

  • Ленивая загрузка. Не перегружать DOM информацией: не загружать контент далее видимой области. (Это касается и всевозможных каруселей с аккордеонами) Под элементы, которые пользователь прямо сейчас не видит, просто резервируется место на странице, и только при подкрутке их в область видимости или ином взаимодействии, данные материализуются и отображаются.

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