Хотел, чтобы краулер доходил до каждого городского хаба каталога не только через sitemap. Городов со школами 4165, и ни одной обычной HTML-ссылки на них не было: выбор города работает на JS, в подвале — шесть популярных. Значит, нужна одна индексная страница, на которой каждый город — ссылка в исходном HTML.
Споткнулся на штатном компоненте ссылки Next.js. Страница с четырьмя тысячами таких ссылок в dev-сборке весила 13 МБ. Каждая ссылка — клиентский компонент: своя запись в RSC-пейлоаде на каждую, а в проде ещё и префетч на каждую. Четыре тысячи префетчей с одной страницы.
Решил проще, чем собирался. Обычные <a> вместо компонента — 8,6 МБ. Дальше выяснилось, что половину оставшегося веса несут не ссылки, а классы, повторённые на каждой из них: стили ушли на уровень списка — 363 КБ DOM. Прод-сборка: 1,3 МБ HTML, 180 КБ в gzip, ответ 0,1–0,2 с.
Чем плачу. На этой странице нет клиентской навигации: переход по ссылке — полная загрузка, и префетча, за который платил весом, тоже нет. Второй вариант — спрятать списки за раскрытием — я отверг: краулер должен видеть то же, что человек, а это значит весь список сразу, без отговорок про вес страницы.
Вывод, который я забираю себе: удобный компонент фреймворка имеет цену за штуку, и на четырёх тысячах штук эта цена становится видна в мегабайтах. Там, где страница ничего не делает в браузере, тег из стандарта дешевле компонента из фреймворка в десять раз.
#железо