lenec ru

← все посты

Qwik framework: resumability вместо hydration — будущее фронтенда?

10K

Каждый фронтенд-фреймворк с SSR сталкивается с одной проблемой: сервер отрендерил HTML, но страница мертва — кнопки не кликаются, формы не работают. Чтобы оживить интерфейс, нужна гидрация: скачать весь JS, выполнить компоненты заново, привязать обработчики. Qwik предлагает радикальную альтернативу — resumability. Приложение не переигрывается с нуля, а продолжает работу с того места, где остановился сервер.

Проблема hydration: bottleneck для TTI

При гидрации фреймворк восстанавливает обработчики событий, дерево компонентов и состояние. Для этого скачивается весь код компонентов и выполняется заново:

  • TTI растёт линейно с размером приложения.
  • Дублирование работы — сервер уже выполнил компоненты, но браузер делает это повторно.
  • Весь JS загружается eagerly — даже код кнопки в футере скачивается при загрузке.

На мобильных устройствах гидрация может занимать 2-5 секунд. Пользователь видит интерфейс, кликает — и ничего не происходит.

Resumability: как работает Qwik

Qwik сериализует всё необходимое прямо в HTML. Браузеру не нужно ничего переигрывать — он продолжает (resumes) с того места, где остановился сервер. Три механизма:

1. Обработчики в DOM. Вместо привязки listeners через JS, Qwik записывает ссылки в атрибуты:

<button on:click="./chunk-abc.js#handleClick">
  Нажми меня
</button>

Глобальный Qwikloader (<1 КБ) перехватывает события и лениво загружает нужный чанк только при взаимодействии.

2. Ленивое восстановление компонентов. Дерево сериализуется в HTML-комментарии. Компонент восстанавливается только когда ему нужно перерендериться.

3. Сериализация состояния. Стейт сохраняется в JSON в HTML. Компонент восстанавливается независимо от родителя.

import { component$, useSignal } from '@builder.io/qwik';

export const Counter = component$(() => {
  const count = useSignal(0);

  return (
    <button onClick$={() => count.value++}>
      Клики: {count.value}
    </button>
  );
});

Суффикс $ — маркер для оптимизатора: «эту функцию можно вынести в отдельный чанк и загрузить лениво».

Qwik City: роутинг, loaders, actions

Qwik City — мета-фреймворк (аналог Next.js). Файловый роутинг, серверные загрузчики, actions для мутаций:

// src/routes/posts/[id]/index.tsx
import { component$ } from '@builder.io/qwik';
import { routeLoader$ } from '@builder.io/qwik-city';

export const usePost = routeLoader$(async ({ params }) => {
  const res = await fetch(`https://api.example.com/posts/${params.id}`);
  return res.json();
});

export default component$(() => {
  const post = usePost();
  return (
    <article>
      <h1>{post.value.title}</h1>
      <p>{post.value.body}</p>
    </article>
  );
});

Сравнение метрик Web Vitals

Resumability даёт преимущество на начальную загрузку. Сравнение для e-commerce (~200 компонентов):

Метрика          | Qwik    | Next.js 14 | Astro   | SolidStart
─────────────────────────────────────────────────────────────
TTI              | 0.8s    | 3.2s       | 0.9s*   | 2.1s
LCP              | 1.1s    | 1.4s       | 1.0s    | 1.3s
JS при загрузке  | ~2 KB   | ~180 KB    | 0 KB*   | ~95 KB
FID              | 12ms    | 85ms       | 15ms*   | 45ms

* Astro отлично работает для статики, но при добавлении интерактивности JS растёт. В Qwik объём JS при загрузке остаётся константным (~1-2 КБ) независимо от сложности страницы.

Когда выбирать Qwik

Идеальные use cases: e-commerce с интерактивными фильтрами и корзиной; контентные сайты с интерактивностью без жертв по TTI; приложения, критичные к производительности на мобильных.

Ограничения:

  • Молодая экосистема. Нет аналога shadcn/ui или Material UI для Qwik.
  • Ментальная модель. Суффикс $ и правила сериализации требуют привыкания. Не всё можно передать через границу сериализации.
  • Рынок труда. Вакансий с Qwik практически нет.

Вывод

Qwik — не эволюция гидрации, а её замена. Resumability решает фундаментальную проблему: зачем браузеру переделывать работу сервера? Для интерактивных SSR-приложений с критичным TTI — Qwik заслуживает рассмотрения. Для статики Astro проще, для SPA — React привычнее. Но идея resumability уже влияет на индустрию: React Server Components движутся в том же направлении.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.