Будущее фронтенда: хватит ли веб-платформы?
Представим, что в 2027 году браузер даёт нам все базовые компоненты интерфейса. Дизайнер собирает из них экран, общие дизайн-токены превращаются в CSS-переменные, и из этого получается работающий продукт. Нам больше не приходится в каждой компании заново писать выпадающий список.
С такого предположения я начал разговор с Алексеем Назаренко, Заром Захаровым, Вадимом Аркадовым и Павлом Малышевым. На мобильные платформы смотришь и думаешь: почему у них готовые элементы управления давно стали обычной частью разработки, а у нас всё ещё столько работы вокруг кнопки? Зар сразу уточнил, мечта это или прогноз. Пока мечта. Но платформа за последние годы заметно приблизилась к тому, о чём раньше мы могли только мечтать.
Браузеры успели измениться
Лёша Назаренко начал с привычного положения дел: HTML даёт нам input и select, а в продукте нужны вкладки, аккордеоны и более сложные элементы. Мы подключаем фреймворк, собираем дизайн-систему и дальше живём внутри неё. Представление о возможностях браузера при этом часто остаётся тем же, с которым мы начинали проект.
За последние несколько лет у браузеров появился общий способ сокращать расхождения. В Interop они выбирают области, над которыми будут работать в течение года, и проверяют результат общими тестами Web Platform Tests. Для разработчика это особенно ценно там, где сама возможность уже существует, но пользоваться ею мешает разное поведение движков.
Лёша связывал с этой работой ускорение внедрения новых возможностей. Например, осенью 2025 года он ждал скорого появления якорного позиционирования (Anchor Positioning) во всех основных браузерах. Отдельно мы говорили о времени между первым появлением возможности и достаточно широкой поддержкой: даже несколько лет теперь воспринимаются иначе на фоне того, как долго когда-то приходилось ждать Flexbox.
Ещё одно направление ведёт группа Open UI. Её участники изучают существующие библиотеки компонентов: какие элементы повторяются, как они себя ведут, что разработчики постоянно реализуют вручную. Из этих наблюдений вырастают предложения для платформы. У группы открытые обсуждения, в них могут участвовать и представители браузеров, и разработчики продуктов.
Лёша перечислял dialog, Popover API и стилизуемый select, а рядом с ними ещё обсуждаемые предложения для подсказок и ползунков с двумя ручками. Браузер постепенно забирает поведение, которое до этого приходилось собирать из div и обработчиков событий.
Со стилизацией тоже появилась возможность двигаться дальше. Лёша рассказал о предложении, которое представила Джен Симмонс: дать стандартным элементам управления режим без оформления операционной системы. Браузер оставляет поведение элемента, а его вид можно задавать через CSS. Стилизуемый select стал примером такого подхода, который хотелось распространить и на другие контролы.
Веб-компоненты развиваются параллельно. Базовые API уже есть, а вокруг них обсуждаются декларативное описание элементов и привязки данных. В JavaScript идут свои предложения, в том числе сигналы. Лёша видел в этом возможность собирать дизайн-системы ближе к платформе, с меньшей зависимостью от конкретного фреймворка.
На самой конференции был и практический пример: команда Едадила рассказывала о переходе с React на Lit и веб-компоненты, после которого улучшилась производительность.
Диалог, на который не получилось перейти
Вадим Аркадов занимается UI-китом Авито. Его ответ на эту картину был очень конкретным: команда попробовала заменить собственный диалог нативным и не смогла.
Задача выглядела скромно. Уже есть прямоугольное окно с управлением фокусом, хочется поменять реализацию внутри, чтобы пользователи и остальные разработчики ничего не заметили. Новых возможностей от продукта не требовали. Критерий приёмки: сохранить существующее поведение.
С inert у него было более предметное замечание. Атрибут исключает поддерево из взаимодействия, а Вадиму хотелось задавать область, внутри которой взаимодействие разрешено. В существующей структуре документа приходилось обходить соседние части и следить, чтобы ничего не пропустить. Особенно когда модальные окна в разных местах приложения устроены по-разному.
Лёша напомнил о верхнем слое и поведении модального dialog. Но Вадим говорил именно о текущей кодовой базе, где нельзя одним решением переустроить все окна. Здесь они смотрели на задачу с разных сторон: один начинал с возможностей платформы, другой с условий замены работающего компонента.
Похожее расхождение обнаружилось вокруг disabled. Отсутствие фокуса у отключённой кнопки не всегда совпадает с тем, как команда хочет объяснять пользователю недоступное действие. Такие детали и превращаются в собственный код. Их трудно увидеть, если смотреть на компонент только как на прямоугольник нужного цвета.
Два с половиной года для браузера и для бизнеса
Павел Малышев сомневался прежде всего в сроках. Для стандарта несколько лет могут быть хорошим темпом. За это же время коммерческий проект успевает появиться, закрыться или полностью переписаться. Обещание подходящего компонента через два с половиной года мало помогает команде, которой он нужен сейчас.
К этому добавляется опыт предыдущих ожиданий. У браузеров разные интересы, а согласование занимает время. Разработчики уже привыкли решать задачи своими средствами и не готовы заново строить планы вокруг обещания, что теперь все наконец договорятся.
Зар добавил ещё одну задержку: даже готовую возможность нельзя немедленно использовать, если у продукта остаются пользователи старых браузеров. Некоторые команды с трудом отходят от ES5. Новая реализация рядом со старой означает дополнительную работу, а отказ от старой поддержки требует решения бизнеса.
Лёша объяснял медленное движение стандартов обратной совместимостью и необходимостью договориться о поведении. Павел возражал, что новый элемент вроде диалога мог бы сразу учесть практики, давно существующие в библиотеках. Спор не сводился к тому, хороши ли стандарты. Вопрос был в том, успевает ли их общий ответ за конкретной задачей продукта.
Общие примитивы вместо ещё одной дизайн-системы
Лёша предложил промежуточный путь, о котором писал автор Atomic Design Брэд Фрост. Пока стандартизация движется своим темпом, сообщество может сделать общую библиотеку примитивов интерфейса на веб-компонентах.
В этой идее нет обязательного цвета кнопок или единого вида всех сайтов. Компоненты предоставляют поведение, оставляя оформление разработчику. Такой подход обычно называют headless. Команда берёт, например, комбобокс, добавляет свои стили и при необходимости расширяет поведение. Исправления можно возвращать в общую библиотеку.
Польза веб-компонентов здесь в том, что базовый элемент не привязан к одному фреймворку. Вместо отдельных реализаций для React и Angular можно заниматься одной основой. При этом продуктовая дизайн-система остаётся у компании: общая библиотека не должна решать, как выглядит карточка товара Авито.
Павел услышал в этом знакомое обещание. Во многих компаниях, где он работал, особенно в заказной разработке, однажды появлялась идея общего UI-кита для всех проектов. Хотелось один раз вложиться и дальше экономить. По его опыту, результат редко соответствовал ожиданиям. Почему библиотека, которая должна подойти всему интернету, избежит той же сложности?
Зар привёл другую историю. Он предлагал команде, поддерживающей отдельные дизайн-системы для Angular и React, посмотреть на Stencil. В ответ услышал опасение, что тогда часть разработчиков окажется не нужна. Позже у них появилась ещё и реализация для Vue. Лёша предложил направить эти силы на качество общей библиотеки, в том числе на доступность. Но этот обмен хорошо показывает, что выбор технологии упирается и в устройство команды.
Второе возражение Зара касалось самих требований. Open UI собирает пересечение возможностей популярных библиотек. Однако особенности, которые в это пересечение не попали, тоже возникли не случайно. У Material Design одни дополнения, у Mantine другие, у отдельного продукта свои. Если каждый начнёт дописывать общий компонент под себя, не получим ли мы множество расходящихся копий?
Я предложил посмотреть на собственные UI-киты с той же стороны: выделить нижний слой поведения, который было бы проще постепенно заменять. Ведь многие компоненты мы начали писать именно потому, что их не хватало в браузере. Если платформа догоняет, полезно хотя бы проверить, какую часть своей реализации можно убрать.
Где кончается примитив
Павел сформулировал более жёсткое возражение: настройка универсального компонента может оказаться сравнима по трудоёмкости с написанием узкого решения с нуля. Чем больше случаев компонент поддерживает, тем больше документации и условий нужно изучить всем его пользователям.
Например, обычному аккордеону достаточно раскрывать секции. Но кому-то понадобится переставлять их перетаскиванием. Если заложить это в общий элемент, сложность достанется и тем, кому перемещение никогда не понадобится. Если не заложить, нуждающаяся в нём команда снова будет дописывать своё.
Лёша разделял базовый примитив и более сложный продуктовый компонент. Платформа не обязана поставлять все варианты карточки товара. Она может дать работающий доступный элемент, на который уже можно опереться. Настроить его внешний вид и собрать из нескольких элементов более сложную конструкцию всё равно придётся разработчику.
Это особенно заметно на селекте. У списка вариантов есть управление с клавиатуры, работа со скринридером и состояние раскрытия. Когда всё это уже реализовано, задача стилизации существенно отличается от создания собственного комбобокса на div.
Зар возражал, что даже у кнопки множество вариантов: иконка слева или справа, разные виды оформления, соседство с другими элементами. Лёша отвечал композицией. Иконку можно передать внутрь кнопки, расположение изменить CSS. У веб-компонентов для содержимого есть слоты, для оформления внутренних частей — CSS Shadow Parts. Не каждое отличие требует нового параметра в универсальном компоненте.
Разногласие осталось в допустимой степени свободы. Павел предлагал пересмотреть сами требования: если в веб-приложениях мы согласимся чаще пользоваться стандартным поведением, платформе будет гораздо проще закрыть наши задачи. На мобильном устройстве нас устраивает системный выбор даты; в вебе мы часто начинаем с требования сделать совершенно свой.
Лёша тоже считал ограничения полезными, особенно когда они защищают доступность. Но не предлагал всем оставить серые кнопки. Ему хотелось получить базовое поведение, которое можно оформить под продукт, не переписывая его целиком.
Что потребуется генеративному интерфейсу
Зар посмотрел на стандартизацию с другой стороны: если у интерфейса появится полный понятный API, не сможет ли ИИ собирать всё сам? Здесь к нам присоединился Глеб Михеев.
Глеб сразу возразил против обещания результата по щелчку пальца. Для модели не так существенно, лежат ли компоненты в браузере или в собственной библиотеке компании. Гораздо важнее, сформулированы ли правила их использования. Что с чем сочетается? Какие ограничения есть у продукта? Как устроен дизайн и какие решения команда считает допустимыми?
В привычной работе часть этих знаний живёт в людях. Разработчик посмотрел на соседние экраны, поговорил с дизайнером, понял подход и продолжил. Чтобы передать ту же работу модели, требования приходится выражать явно. Наличие кода компонентов не заменяет этой части дизайн-системы.
Глеб ожидал, что в ближайшие годы будет меняться и сам способ взаимодействия с продуктом. Вместо заранее проложенного пути по экранам человек сможет сказать, что ему нужны к среде белые с красным кроссовки для тенниса, назвать любимые марки и получить подходящий ответ.
Такой интерфейс, по его предположению, будет собираться под запрос и предпочтения человека. Одному удобнее сравнительная таблица, другому краткий ответ. Речь шла о вариативном интерфейсе во время использования продукта, а не только о генерации кода при разработке.
Глеб видел зачатки этого в чатах с моделями: к тексту добавляются таблицы, ссылки и карточки товаров. Он предлагал уже сейчас описывать принципы дизайн-системы так, чтобы ими можно было пользоваться без постоянных устных пояснений.
Я всё же вернулся к платформе: даже такому общению понадобятся элементы интерфейса. Генеративность меняет способ их выбора и сборки, но сама по себе не отвечает на вопрос, откуда брать их поведение.
Зачем UI-кит большой компании
Павел предложил временно убрать из обсуждения стоимость написания кода. Допустим, создавать компонент каждый раз почти бесплатно. Останется ли причина хранить общую библиотеку?
Вадим назвал редизайн. Когда над продуктом работают многие команды, изменение общего оформления не должно превращаться в отдельную переделку каждого экрана. Ещё важнее единое поведение. Если сложную форму собирают десять команд и каждая пишет свой селект, у пользователя окажутся десять разных способов взаимодействия в одном продукте.
В UI-ките собрана экспертиза, которой не обязательно в равной степени владеют все разработчики. Он помогает сохранить узнаваемый продукт и общие решения. Даже если значительная часть реализации переедет в браузер, компании останутся нужны собственные правила и настройки поверх неё.
Зар вспомнил Bootstrap: можно было взять готовую основу, поменять цвета и собрать сайт. Вадим согласился, что на старте этого может хватить. По мере роста компании появляются другие потребности. Проблема не в том, что готовые библиотеки никогда не работают, а в том, как меняется цена отдельных решений вместе с продуктом.
Павел продолжил свою мысль через Svelte. Когда писать сложные интерфейсы вручную стало неудобно, мы создали фреймворки. Затем Svelte предложил описывать компонент декларативно, а обычный JavaScript получать после компиляции. Человек задаёт намерение, компьютер выполняет механическую работу.
В моделях Павел видел следующий шаг: теперь код может писать нейросеть. Если правила оформления и поведения хорошо описаны, она, по его предположению, сможет каждый раз генерировать нужную реализацию и сохранять согласованность между экранами. Тогда часть аргументов в пользу переиспользования готового кода ослабевает.
Это не отменило возражения Вадима. Дешёвый код сам по себе ещё не обеспечивает общего поведения. Но спор обозначил разные места, где участники предлагают хранить договорённости: в готовой библиотеке, в возможностях платформы или в явно описанных правилах для генерации.
Неудачный опыт тоже стареет
Мне кажется, за привычным стеком легко перестать замечать, что браузер уже умеет сделать за нас. У команды есть React, свой UI-кит и работающий процесс. На повторную проверку платформы приходится отдельно находить время.
История с диалогом это хорошо проявила. Вадим пробовал переход примерно за год до нашей встречи. У команды Едадила, которая обсуждала свой опыт на конференции, переход получился. Я предположил, что они могли проверять разные состояния одного и того же элемента: за это время его поведение продолжали дорабатывать.
Лёша напомнил об изменениях вокруг закрытия диалогов и CloseWatcher API. Это не доказывало, что теперь Авито сможет переехать без затруднений. Но отрицательный результат годичной давности тоже не описывает платформу навсегда.
С обратной связью ситуация похожая. На сцене несколько раз звучало: почему разработчиков не спросили? Между тем существуют открытые обсуждения и опросы вроде State of HTML, в которых можно описать недостающее поведение. Участие требует времени, но ожидать подходящего результата, совсем не сообщая о своих условиях, тоже странно.
К концу разговора позиции остались разными. Зар готов внедрять новое, когда увидит пользу для своего случая, и считает регулярные обновления важными. Он вспомнил проект на AngularJS: команда двигалась по версиям постепенно, тогда как другие компании однажды пропустили обновление и надолго застряли.
Павел ждал пересмотра требований к кастомизации и продолжал считать генерацию обычного JavaScript перспективным способом уменьшить зависимость от библиотек. Вадим собирался снова сравнивать нативные элементы с текущими требованиями продукта. Ему также хотелось более явного способа различать новые и старые варианты поведения платформы.
Для Лёши ждать общей переломной точки уже не нужно: он использует dialog, details и summary, когда они решают задачу и подходят по поддержке браузеров. Если необходима дополнительная совместимость, отдельно оценивает возможность полифила.
Я вспомнил jQuery и другие инструменты, которые когда-то закрывали пробелы браузеров. Со временем многие из этих задач стало можно решать средствами платформы. С компонентами необязательно произойдёт один большой переход, после которого мы выбросим все библиотеки. Но открыть свой UI-кит и проверить, какую часть кода уже можно не поддерживать самим, можно и до 2027 года.