awesome-everything EN
↑ Обратно к восхождению

Браузер и фронтенд-рантайм

Цена гидратации: selective, progressive, острова, resumability

Суть Почему полная гидратация дорогая, как selective hydration и острова сокращают объём гидратации, и как resumability полностью устраняет переисполнение.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 16 min

Страница новостной статьи: 2 000 слов текста, один бокс комментариев, кнопка лайка. Классическая полностраничная гидратация гоняет фреймворк по всем 2 000 словам текста — делая текст без какой-либо интерактивности «интерактивным». Бандл больше, чем нужно, и длинная задача гидратации блокирует главный поток, взрывая INP. Есть лучшие варианты.

Почему гидратация дорогая. Гидратация примерно удваивает работу рендера — дерево рендерится один раз на сервере и фактически рендерится снова на клиенте. Но это хуже простого удвоения, потому что клиентский рендер гоняется на устройстве пользователя, которое может быть средним телефоном на порядок медленнее вашего сервера. И это всё JavaScript на главном потоке: скачать бандл, распарсить и скомпилировать его (работа V8), потом гонять дерево компонентов и цеплять обработчики. На большом приложении это сотни миллисекунд — секунды времени главного потока, во время которых страница выглядит готовой, но не готова. Всё это окно — «зловещая долина» SSR — страница нарисована и выглядит интерактивной, пользователь пытается взаимодействовать, и ввод отбрасывается или встаёт в очередь за длинной задачей гидратации, взрывая INP.

Full vs selective гидратация. Классическая гидратация React — полная и нетерпеливая: всё приложение гидрируется одним блокирующим проходом до того, как что-либо станет интерактивным. React 18 ввёл selective hydration: с границами Suspense части дерева гидрируются независимо, и React приоритизирует гидратацию того, с чем пользователь только что взаимодействовал. Если пользователь кликает по ещё-не-гидрированной секции, React гидрирует эту секцию первой. Гидратация становится прерываемой — может уступить вводу посреди прохода. Selective hydration не убирает суммарную цену; она переупорядочивает её.

Спектр гидратации — от полной до нулевой

Полная гидратация (классический React)
Гидрирует всё дерево в один блокирующий проход. Ничего не интерактивно, пока вся страница не закончит. Бандл включает код каждого компонента.
Selective hydration (React 18 + Suspense)
Части дерева гидрируются независимо. Взаимодействие пользователя приоритизирует ту границу. Прерываемо — уступает вводу. Та же суммарная цена, лучший порядок.
Архитектура островов (Astro, Marko)
Страница — статический HTML по умолчанию. Только интерактивные компоненты («острова») шлют JS и гидрируются. Статический текст: ноль JS, никогда не гидрируется. Задержка: client:visible, client:idle.
Resumability (Qwik)
Никакой гидратации. Состояние приложения + расположения обработчиков сериализуются в HTML. Клиент возобновляется из сериализованного состояния, цепляет обработчик только на первом взаимодействии. Стартовый JS ≈ 0.

Progressive hydration и архитектура островов. Более глубокий фикс — гидрировать меньше. Архитектура островов (Astro, Marko, Fresh) стартует от противоположного дефолта: страница — это статический HTML, и только конкретные интерактивные компоненты — «острова» — шлют JavaScript и гидрируются. Пост блога на 95% текст: с островами эти 95% шлют ноль JavaScript и никогда не гидрируются, и только бокс комментариев и кнопка лайка несут JS. Каждый остров гидрируется независимо, и ему можно сказать, когда (client:visible гидрирует при скролле в зону видимости, client:idle когда главный поток свободен).

Resumability: пропуск гидратации совсем. Qwik доводит идею до предела через resumability. Вместо переисполнения дерева компонентов на клиенте, чтобы пересобрать состояние и обработчики, Qwik сериализует всё состояние приложения — включая то, какой обработчик к чему прицеплен — в сам HTML. Клиент не перерендеривает, чтобы гидрироваться; он возобновляется с сериализованного состояния, цепляя обработчик только когда пользователь реально взаимодействует с этим конкретным элементом. Стартовый JavaScript приближается к нулю независимо от размера приложения. Компромисс — более сложный формат сериализации и фреймворк, построенный вокруг него с нуля.

Викторина

Что архитектура островов делает иначе, чем классическая полностраничная гидратация?

Викторина

Страница полностью нарисована и визуально завершена, но тап по кнопке в первые 2 секунды ничего не делает. Какая метрика это ловит и в чём причина?

Закончи аналогию

Qwik избегает переисполнения дерева компонентов на клиенте. Вместо этого он сериализует всё состояние приложения — включая то, какой обработчик к чему относится — в HTML, и клиент подхватывает ровно там, где сервер остановился, цепляя обработчик только на первом взаимодействии. Как называется этот безгидратационный подход?

Выбери лучший вариант

Контентный сайт: длинные статьи (большей частью текст) с боксом комментариев и несколькими интерактивными виджетами. Выберите подход рендеринга и гидратации.

Вспомните перед уходом
  1. 01
    Каковы четыре этапа стоимости гидратации на главном потоке?
  2. 02
    Как selective hydration меняет опыт пользователя по сравнению с полной гидратацией?
  3. 03
    Каков дефолтный посыл архитектуры островов и чем он отличается от дефолта полной гидратации?
Итог

Стоимость гидратации состоит из четырёх частей — скачать, распарсить/скомпилировать, исполнить, прицепить — все на главном потоке, все после того, как страница нарисована. Бандл на 500 КБ — это не просто 500 КБ сети; это сотни миллисекунд parse-compile-execute на телефоне. Зловещая долина: страница выглядит интерактивной, но ввод отбрасывается, потому что длинная задача гидратации владеет главным потоком — полевой INP. Selective hydration React 18 делает цену прерываемой и приоритизированной, но не сокращает суммарную. Архитектура островов атакует суммарную, гидрируя только интерактивные части — текстоёмкая страница с островами шлёт ноль JS для текста. Resumability (Qwik) полностью устраняет переисполнение: состояние и расположения обработчиков сериализуются в HTML, и клиент возобновляется из этого сериализованного состояния с нулевым стартовым JavaScript независимо от размера приложения.

Связанные уроки
встречается в267
Продолжить восхождение ↑Hydration mismatch: причины, обнаружение и правило детерминизма
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources4
expand
  1. 01
  2. 02
  3. 03
  4. 04

Trademarks belong to their respective owners. Editorial reference only.