Мы нашли у себя дефект, который стоил сайту всей предварительной отрисовки: одна ссылка в подвале заставляла React перерисовывать каждую страницу заново. Подвал общий, поэтому доставалось всем 174 страницам. Разбор целиком — с методом поиска, потому что метод здесь полезнее самой находки.
Что было сломано
В подвале компонент логотипа стоял внутри ссылки:
<Link href="/"><Logo /></Link>
А у Logo был свой href по умолчанию — тоже "/". То есть он оборачивал
себя во вторую ссылку. Получалось <a> внутри <a>.
Что с этим делает браузер
Такую вложенность браузер не строит вообще. Мы это проверили прямо сейчас, на живом движке браузера. Подали разметку:
<a href="/"><span>лого</span><a href="/">NEXFORCE</a></a>
И посмотрели, что получилось в документе после разбора:
<footer>
<a>
<span>
<a>
Ссылок осталось две, но они стали соседями, а не вложенными: браузер разорвал первую ссылку и начал вторую рядом. Вложенных не осталось ни одной.
Вот отсюда и берётся поломка. React отрисовал на сервере одно дерево, в документе оказалось другое — и он отказывается от серверной разметки целиком. В режиме разработки это написано словами: «There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering».
Ключевое здесь — the entire root. Не подвал, не одна ссылка, а весь корень страницы.
Как нашли
Это тот случай, ради которого техническое SEO вообще существует: дефект не
проявляется внешне — страница выглядит правильно, ссылки работают, ничего не
мигает. Единственный след — четыре ошибки в консоли на каждой
странице, коды #418 и #423.
Готовая сборка их не расшифровывает: React в production печатает минифицированные номера, по которым ничего не понять. Поэтому смотреть надо в режиме разработки — там та же ошибка написана человеческим текстом.
Как отличили свою поломку от давней
Это главная часть, ради которой стоит читать. Ошибки нашлись после дня правок, и первая мысль была очевидной: сломали сегодня.
Проверили её так: собрали проект на коммите до дневных работ и повторили тот же замер. Результат — ровно те же 16 ошибок на четырёх страницах. Значит дефект давний, к сегодняшним правкам отношения не имеет, и искать его в них бессмысленно.
Дальше поиск шёл уже по подозреваемому — по общей для всех страниц части, то есть по каркасу. Подвал нашёлся за минуты.
Правило, которое мы из этого вынесли: прежде чем искать причину, установите возраст дефекта. Одна пересборка на старом коммите отделяет «я только что сломал» от «оно так было всегда», и это разные поиски в разных местах.
Проверка сегодня
После правки в тот же день на пяти шаблонах локальной сборки было ноль ошибок в консоли. Мы перемерили это на живом сайте 4 сентября 2026 года:
| Страница | Ошибок в консоли | Из них про разметку |
|---|---|---|
| Главная | 0 | 0 |
| /ekaterinburg/ | 0 | 0 |
| /blog/ | 0 | 0 |
| /proverka/ | 0 | 0 |
| /seo/avtoservis/ | 0 | 0 |
| /slovar/konversiya/ | 0 | 0 |
Починка держится месяц.
Что забрать себе
- Проверяйте консоль на готовом сайте, а не только в разработке. Дефект ничем себя не выдаёт, кроме этих строк.
- Ищите вложенные ссылки.
<a>внутри<a>— самый частый источник таких рассинхронов, и в компонентном коде он получается случайно: обёртка ставит ссылку снаружи, компонент — внутри. - Считайте масштаб по каркасу. Ошибка в подвале или шапке — это ошибка на всех страницах сразу.
- Устанавливайте возраст дефекта до поиска причины. Сборка на старом коммите стоит пяти минут и экономит часы.
Это тот же класс работ, что и технические ошибки сайта вообще, и та же история, что с анимациями, прятавшими прочитанный текст: внешне всё в порядке, а замер показывает обратное. Как мы дважды ошиблись с замером скорости — в отдельном разборе.
