Гидратация компонентов

Гидратация в SkateJS — это процесс связывания уже существующей в DOM структуры с функциональностью веб-компонента. Она особенно актуальна в сценариях серверного рендеринга, когда HTML создаётся на сервере, а на клиенте необходимо подключить логику компонента без повторной отрисовки.

Основные принципы

  1. Идентификация компонентов SkateJS использует customElements.define для регистрации компонентов. Если элемент уже присутствует в DOM, SkateJS способен его распознать и инициализировать, не заменяя существующий HTML. Это позволяет сохранять состояние и контент, созданный на сервере.

  2. Механизм гидратации Гидратация происходит автоматически при инициализации компонента через skate или define. Важно, чтобы HTML имел корректные атрибуты и структуру, соответствующую компоненту. SkateJS не удаляет существующие узлы, а лишь добавляет обработчики событий, наблюдателей свойств и привязывает рендер-функцию.

  3. Свойства и атрибуты При гидратации SkateJS синхронизирует свойства и атрибуты компонента. Если элемент имеет атрибуты, соответствующие наблюдаемым свойствам, их значения будут автоматически преобразованы в свойства компонента. Например:

    import { define, props, h } from 'skatejs';
    
    class MyComponent extends HTMLElement {
      static props = {
        title: props.string
      };
    
      render() {
        return h('h1', {}, this.title);
      }
    }
    
    define('my-component', MyComponent);

    Если в HTML уже есть <my-component title="Пример"></my-component>, при гидратации свойство title примет значение "Пример" и компонент отобразит его без перерендеринга всего содержимого.

Рендер и повторная инициализация

SkateJS применяет виртуальный DOM для управления обновлениями. При гидратации рендер вызывается один раз после привязки всех свойств. Повторная инициализация компонента на том же элементе приведет к ошибке DOMException: Failed to execute 'define', поэтому важно проверять, зарегистрирован ли компонент, прежде чем вызывать define повторно.

Особенности работы с серверным рендерингом

  1. Сохранение состояния Любые динамические изменения, внесённые на сервере (например, значения атрибутов, текст контента), сохраняются и не перезаписываются при гидратации.

  2. Подключение событий SkateJS связывает обработчики событий только после полной гидратации. Это обеспечивает корректную работу событий на уже существующих DOM-узлах.

  3. Асинхронная гидратация Можно отложить гидратацию до определённого момента, используя skate.hydrate() на контейнере:

    import { hydrate } from 'skatejs';
    
    const container = document.querySelector('#app');
    hydrate(container);

    Этот метод ищет все зарегистрированные компоненты внутри контейнера и инициализирует их, не трогая уже отрисованный HTML.

Оптимизация гидратации

  • Минимизация ререндеров: использовать атрибуты для передачи данных, которые не будут изменяться часто.
  • Избегание дублирующих компонентов: проверять наличие уже зарегистрированных элементов перед define.
  • Разделение на контейнеры: гидратировать только те части страницы, которые требуют интерактивности, оставляя статический контент неизменным.

Взаимодействие с другими библиотеками

SkateJS совместим с любыми библиотеками, создающими HTML на сервере. Например, при использовании Preact или React для SSR, можно рендерить HTML компонентов на сервере, а на клиенте гидратировать эти элементы с помощью SkateJS, обеспечивая полноценную работу событий и реактивных свойств.

Итоговые рекомендации

  • Структура HTML должна соответствовать компоненту и иметь все необходимые атрибуты.
  • Свойства и атрибуты компонента должны быть согласованы для корректной синхронизации при гидратации.
  • Для больших приложений рекомендуется гидратировать только интерактивные части, оставляя остальной HTML статическим.
  • Обработчики событий и наблюдатели свойств становятся активными только после полной гидратации.

Гидратация в SkateJS обеспечивает плавный переход от статического серверного HTML к полноценным интерактивным компонентам, минимизируя повторные рендеры и сохраняя состояние элементов.