Чтение сетевого водопада запросов
Теперь у нас есть протокол сравнения и понимание границ лабораторных данных. Начнём исследовать загрузку speed-lab с Network. Панель показывает запросы во времени и помогает ответить на конкретный вопрос: почему необходимый ресурс не был готов к показу страницы? Длинная строка сама по себе ещё не объясняет причину.
В варианте baseline изображение создаётся через JavaScript после учебной задержки 900 миллисекунд. Число выбрано для демонстрации позднего обнаружения и не является временем работы ProfessorWeb. Исходники автора не выполнялись; описанные наблюдения — ожидаемый ручной результат, который читатель должен сопоставить с собственной трассой и версией браузера.
Запрос начинается раньше передачи файла
У сетевого запроса есть несколько стадий. Браузер может ждать доступной возможности отправки, устанавливать соединение, отправлять запрос, ожидать первые данные и получать тело ответа. Для повторного соединения некоторые стадии будут короткими или отсутствовать. Поэтому две одинаково длинные полосы способны обозначать совершенно разные ограничения.
Откройте Network до перехода к документу. Выберите запрос HTML и вкладку Timing. Сначала ищем, какая стадия занимает время, затем проверяем связанные условия. Длительное ожидание первых данных не доказывает медленную генерацию HTML: между браузером и приложением находятся сеть и промежуточные узлы. У статической страницы тоже может быть поздний ответ. Интерфейс Network и Timing.
Получение тела ответа связано с объёмом доставки и доступной пропускной способностью. Но уменьшение файла не обязательно меняет ожидание первого байта. Если ресурс невелик и долго ждёт начала ответа, сокращение его размера способно почти не повлиять на общую задержку. Сначала локализуем фазу, затем предлагаем действие, относящееся именно к ней.
В HTTP/2 и HTTP/3 запросы могут использовать общую транспортную основу и выполняться с перекрытием. Поэтому общее число запросов не переводится напрямую в одинаковое число последовательных соединений. Однако ресурсы всё равно конкурируют за сеть и работу браузера. Нельзя ни объявлять любой дополнительный запрос дорогим отдельным соединением, ни считать параллельную доставку бесплатной.
Инициатор и зависимость
Инициатор показывает, каким путём браузер узнал о ресурсе. Изображение в исходном HTML может обнаруживаться при разборе документа; картинка, добавленная скриптом, становится известной позднее. Фоновое изображение в CSS зависит от получения и обработки стилей. Эти пути помогают увидеть причинную цепочку, а не просто список файлов.
В baseline задержанная вставка выглядит так. Это полный обработчик таймера из учебного проекта; переменная image существует только внутри него:
setTimeout(() => {
const image = document.createElement("img");
image.className = "hero";
image.src = "../assets/delivery-1200.v1.png";
image.alt = "Три стадии доставки: документ, ресурсы и отображение";
document.querySelector("#hero").replaceChildren(image);
}, 900);
Когда читатель выполнит стенд, запрос картинки ожидается после исполнения таймера, а инициатор связан с кодом. Фактическое начало не обязано точно совпасть с 900 миллисекундами: таймер задаёт минимальную задержку планирования, а не точное время выполнения. Если основной поток занят, обработчик может получить возможность работать позднее.
Для независимого сравнения скопируйте baseline и замените только эту вставку обычным img в HTML, не меняя размеры набора карточек и остальной код. Тогда исследуется путь обнаружения. Полный candidate меняет несколько свойств сразу и подходит для просмотра итогового прототипа, но не для доказательства эффекта одной строки.
Проверяйте наличие двойного запроса. Если старый обработчик остался, он может заменить раннее изображение новым ресурсом или создать лишнюю загрузку. Если добавлен preload с другим URL, браузер также способен получить ненужный файл. Успех эксперимента означает понятную цепочку одного нужного ресурса, а не исключительно его раннюю полоску.
Временные данные из браузера
Network удобен для визуального исследования. Для собственной краткой записи можно получить Resource Timing. Следующий диагностический фрагмент читатель выполняет после доставки ресурсов в Console; автор его не запускал:
const images = performance.getEntriesByType("resource")
.filter((entry) => entry.name.includes("delivery-"));
console.table(images.map((entry) => ({
url: entry.name,
start: Math.round(entry.startTime),
wait: Math.round(entry.responseStart - entry.requestStart),
receive: Math.round(entry.responseEnd - entry.responseStart),
transfer: entry.transferSize,
})));
startTime относится к временной шкале документа. Разность между responseStart и requestStart показывает соответствующий интервал запроса, а последняя разность — получение ответа в доступных записи границах. Это диагностическая выборка, не готовая система мониторинга. Поля для внешнего origin могут ограничиваться политикой раскрытия данных. PerformanceResourceTiming.
Нулевая передача не всегда означает пустой файл. Ответ мог прийти из локального кеша, а некоторые сведения могут быть закрыты для внешнего ресурса. Сопоставьте запись с Headers, колонкой Size и происхождением ресурса. Размер тела, переданные по сети байты и декодированный размер обозначают разные величины; перед сравнением выберите одну.
Перекрытие запросов и важный путь
Представим выдуманную учебную цепочку: HTML готов через 700 миллисекунд, изображение обнаружено через дополнительное ожидание 900, доставка заняла 400. Эти числа иллюстрируют зависимость, а не полученный результат. Уменьшение картинки сокращает лишь последний участок; перенос URL в HTML способен изменить средний. Оба действия нужно оценивать по собственной трассе.
Ресурсы нижних карточек могут загружаться параллельно с главным изображением. Если ускорить один необязательный файл, показ основной статьи иногда не изменится. Поэтому ищите ресурс, находящийся на пути к выбранному пользовательскому результату. Сортировка по размеру помогает найти большие файлы, но не определяет их влияние на этот путь.
И наоборот, маленький CSS-файл может оказаться существенным, если без него браузер не показывает нужное оформление. Из Network известно только получение файла. Нужно соединить водопад с Performance и кадрами: когда ресурс готов и когда результат действительно видим? Именно это различие станет предметом следующего урока.
Ошибка ответа как отдельное состояние
Перед сравнением длительности убедитесь, что оба запроса получили нужный ресурс. Быстрая страница ошибки или пустое тело не соответствуют успешно доставленному изображению. Проверьте статус, MIME и предварительный просмотр ответа. Если сервер перенаправил запрос, учитывайте цепочку отдельно: новый адрес способен добавить работу и изменить область кеширования. Сама короткая полоса ещё не говорит о полезном результате.
Сетевой журнал также может содержать запросы расширений и сторонних инструментов. Не приписывайте их автоматически приложению. Посмотрите origin и инициатора, сопоставьте с исходниками стенда. Чистое окружение полезно для контролируемого сравнения, а обычное окружение пользователя — для дополнительного исследования, но это разные наборы условий. Назовите, какой именно набор вы сейчас читаете.
При экспорте HAR помните, что настоящий журнал может содержать адреса с параметрами и сведения запросов. В локальном speed-lab таких пользовательских данных нет, однако привычка переносить чужой HAR в публичную задачу требует отдельного просмотра. Для объяснения механизма часто достаточно очищенного фрагмента одной цепочки. Сохраняйте данные, необходимые для вывода, без случайного распространения всей сессии.
В конце сохраните одну цепочку: документ → инициатор → нужный ресурс, условия кеша и предполагаемое ограничение. Если причина пока неизвестна, запишите две конкурирующие гипотезы и предложите наблюдение, которое их разделит. Такая заметка полезнее общего совета «сжать всё»: она направляет изменение в конкретную фазу и позволяет проверить, произошло ли ожидаемое действие.