День, когда кнопка стала проблемой зависимостей

Худшая ошибка фронтенда — это не сбой. Это обычная страница, которая перестает вести себя так, как привыкли пользователи.

Мы внесли безобидное изменение в интерфейс — и кнопка оформления заказа перестала реагировать на нажатие у части пользователей. Не у всех. Не во всех браузерах. Но этого оказалось достаточно, чтобы заявки в службу поддержки не выглядели как случайные и индивидуальные. Решение проблемы было не в бизнес-логике. Оно оказалось в графе зависимостей.

Обновление затронуло 900 записей в lock-файле (файле блокировки). Сам виджет состоял из восьми строк пользовательского интерфейса. Это несоответствие и перевернуло мое сознание. Мы больше не отлаживали компонент. Мы отлаживали платформу, которая продолжала меняться в процессе разработки.

После пережитого в ту неделю я перестал задаваться вопросом, какой фреймворк лучший. Я стал думать о том, какие части нашего пользовательского интерфейса смогут пережить следующую переработку.

Контракт, который уже предлагает браузер

Фронтенд-фреймворки отлично подходят для быстрой поставки продукта. Во что это выливается, выясняется потом, после бесконечных переделок. Каждый год появляется новый маршрутизатор, новая модель отрисовки, новый инструмент сборки. Враги — не React, Vue или Angular. Врагом становится необходимость постоянно переписывать интерфейс, который должен быть простым и стабильным.

Веб-компоненты меняют правила игры, потому что их контракт — сам браузер. Пользовательский элемент — тег. Его входы — атрибуты и свойства. Его выходы —  события DOM. Этому контракту все равно, кто его использует.

Можно рендерить один и тот же компонент на серверной странице, в устаревшем приложении или в современном одностраничном приложении. Компонент не запрашивает библиотеку состояний. Он запрашивает HTML.

Как выглядит успех в реальной кодовой базе

Веб-компоненты доказывают свою эффективность, когда один и тот же интерфейс нужно встроить в системы с разными технологиями.

У нас был маркетинговый сайт, внутренний дэшборд и встраиваемый партнерский модуль. Каждый из них находился в отдельном репозитории. У каждого были свои правила сборки. Мы трижды переписывали один и тот же виджет и все равно получали три слегка отличающихся друг от друга бага.

Затем мы создали его как веб-компонент. Когда он заработал с первого раза, мы сразу почувствовали облегчение, а система сборки перестала выдавать баги.

App Or Cms Or Dashboard
        |
        v
   <x-pay></x-pay>
        |
  Shadow Dom Boundary
        |
   Styles And Markup

После этого фреймворк стал просто деталью реализации. Продуктом стал тег.

Компонент с чистым интерфейсом

Компонент обеспечивает минимальный публичный интерфейс, скрывая сложность внутри и поддерживая коммуникацию через события.

<x-toggle on="0"></x-toggle>



<script>
class XToggle extends HTMLElement {
  static get observedAttributes() { return ['on'] }
  connectedCallback() {
    const r = this.attachShadow({mode:'open'})
    r.innerHTML = `<button id=b></button>`
    r.getElementById('b').onclick = () => {
      const v = this.getAttribute('on') === '1' ? '0' : '1'
      this.setAttribute('on', v)
      this.dispatchEvent(new CustomEvent('change', {detail:v}))
    }
    this.render()
  }
  attributeChangedCallback() { this.render() }
  render() {
    const b = this.shadowRoot.getElementById('b')
    b.textContent = this.getAttribute('on') === '1' ? 'On' : 'Off'
  }
}
customElements.define('x-toggle', XToggle)
</script>

Можете добавить этот тег в любое приложение. Слушайте событие изменения. Установите нужный атрибут. Это все. Никаких оберток, устаревающих со временем.

Именно благодаря этому команды чувствуют облегчение. Перестают спорить о подходах и начинают согласовывать контракты.

В чем веб-компоненты эффективнее

Веб-компоненты не являются каким-то новшеством. Просто экосистема вокруг них созрела. Браузеры стали стабильными. Модули стали нормой. Команды устали от постоянно меняющихся инструментов.

Фреймворки все еще лучше подходят для сложной навигации, интенсивной работы с состоянием и насыщенных клиентских взаимодействий. Веб-компоненты выигрывают в дизайн-системах, общих виджетах и любых элементах, которые встраиваются в разные среды. Они не пытаются все заменить. Они пытаются остановить «кровотечение».

Компромисс, с которым придется смириться

Выбор веб-компонентов означает работу на более низком уровне абстракции, близком к нативной платформе, которая предъявляет строгие требования. Нужен план для темизации. Стилизация в Shadow DOM может преподнести сюрпризы. Доступность зависит от вас, особенно управление фокусом и поведение с клавиатурой. Серверный рендеринг требует продуманной интеграции. Ничто из перечисленного не является невозможным. Это просто настоящая инженерия.

Я считаю, что этот компромисс стоит того, потому что наградой становится спокойствие. Когда придет следующая волна новых фреймворков, основной UI не «запаникует». Он останется как тег и будет выполнять свою работу.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи The Thread Whisperer: The End of the Frontend Framework? Why Native Web Components are Finally Winning

Предыдущая статьяАнализ тональности в 3 шага: использование quick_sentiments в Python
Следующая статьяJava и Spring Boot: 7 трендов, которые изменят бэкенд-разработку в 2026 году