[Lv2] Основы Lifecycle и Hydration в Nuxt 3
Понимание границ lifecycle и поведения hydration критично, чтобы избегать проблем рассинхронизации SSR и клиента.
1. Фокус на интервью
- Различия lifecycle на сервере и на клиенте
useStatevsrefв SSR- Типичные причины hydration mismatch и их исправления
2. Границы lifecycle в Nuxt 3
В SSR-режиме:
setup()выполняется на сервере и на клиентеonMounted()выполняется только на клиенте- Browser API должны быть защищены для клиентского выполнения
<script setup lang="ts">
if (process.server) {
console.log('Server render phase');
}
onMounted(() => {
// Client only
console.log(window.location.href);
});
</script>
3. Почему возникает hydration mismatch
Типичные причины:
- Рендер слу чайных значений (
Math.random()) во время SSR - Рендер time-dependent значений (
new Date()) без синхронизации - Обращение к browser-only API во время серверного рендера
- Разные условные ветки на сервере и клиенте
4. useState vs ref в SSR
ref— локальное реактивное состояние экземпляра компонентаuseStateсериализует и гидратирует состояние через SSR-границу
const counter = useState<number>('counter', () => 0);
Для общего состояния с учетом SSR предпочтителен useState.
5. Практика предотвращения mismatch
- При необходимости оборачивайте browser-only UI в
ClientOnly - Переносите browser API в
onMounted - Обеспечивайте детерминированные начальные значения рендера
- Явно разделяйте ветки SSR и клиента (
process.server,process.client)
6. Процесс отладки
- Воспроизводите mismatch при полном обновлении страницы
- Сравнивайте серверный HTML и hydrated DOM
- Поэтапно отключайте подозрительные динамические фрагменты
- Подтверждайте стабильность финального рендера при медленной сети и cold load
Краткое резюме для интервью
Я рассматриваю SSR и клиент как две фазы выполнения. Делаю начальный output детерминированным, использую
useStateдля общего SSR-состояния и изолирую browser-only логику в клиентские хуки. Это предотвращает hydration mismatch и делает рендер предсказуемым.