Веб-производительность
Page Speed: комплексная оптимизация загрузки сайта

Page Speed — это не один показатель, а система метрик и оптимизаций, которая определяет, насколько быстро пользователь получает рабочую страницу. Разбираем все ключевые слои: сервер, активы, скрипты, кэш — от диагностики до конкретных техник.
Page Speed — одна из ключевых инвестиций в SEO и конверсию одновременно. Amazon посчитал, что каждые 100 мс задержки стоят 1% продаж. Google с 2010 года использует скорость как фактор ранжирования для десктопа, с 2018 — для мобайла, а с 2021 ввёл Core Web Vitals как прямой сигнал Page Experience.
Что такое Page Speed и как его измеряют
Page Speed — не один показатель, а совокупность метрик, каждая из которых измеряет отдельный аспект загрузки. Google PageSpeed Insights объединяет лабораторные данные (Lighthouse) и полевые данные реальных пользователей (Chrome User Experience Report). Итоговый «балл» от 0 до 100 — это взвешенная сумма нескольких метрик, а не единственный ориентир для оптимизации.
Для SEO критичны именно полевые данные (Field Data / CrUX): Google использует 75-й перцентиль реальных пользователей Chrome при оценке Core Web Vitals. Лабораторный Lighthouse помогает диагностировать проблемы, но не является прямым входом в алгоритм ранжирования.
Ключевые метрики скорости
Каждая метрика отвечает за конкретный аспект пользовательского опыта. Понимание их различий — основа правильной диагностики.
| Метрика | Что измеряет | Хорошее значение | Влияет на ранжирование |
|---|---|---|---|
| TTFB (Time to First Byte) | Время до первого байта HTML от сервера | < 800 мс | Косвенно (через LCP) |
| FCP (First Contentful Paint) | Первый пиксель контента на экране | < 1.8 сек | Lighthouse, не CrUX-фактор |
| LCP (Largest Contentful Paint) | Основной контент виден пользователю | < 2.5 сек | Да (Core Web Vitals) |
| INP (Interaction to Next Paint) | Отзывчивость на взаимодействие пользователя | < 200 мс | Да (Core Web Vitals, заменил FID) |
| CLS (Cumulative Layout Shift) | Стабильность макета — насколько прыгают элементы | < 0.1 | Да (Core Web Vitals) |
| TBT (Total Blocking Time) | Суммарное время блокировки основного потока JS | < 200 мс | Лабораторный прокси для INP |
Уходят за 3 сек
Мобильных пользователей покидают страницу при загрузке дольше 3 секунд
Конверсия/сек
Каждая секунда задержки снижает конверсию в среднем на 1–3%
Перцентиль CrUX
Google оценивает Core Web Vitals по 75-му перцентилю реальных пользователей
Окно CrUX
Скользящий период, за который собираются данные для оценки сайта
Диагностика: с чего начать оптимизацию
Слепая оптимизация — пустая трата времени. Правильный порядок: сначала измерить, выявить узкое место, устранить, снова измерить.
- Откройте PageSpeed Insights и проверьте 5–10 ключевых страниц: главная, категории, карточки товаров, лендинги. Смотрите на Field Data, а не только на Lighthouse Score.
- В Google Search Console перейдите в раздел Core Web Vitals — он покажет, какие URL имеют «Poor» или «Needs improvement» по LCP, INP, CLS с реальными данными пользователей.
- Запустите WebPageTest для глубокого анализа: waterfall загрузки, filmstrip, время до первого байта, влияние CDN. Выберите тест из региона основной аудитории.
- Используйте Chrome DevTools → Performance → запишите загрузку страницы. Flame chart покажет, какой скрипт занимает основной поток и блокирует рендеринг.
- Проверьте Coverage (DevTools → Coverage): неиспользуемый CSS/JS — это прямые кандидаты на удаление или отложенную загрузку.
PageSpeed Insights
Бесплатный инструмент Google. Показывает Lab (Lighthouse) и Field (CrUX) данные. Даёт список конкретных рекомендаций с оценкой экономии времени. Лучший старт для первичного аудита.
WebPageTest
Детальный waterfall, filmstrip, тест из разных точек мира, сравнение версий. Показывает влияние CDN, DNS, SSL-handshake. Незаменим для глубокой диагностики TTFB.
Google Search Console
Реальные данные CrUX по группам URL. Показывает тренд метрик по времени — лучший инструмент для мониторинга улучшений после деплоя оптимизаций.
Chrome DevTools
Performance Profiler и Coverage вкладки — для поиска конкретного скрипта или CSS, блокирующего рендеринг. Flame chart показывает длинные задачи в основном потоке (Long Tasks > 50 мс).
Оптимизация сервера и TTFB
TTFB (Time to First Byte) — фундамент всей скорости. Если сервер отвечает медленно, все последующие оптимизации работают в условиях искусственного ограничения. Цель: TTFB < 200 мс для CDN-окружений, < 400 мс для динамических серверов.
Хостинг и инфраструктура
- Выбор хостинга
- Shared хостинг с ресурсами, разделёнными между тысячами сайтов, ограничивает TTFB физически. VPS или dedicated сервер с Nginx/Caddy + правильным кэшированием даёт TTFB 20–80 мс для статики.
- CDN (Content Delivery Network)
- Cloudflare, BunnyCDN, Fastly — ближайший edge-узел к пользователю отвечает вместо вашего сервера. Для статичного или кэшированного контента TTFB падает до 10–50 мс. Для динамического — зависит от настроек кэша на edge.
- HTTP/2 и HTTP/3 (QUIC)
- HTTP/2 убирает head-of-line blocking и поддерживает мультиплексирование. HTTP/3 на базе QUIC дополнительно ускоряет установку соединения (0-RTT) и устойчив к потерям пакетов на мобильных сетях.
- Геолокация сервера
- Физическое расстояние между пользователем и сервером добавляет ~1 мс на каждые 100 км (round trip). Для русскоязычной аудитории сервер в Москве или Амстердаме значительно лучше, чем в US-East.
Сжатие и кодирование
- Включите Brotli (br) — экономит 15–25% по сравнению с gzip при аналогичной скорости декомпрессии. Поддерживается всеми современными браузерами.
- Убедитесь, что gzip включён как fallback для старых клиентов. Минимум: уровень сжатия 6.
- Настройте сжатие для HTML, CSS, JS, JSON, XML, SVG. Изображения и бинарные файлы уже сжаты — применять gzip к ним бессмысленно.
- Используйте HTTP-заголовок Vary: Accept-Encoding, чтобы CDN кэшировал разные версии для разных клиентов.
Серверное кэширование
Динамические страницы (PHP, Node.js, Python) каждый раз обращаются к базе данных. Кэш позволяет отдавать готовый HTML без пересчёта.
- Full-page cache: Nginx FastCGI Cache, Varnish, Redis — сохраняют готовый HTML и отдают без обращения к приложению.
- Object cache: Redis или Memcached для кэширования результатов запросов к БД, сессий, вычислений.
- Правила инвалидации: кэш должен сбрасываться при изменении контента (webhook от CMS, TTL по расписанию).
- Stale-while-revalidate: отдавать старый кэш немедленно, обновлять в фоне — пользователь не ждёт регенерации.
Оптимизация активов: изображения, шрифты, CSS
Изображения
Изображения — обычно самая весомая категория трафика на странице. Правильная оптимизация даёт 30–70% экономии на трафике и прямо влияет на LCP.
| Техника | Экономия | Приоритет |
|---|---|---|
| WebP вместо JPEG/PNG | 25–35% | Высокий |
| AVIF вместо JPEG/PNG | 40–55% | Высокий (поддержка 90%+ браузеров) |
| Сжатие без потерь (PNG → oxipng) | 5–20% | Средний |
| Correct sizing (srcset + sizes) | 50–80% для мобайла | Высокий |
| lazy loading для off-screen изображений | Экономия запросов при загрузке | Высокий |
| fetchpriority="high" для LCP-изображения | 0.5–1.5 сек LCP | Критический |
Используйте элемент <picture> для подачи правильного формата: AVIF для поддерживающих браузеров, WebP как fallback, JPEG/PNG для старых браузеров. Next.js Image компонент делает это автоматически.
Шрифты
- Self-host шрифты: загружайте .woff2 с собственного домена — убираете DNS lookup, TCP handshake и зависимость от Google Fonts CDN.
- Preload критичных шрифтов: <link rel="preload" as="font" type="font/woff2" crossorigin> в <head> — браузер начнёт загрузку до парсинга CSS.
- font-display: swap — браузер показывает системный шрифт, пока кастомный загружается. Устраняет FOIT (невидимый текст).
- Subset шрифтов: загружайте только нужные символы (латиница + кириллица). Инструмент: glyphhanger или fonttools.
- Используйте variable fonts — один файл вместо нескольких начертаний (regular, bold, italic). Экономия 30–50% суммарного размера.
CSS
- Critical CSS inline
- Стили «выше сгиба» (above-the-fold) встраивают прямо в <head> в <style> — браузер рендерит первый экран без ожидания загрузки внешнего CSS-файла. Остальной CSS загружается асинхронно.
- Минификация
- Удаление пробелов, комментариев, сокращение свойств. Cssnano или LightningCSS. Экономия 10–30% от исходного размера.
- Удаление неиспользуемого CSS
- PurgeCSS, UnCSS или встроенный механизм фреймворка (Tailwind purge). Особенно актуально при использовании Bootstrap, Material UI — они тянут тысячи неиспользуемых правил.
- Avoid @import в CSS
- CSS @import создаёт последовательные запросы: сначала загружается файл, потом браузер «видит» @import и начинает загрузку следующего. Используйте <link> теги для параллельной загрузки.
JavaScript: render-blocking и основной поток
JavaScript — главный враг Page Speed на современных сайтах. Он блокирует рендеринг, занимает основной поток, задерживает интерактивность. Цель: минимум JS в критическом пути, максимум — defer/async/dynamic import.
Стратегии загрузки
| Атрибут | Поведение | Когда использовать |
|---|---|---|
| Без атрибута | Блокирует HTML-парсинг, выполняется сразу | Только критичный инлайн-код |
| async | Загружается параллельно, выполняется по готовности (может прервать парсинг) | Независимые скрипты (аналитика) |
| defer | Загружается параллельно, выполняется после парсинга HTML | Большинство скриптов на странице |
| type="module" | Как defer по умолчанию + поддержка ESM | Современные ESM-скрипты |
Бандл и code splitting
- Code splitting: разделите JS на чанки — загружайте только то, что нужно для текущей страницы. В Next.js это происходит автоматически per-page.
- Dynamic import: import('module') для компонентов, которые не нужны при первой загрузке (модальные окна, вкладки, фильтры).
- Tree shaking: собирайте только реально используемый код. Webpack и Rollup делают это для ESM-пакетов. Проверьте: нет ли CommonJS зависимостей, которые ломают tree shaking.
- Анализ бандла: bundlephobia.com для проверки веса npm-пакетов, @next/bundle-analyzer для Next.js — показывает, что именно занимает место.
- Избегайте крупных монолитных библиотек: moment.js (67 KB) → day.js (2 KB), lodash → nanoutility, jQuery → нативный JS.
SPA и серверный рендеринг
Клиентские SPA (React без SSR, Angular, Vue с CSR) отдают пустой HTML и генерируют контент в браузере. Это приводит к высокому LCP и плохому Time to Interactive.
- SSR (Server-Side Rendering)
- Полный HTML генерируется на сервере. Браузер получает готовый контент немедленно. LCP, FCP и Lighthouse Score резко улучшаются. Требует гидрации на клиенте — учитывайте TTI (Time to Interactive).
- SSG (Static Site Generation)
- HTML генерируется на этапе сборки. Максимально быстрый TTFB и LCP. Подходит для контента, который меняется редко: блог, документация, лендинги.
- PPR (Partial Prerendering)
- Новинка Next.js 15: статическая оболочка страницы + потоковые динамические части. Статика отдаётся мгновенно с CDN, динамические данные стримятся по готовности.
Кэширование: браузер и CDN
Правильно настроенное кэширование — самая дешёвая оптимизация с максимальным эффектом для повторных визитов. Цель: все статические активы кэшируются на 1 год; HTML — кэшируется минимально или не кэшируется.
| Тип ресурса | Cache-Control | Стратегия инвалидации |
|---|---|---|
| JS/CSS с хешем (bundle.abc123.js) | max-age=31536000, immutable | Хеш меняется при изменении файла |
| Изображения | max-age=2592000 (30 дней) | URL с версией или Content Hash |
| HTML-страницы | no-cache или max-age=0, must-revalidate | Всегда проверяется у сервера |
| Шрифты | max-age=31536000, immutable | Хеш в URL или версионирование |
| API-ответы | Cache-Control: private, max-age=60 | Зависит от изменчивости данных |
- Content-based hashing (fingerprinting): Webpack, Vite, Next.js автоматически добавляют хеш содержимого к имени файла. При изменении кода — новый хеш, старый кэш не используется.
- ETag и Last-Modified: если клиент уже имеет ресурс, сервер отвечает 304 Not Modified без тела. Меньше трафика, но задержка сети всё равно есть.
- Service Worker: программируемый кэш на стороне браузера. Позволяет настроить сложные стратегии (Cache-First, Network-First, Stale-While-Revalidate) для PWA и офлайн-работы.
- CDN Cache-Control: используйте s-maxage для управления кэшем на CDN независимо от браузерного max-age. CDN кэширует дольше, браузер — короче.
Сторонние скрипты: главный скрытый тормоз
Сторонние скрипты (аналитика, чат-боты, пиксели, A/B-тестирование, виджеты) часто становятся главной причиной медленного TBT и INP. Среднестатистическая коммерческая страница загружает 15–30 сторонних скриптов.
Аудит сторонних скриптов
WebPageTest → вкладка «Third-party Summary» показывает, какой скрипт сколько миллисекунд блокирует основной поток. Типичные нарушители: Intercom, Hotjar, старые версии Google Analytics (gtag без async).
Отложенная загрузка
Загружайте некритичные скрипты с задержкой: setTimeout(loadScript, 3000) после load события. Пользователь успевает взаимодействовать со страницей до загрузки аналитики.
DNS prefetch и preconnect
<link rel="preconnect"> для доменов, к которым обращаетесь точно. <link rel="dns-prefetch"> для вероятных. Экономия: 100–300 мс на DNS lookup + TCP handshake для каждого стороннего домена.
Замена или удаление
Лучшая оптимизация сторонних скриптов — их удаление. Зачем платный чат-бот на всех страницах? Зачем 5 пикселей соцсетей? Аудит реально используемых скриптов часто выявляет 30–50% ненужных.