Оценка PageSpeed — это модель, а не замер
Почему страница открывается за 2,4 секунды, а PageSpeed пишет 12,8: как устроена проверка, какой телефон и какую сеть она изображает и одно правило, из которого следует почти вся оптимизация.
Почему страница открывается за 2,4 секунды, а PageSpeed пишет 12,8: как устроена проверка, какой телефон и какую сеть она изображает и одно правило, из которого следует почти вся оптимизация.
КБ × 8 ÷ 1600 — и вы знаете, сколько секунд добавит к LCP то, что попало в окно первой отрисовки. Шрифты на 2 МБ дали 10,3 с при отчёте 10 523 мс. Как пользоваться и когда формула не сходится.
Одна команда, JSON-отчёт и скрипт на двадцать строк — и видно, какие файлы попали в окно первой отрисовки и сколько секунд они стоят в оценке. Локальный прогон дал 69 при 69 в PageSpeed.
Оценка плавает на ±10 баллов, а изредка один прогон выдаёт Speed Index в 10 раз хуже обычного. Как мерить сериями, какие прогоны выкидывать и три способа обмануть себя ещё до замера.
Заблокировали видео — LCP стал хуже: 16,2 с против 15,1. Вывод «видео ни при чём» оказался ложным: оно занимало 706 КБ из 960 в окне первой отрисовки. Почему блокировка меняет саму страницу и как проверять вину правильно.
Наблюдение на каждом кадре показало задержку 7448 мс при настоящих 1499. curl -I проверял не тот кэш, массовый обход мерил сам себя, а первый же запрос «чинил» холодные страницы. Как не обмануть себя своим зондом.
Шрифты, видео в карточках, ленивые блоки, картинки без размеров, CSS и соседние слайды — где мы находили вес, тянувший оценку PageSpeed вниз, как узнать каждый источник в отчёте и сколько он стоил.
Когда открывать загрузку тяжёлого: отрисовка И load, досрочно по действию, потолок 4 секунды. Две грабли, готовый код и результат: каталог 69 → 100, товарная 77–83 → 96–97 — без единого спрятанного блока.
Скрипты с defer запускаются до первой отрисовки — слайдеры и замеры держали белый экран 2,5 секунды. Пауза в один кадр перед инициализацией: товарная 92 → 95–98, первая отрисовка 2531 → 1376 мс.
Ворота после отрисовки поставили на наблюдатель, а фоновая догрузка обгоняла отрисовку на 600 мс и приносила в окно 1,2 МБ. Как найти второй путь загрузки и закрыть его, не потеряв блоки для людей и поисковиков.
259 заходов поискового робота за неделю — и ни одного запроса за содержимым ленивых блоков. Почему робот не видит блоки, которые грузятся при прокрутке, как это проверить и как починить, не потеряв в PageSpeed.
Превью в карточках каталога (706 КБ из 960 в окне), программный «клик» по постеру (3,4 МБ всем подряд) и фоновый ролик секции (2157 КБ на 185-й миллисекунде). Как находили и как лечили: 97 / 99 / 99.
Баннер загружается за 180 мс, а PageSpeed пишет «задержка отрисовки элемента 2040 мс». Так проявляется анимация появления на первом экране. Как её найти, как лечить без потери дизайна и родственная ловушка со стилями в ленивом файле.
content-visibility (292 → 286 мс, оценка та же), урезание DOM шаблонов, блокировка подозреваемых, top → transform (CLS 0,176 → 0,153) и font-display: optional. Почему не сработало и что сработало вместо.
Одна строчка в компоненте подвала — и сборка прелоадит всё семейство: 40 файлов, 2062 КБ до первой отрисовки, LCP 12,5 с. Как найти ловушку одной командой и как чинить: каталог 68 → 98.
В файле subset-*.woff2 — 1092 символа, из них 247 вьетнамских, а русскоязычному сайту нужно около трёхсот. fontTools: 45 КБ → 19 КБ на начертание, шрифты главной 333 → 172 КБ. Команда, диапазоны и проверка без потерь.
Набор символов для сабсета шрифта — из всего контента сайта: 204 символа, среди них ⌀ ≈ − ● ₽ №. Скрипт для WordPress, проверка «ни одной потери» и сюрприз: в полужирном Open Sans нет знака рубля.
Без прелоадов страница вживую рисовалась быстрее (1668 против 2056 мс), а оценка падала с 95–97 до 92–93. Почему так, как модель считает цепочку обнаружения шрифта и когда прелоада, наоборот, не хватало: 95 → 99.
Системный шрифт уже веб-шрифта: «Прицеп» 349 px против 417, и при подмене страница вырастала на 142 px — на iPhone это видно как «ползущий» экран. size-adjust и ascent-override, главная грабля (+94 px) и как проверить.
Bold и ExtraBold одним файлом, 47 КБ ради одного заголовка, три семейства без единого использования и «жирный», нарисованный браузером. Чек-лист из пяти пунктов и что должно остаться после аудита.
Без размеров вёрстка прыгает (CLS 0,33 → 0 после правки), а ленивая загрузка тянет картинки в окно первой отрисовки. С размерами — две ловушки: карточки втрое выше и сдвиг из-за размеров коробки вместо файла.
Меню, вкладки, фильтры: картинки в скрытых элементах Chrome грузит сразу, несмотря на lazy. 27 КБ скрытого меню на каждой странице и 94 КБ декора, который не показывается нигде. Как найти одной строкой и как лечить.
Лента в одну колонку (774 → 513 КБ до отрисовки), слайдер у края экрана, соседние слайды (335 ↔ 432 КБ на одном билде) и lazy на главной картинке — +1,8 с к загрузке. Что делать в каждом случае.
Функция переносит src и srcset в data-атрибуты в выводе любого плагина или слайдера, скрипт возвращает их после первой отрисовки. Одна разметка для всех, кэш не ломается. Окна: 6885 → 274 КБ, 2546 → 387 КБ.
О фоне браузер узнаёт поздно, у него нет ни lazy, ни fetchpriority, ни srcset. Обложки-фоны дали 2,7 с «задержки загрузки» — после перевода на img с object-fit страница выросла с 77 до 92, а мобильный размер файла срезал вес втрое.
webp на качестве 80 вышел тяжелее jpg (40–95 КБ против 31–60). Под затемнением 50 % качество 50 неотличимо — постер 110 → 34 КБ. А зернистый кадр не берёт ни шумоподавление, ни качество 30 — помогает только ширина.
PageSpeed эмулирует экран плотностью 1,75, и srcset с 1x/2x отдаёт ему двойной файл — «изображение больше, чем нужно». Разделение через media="(min-resolution: 2dppx)": претензий 8 → 0, вес 702 → 420 КБ.
Форматы делаются в фоне, а страница кэшируется раньше — и неделю отдаёт PNG на 122 КБ при готовом AVIF на 14 КБ рядом. Как поймать (curl, а не Lighthouse), как лечить за 0,5 мс на страницу и сколько стоит AVIF для сервера.
Дважды встроенный CSS делал хуже, и мы откатывали. Один раз — товарная 80 → 88, первая отрисовка 1286 → 209 мс при обещанных отчётом 150 мс. Чем отличались эти случаи и как понять, нужен ли инлайн вашей странице.
Стили для широких экранов выносятся в отдельный файл с атрибутом media, и телефон перестаёт их ждать: Speed Index 4,4 → 1,8 с, задержка отрисовки LCP 1870 → 270 мс. Как это устроено и три грабли, включая молча выключившееся разделение.
Два правила на 48 байт (min-width 381 и 441 px) опустили порог десктопного файла, и телефоны снова ждали его — 450 мс из 850. Плюс каскад: правило из отдельного файла побеждает базовое ровно с ширины порога.
Виджет звонка на 641 КБ и счётчик с картой кликов давали TBT 3 секунды, а без них оценка поднималась с 67 до 90. Как загружать сторонний код после первого действия посетителя — с готовым кодом и честной ценой подхода.
API Яндекс Карт грузился на каждой странице с формой — 465 КБ и 350 мс блокировки. Почему внешний модуль сборки грузится не по import(), как написать свой загрузчик и почему большой запас наблюдателя тянет карту в первый экран.
Плеер YouTube, VK или Rutube грузит мегабайты до нажатия «плей». Плитка с превью и iframe по клику — ноль чужих скриптов до действия. Как запустить ролик с первого клика на каждом хостинге и грабли: голый id, второй домен VK, Rutube без параметров.
$ tail -f /blog
Пишу разборы по скорости сайтов, кэшу и разработке — на живых проектах и с цифрами. Подпишитесь, и ссылка на новую статью придёт сразу после выхода. Без рекламы и спама, отписаться — в один клик.
или на почту