Дайджесты новостей
Бесшовное оживление разметки в Preact 11 с новым ядром Hydration 2.0, прямой передачей ref и модульным стандартом ESM.

Preact 11: переписанная гидратация, автофорвардинг ref и переход на ESM

Борьба за миллисекунды загрузки интерфейсов на мобильных устройствах держит библиотеку Preact в топе предпочтений фронтенд-инженеров. С весом ядра всего около четырех килобайт этот инструмент предлагает виртуальный DOM и привычный React-синтаксис, спасая высоконагруженные виджеты, медиапорталы и микрофронтенды от раздувания клиентского бандла.

Разработка следующей мажорной версии библиотеки началась еще в 2020 году. Спустя шесть лет напряженного труда команда мейнтейнеров представила официальный релиз Preact 11. Это не просто минорная полировка, а фундаментальный пересмотр внутреннего рантайма: архитекторы переписали алгоритм гидратации серверного HTML, избавились от устаревшего синтаксического сахара и полностью перевели проект на современные стандарты сборки.

Hydration 2.0: почему исчезли сбои при оживлении разметки

Главной инженерной победой релиза стало новое ядро гидратации (Hydration 2.0). В десятой версии процесс сопоставления серверного HTML с клиентским Virtual DOM был хрупким: асинхронные границы Suspense требовали строго одного корневого DOM-узла, а малейшее расхождение данных приводило к сбросу дерева и повторному рендерингу с неприятным мерцанием экрана (layout shift).

В Preact 11 эти ограничения полностью устранены:

  • Компоненты внутри асинхронных границ Suspense теперь могут возвращать ноль, один или фрагмент из десятков элементов без риска уронить страницу.
  • Процесс оживления разметки больше не совершает деструктивных мутаций реального DOM во время загрузки динамических чанков (lazy), обеспечивая идеальную стабильность островной архитектуры в метафреймворках вроде Astro и Fresh.

Прощание с forwardRef и чистый формат ESM

С точки зрения повседневного написания кода Preact 11 устраняет главный раздражитель компонентной разработки — необходимость оборачивать функции в специальный метод forwardRef:

import { useRef } from 'preact/hooks';
import type { Ref } from 'preact';

interface CustomInputProps {
  label: string;
  ref?: Ref<HTMLInputElement>;
}

// В Preact 11 ref — это обычный пропс без громоздкой обертки forwardRef:
export function CustomInput({ label, ref, ...rest }: CustomInputProps) {
  return (
    <label className="flex flex-col gap-1 text-sm font-medium">
      <span>{label}</span>
      <input
        ref={ref}
        type="text"
        className="px-3 py-2 border rounded-md focus:ring-2 focus:ring-blue-500"
        {...rest}
      />
    </label>
  );
}

export function LoginForm() {
  const inputRef = useRef<HTMLInputElement>(null);

  return (
    <form onSubmit={(e) => e.preventDefault()} className="space-y-4">
      <CustomInput label="Логин" ref={inputRef} />
      <button
        type="button"
        onClick={() => inputRef.current?.focus()}
        className="px-4 py-2 bg-blue-600 text-white rounded"
      >
        Фокус на поле
      </button>
    </form>
  );
}

Пропс ref теперь передается напрямую в аргументы функции, как и любой другой параметр, что делает код чище и полностью гармонизирует его с современным стандартом React 19.

Второе важнейшее изменение — переход на распространение исключительно в формате ECMAScript Modules (ESM-only). Разработчики окончательно вырезали устаревшие сборки CommonJS (CJS) и UMD. В связке с современными сборщиками (Vite, Rollup, esbuild) это обеспечивает безупречный tree-shaking и мгновенный холодный старт приложений.

// client.ts
import { hydrate, h } from 'preact';
import { LoginForm } from './components/LoginForm.js';

const rootElement = document.getElementById('app-root');

if (rootElement) {
  // Hydration 2.0 оживляет серверный HTML без сброса DOM-дерева
  hydrate(h(LoginForm, null), rootElement);
}

Практические шаги перехода: что нужно учесть при обновлении

Мажорное обновление несет в себе несколько строгих требований, о которых важно помнить перед миграцией:

  • Библиотека окончательно отказалась от поддержки Internet Explorer 11 и требует наличия компилятора TypeScript версии 5.1 или выше.
  • Сравнение массивов зависимостей в хуках (useEffect, useMemo) переведено на семантику Object.is, что исключает скрытые баги со значениями NaN и -0.
  • Проектам со старыми тестовыми раннерами на базе Jest потребуется обновить конфигурацию для корректного чтения ESM-пакетов либо перейти на современный Vitest.

Preact 11 подтверждает свою репутацию бескомпромиссного инструмента для высокопроизводительного веба: сохранив рекордный размер бандла в 4 КБ, библиотека избавилась от легаси-балласта и обеспечила идеальный комфорт для современных фронтенд-команд.