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

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

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

В данный момент, я являюсь тех-лидом небольшой группы энтузиастов, создающих инновационную открытую платформу для разработки веб-приложений. Мы пытаемся сделать, эту самую разработку, более простой и доступной. Это наша самая главная цель, как бы пафосно или наивно это не звучало. Мы хотим, чтобы создание веб-приложений стало более тривиальной задачей для дизайнеров, аналитиков, маркетологов, разработчиков для других платформ и стеков. В основе, мы используем существующие стандарты и проверенные технологии, такие как HTML, CSS, современный JavaScript, git, блокчейн, Smart CDN, нейросети... и, конечно, веб-компоненты.

Также, я специализируюсь на создании виджетов, микрофронтендов и библиотек для работы с ними. За моими плечами около 20 лет опыта в IT и немало решенных на практике задач. Думаю этого хватит, если кому-то недостаточно деталей, можно сходить по ссылкам в моем профиле, вступление и так получилось длинным. Давайте скорее перейдем к сути.

Веб-компоненты - это не замена вашему фреймворку

Многие попадают в эту ловушку, начиная сравнивать и противопоставлять веб-компоненты различным популярным библиотекам и фреймворкам. В итоге, эти многие, задаются вопросом: а зачем мне эти ваши нативные компоненты, если они, из коробки, не умеют делать того, что умеет, условный, React? Где реактивность? Где синтаксис шаблонов с привязками любых типов данных? Где работа с локальным и глобальным состоянием?

Этого всего нет, все верно. Но, вовсе не потому, что веб-компоненты плохие, а потому, что это не очередной хипстерский фреймворк, а часть современного DOM API, которая помогает решать некоторые, низкоуровневые задачи. И решать их блестяще, избегая создания лишних слоев абстракций.

Другими словами, веб-компоненты и <ваша_любимая_библиотека> - не конкуренты, а союзники в решении определенного класса проблем. А если вы любите строить свои велосипеды, то веб-компоненты - это отличная основа для велосипедостроения. Просто лучшая, на текущий момент.

Главное - это жизненный цикл

Повторю, потому, что это очень важно: главное - это жизненный цикл. С Custom Elements, вы обладаете бесценным знанием того, когда ваши компоненты появились у пользователя на экране. Не важно кто, как и в какой момент эти компоненты добавил, вы ЗНАЕТЕ что вам пора что-то с этим делать: инициализировать виджет, сделать дополнительный запрос, динамически подтянуть зависимость или ассет, "поздороваться" с другими элементами приложения... Да что угодно. Также, вы знаете, когда именно ваш компонент исчез и настала пора очистить память, "попрощаться" и прибрать за собой.

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

Композиция и разметка

Веб-компоненты очень хорошо дружат с, его величеством, HTML. Они, по сути, его органичная часть. А HTML - это альфа и омега всего веба.

Добавить, условный React-компонент на страницу, вы можете только в шаблоне React (JSX), или в его рантайме через внутренний API. Либо, вам нужно делать какой-то враппер, и активировать весь последующий воркфлоу.

А добавить Custom Element - можно как и куда угодно, от любого серверного шаблонизатора или реактивного шаблона на фронте, до статического HTML-файла. И это будет просто работать. Браузер сам запустит вашу логику в нужный момент. В этом плане, веб-компоненты - это отличное решение для добавления динамических элементов при JAMStack подходе.

Shadow DOM - это опция

Некоторые считают, что все, что находится внутри веб-компонента, автоматически попадает в "тень". Из этого, для этих некоторых, вытекают проблемы с индексацией поисковыми роботами и проблемы с внешней кастомизацией. И все это, тоже большое заблуждение.

Во первых, хорошей практикой считается не заворачивать индексируемый контент в Shadow DOM, а использовать для этого слоты и работать как с обычными потомками элемента.

А во вторых, Shadow DOM - это вообще не обязательно. Вы имеете полное право НЕ использовать эту технологию в тех случаях, когда, как вам кажется, она вам мешает. Тут я хочу сделать акцент, на том, что я не предлагаю полностью отказаться от использования Shadow DOM. Нет, это очень клевая штука, изучите ее обязательно. Но я за то, чтобы использовать теневую магию только тогда, когда вы сами хорошо понимаете зачем вы это делаете и как избежать проблем. Сила и ответственность, ну вы поняли.

Кстати, для тех, кто не знал, shadow root можно создать и у обычного элемента, например, div.

А про кастомизацию элементов с Shadow DOM я хочу написать отдельную статью.

Объектная модель

Custom Elements - это полноправные элементы DOM. Это значит, что они будут доступны через селекторы и что у них есть все свойства и методы обычных DOM-элементов. Это открывает богатые возможности для реализации решений со слабо связанной архитектурой и переносом многих взаимодействий на уровень стандартных браузерных возможностей.

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

Веб-компоненты - готовы к продакшн

Кто-то считает, что все, о чем мы тут говорим, это некая "сырая" технология, у которой есть проблемы с поддержкой. Ребята, где вы были 8 лет? Пожалуйста, зайдите на caniuse и проверьте сами. Да, некоторые браузеры, действительно, не поддерживают наследование от встроенных браузерных элементов. Но это совсем не критично и есть очень простые альтернативные методы работы с этими элементами. Все основные возможности - поддерживаются давно и везде, кроме, возможно, всеми заброшенных некро-браузеров.

Полезные ссылки

Библиотеки: Community: Base Libraries

Доки: Using custom elements

Комментарии (47)


  1. Synopticum
    19.09.2023 12:25
    +2

    Вопрос не совсем по теме статьи - существуют ли хорошие примеры UI-kitов на чистых веб компонентов без дополнительных абстракций типа lit или их аналогов?

    Грубо говоря, чтобы все было в одном стиле, и при этом можно было подключить, скажем мультиселект или датагрид одним-двумя импортами прямо в HTML?


    1. i360u Автор
      19.09.2023 12:25
      +4

      https://www.fast.design/ - есть такое. Оно?


      1. Synopticum
        19.09.2023 12:25

        Спасибо, изучу!


      1. Synopticum
        19.09.2023 12:25

        UPD. Интересно, правда через CDN можно подключить только все компоненты сразу, поштучно, кажется, нельзя.


        1. i360u Автор
          19.09.2023 12:25
          +1

          Мне лично в FAST не очень нравится то, что они примитивы типа кнопок в shadow root кладут, для меня это лишний оверхед. Но в целом, либа интересная и в ней реализовано много правильных идей.


    1. alexnozer
      19.09.2023 12:25
      +1

      А Lit - это достаточно тонкий утилити-слой для более удобной работы с веб-компонентами и лучшего DX. Я с удовольствием использую библиотеку shoelace.style, хоть она и использует Lit под капотом


    1. nin-jin
      19.09.2023 12:25
      +1

      Ну а я добавлю по теме статьи: автор почему-то постеснялся дать ссылку на упоминаемую им дискуссию.


      1. codegentop
        19.09.2023 12:25
        +2

        Полностью согласен с комментариями автора этой статьи, кажется, вы не совсем разбираетесь в этой теме.


        1. nin-jin
          19.09.2023 12:25

          Хороший аргумент, пригодится для дискуссий.


          1. codegentop
            19.09.2023 12:25
            +2

            Но ведь те же веб компоненты создают проблем больше, чем решают...

            Какие?


  1. Xao
    19.09.2023 12:25

    Всё у веб компонент хорошо, но…

    хотелось бы попроще создавать атрибуты и проперти - наверное, однажды решится с появлением декораторов

    почему нельзя создать `<some-component />` а надо именно `<some-component></some-component>`


    1. i360u Автор
      19.09.2023 12:25
      +1

      почему нельзя создать <some-component />; а надо именно <some-component></some-componen>;

      Это из-за механизма парсинга в браузере: до активации компонента браузер не знает, могут ли у такого элемента быть обычные потомки в дереве, и как дальше строить структуру документа. Поэтому, по умолчанию, требуется закрытие тега. До активации, веб-компонент это некий аналог тега <span></span>, а он тоже подразумевает закрывающий тег. Другими словами, для скорости, это как с парсингом JSON и запятой в конце.


  1. devlev
    19.09.2023 12:25

    Надо вспомнить, что когда только эти самые веб-компоненты появились, ими можно было пользоваться разве что для каких то демок поиграться. Были разные реализации в разных браузерах. Это все вставляло палки в колеса разработки. А потом появился React. И только потом настала смерть IE, а вместе с этим наступила эра когда веб-компоненты начали поддерживаться всеми браузерами. Но сейчас уже 2023 год, и вот я задаюсь вопросом, а что могут сделать веб-компоненты, что не может React? Shadow DOM у них есть, а если он мне не нужен?

    Мне кажется, что React как раз и послужил этаким "убийцей" веб-компонентов. Из мира React мне не разу не пригодилась эта технология. А любой велосипед можно сделать и на React, получится React-компонент.

    А вот не в мире React, когда я тут что-то сделал, но я не хочу чтобы другие стили на сайте у меня тут все не поломали, дай-ка я засуну все это в веб-компонент - Shadow DOMом едины. Такой подход имеет место быть. Но здесь же очевидны и другие проблемы, более высокого уровня, архитектурные.


    1. Synopticum
      19.09.2023 12:25

      Для меня важной фичей была бы возможность подключения компонентов любой сложности поштучно в пару <script> тегов, при этом не таща рантайм какого либо фреймворка. Но сколько не встречал готовых решений, везде вижу обвязки-абстракции (которые надо тащить точно также, как реактовый рантайм). Разве что более тонкие, но с явно менее удобные для разработчика по сравнению с React и др. фреймворками.


    1. i360u Автор
      19.09.2023 12:25
      +2

      а что могут сделать веб-компоненты, что не может React

      Статья же буквально об этом. Очень много чего React не может. Вы поймите, если среди ваших задач только работа с избранным вами на старте рантаймом - вам веб-компоненты вполне могут быть и не нужны вовсе. Если перед вами встанет задача композиции нескольких рантаймов (виджеты, микрофронты) - тут уже совсем другая ситуация. Ваша проблема описана в первом же пункте, вы сравниваете и противопоставляете конкретную либу и браузерный API и я пишу о том, что так делать не совсем корректно. А еще, React тяжелый и тормозной, и бывают случаи, когда это само по себе становится проблемой.


    1. alexnozer
      19.09.2023 12:25
      +3

      Веб-компоненты - отличное решение для дизайн-систем и ui-китов. Преимущества в том, что это нативные технологии и они работают в любом фреймворке (для реакта нужен враппер). В итоге один и тот же компонент дизайн-системы можно использовать на статичном HTML-лендинге, во Vue, Angular, React, Svelte и тд (что может быть актуально для микрофронтов).

      У веб-компонентов лучше перформанс, поскольку они близки к браузеру и их API про растают из C++ маппингов и нативного DOM API. И как сказано в статье, не нужно сравнивать их с фреймворками, они не противники, а союзники.


  1. nikis05
    19.09.2023 12:25
    +5

    Я один из «скептиков», попробую объяснить свою нелюбовь. Сразу оговорюсь, считаю, что веб-компоненты имеют свою область применения, но она ограничена.

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

    Ваш тезис:

    HTML - это альфа и омега всего веба

    я считаю ошибочным. HTML - это альфа и омега всего веба в той форме в какой он был задуман, то есть как всемирная база знаний в духе гигантской Википедии. Современный веб совершенно другой. Это платформа для запуска приложений, а не хранилище гипертекста. В современном вебе альфа и омега - это пользовательский интерфейс, а HTML - это не более чем промежуточная его репрезентация, клей между приложением и браузерным рендерером. Причем клей крайне корявый и неудобный, который мы вынуждены использовать по инерции. Приложение ведь можно например отрендерить на Canvas, и HTML тогда будет играть роль не более чем вынужденной входной точки. А бывают еще фреймворки типа Flutter или React, на которых одно приложение может таргетить несколько платформ сразу, и в таком приложении HTML будет просто implementation detail рендеринга под одну из платформ.

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

    И тут я считаю надо оговориться о модных хипстерских смузихлёбных фреймворках. Удивительно, но до сих пор можно иногда наткнуться на людей которые при слове «фреймворк» закатывают глаза и восклицают «о боже мой, очередной фреймворк, зачем они вообще нужны». Хочется спросить этих людей, а где вы были все эти восемь лет? Мне кажется, идея о том, что сколь либо сложное приложение проще, дешевле и удобнее всего писать на декларативном фреймворке с vDOM или его аналогом - это уже устоявшийся и проверенный временем консенсус. Уже сто раз наступали на эти грабли. Ну нет в природе более хорошего способа описывать пользовательский интерфейс, чем f(x) где x - состояние.

    Ну и о том где я считаю веб-компоненты можно использовать хорошо.

    1. Сайт (не приложение) с минимумом интерактивных элементов, где можно обойтись без декларативного фреймворка и при этом не сойти с ума;

    2. Когда вы вынуждены дружить свой новый код со старьем вроде Wordpress;

    3. Когда у вас беспорядочный зоопарк разных технологий в одном приложении (сейчас это называется модным словом «микрофронтенды»)


    1. Mr_FatCat
      19.09.2023 12:25
      +1

      Да, веб-компоненты "опоздали на поезд", но это не делает их ненужными. Технологии постоянно меняются, и то, что было актуально в 2015 году, может быть не таковым в 2023. Автор статьи предлагает рассмотреть альтернативу: сесть на новый высокотехнологичный, скоростной поезд, созданный с использованием новых корейских сверхпроводников. Ведь существуют молодые разработчики, которым навязывают один единственный путь, не упоминая о существовании альтернатив, в пользу своих старых привычек.


      1. codegentop
        19.09.2023 12:25
        +3

        Меня тоже бесит, что большинство курсов для новичков сфокусированы исключительно на React или других популярных фреймворках. Это как учить человека ездить на танке, когда ему нужен велосипед. Новичкам важно понимать базовые принципы, а не сразу погружаться в сложные экосистемы. Веб-компоненты могут быть отличным стартом для понимания, как устроен веб, без лишнего "шума" от фреймворков.


    1. i360u Автор
      19.09.2023 12:25
      +2

      Сразу оговорюсь, считаю, что веб-компоненты имеют свою область применения, но она ограничена.

      Именно об этом я и пишу. Как и абсолютно у любого API, у этого своя область применения и свои ограничения. Почему это вдруг делает его плохим - мне не понятно. Особенно в сравнении с попытками родить костыли, какие породили разработчики таких решений, как Next.js для создания плейсхолдеров и гидрации.

      я считаю ошибочным

      Любая веб-страница, буквально, начинается с HTML-файла. Любая статическая страница с сервера, это буквально, HTML. Мое утверждение про альфу и омегу - это не какая-то моя личная философия, это то, как оно работает, как на заре веба, так и сейчас.

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

      Использовать нативный браузерный DOM API - это грех? Ну ладно.

      vDOM или его аналогом - это уже устоявшийся и проверенный временем консенсус

      Очень спорно, особенно, если вам важна производительность. Это не только мое мнение, авторы кучи либ говорят о отсутствии vDOM как о достоинстве а не о недостатке.

      Ну нет в природе более хорошего способа описывать пользовательский интерфейс, чем f(x) где x - состояние

      На мой взгляд это просто огромное заблуждение всех, кто тащит функциональщину во фронт. Красота математической чистой функции тут ломается о необходимость синхронизации с DOM, то есть с реальным миром... в котором, к тому же, есть такие штуки как накладные расходы на аллокацию и очистку памяти для иммутабельных объектов. Повторюсь - если вам не важна производительность - ок.


      1. artdeco
        19.09.2023 12:25
        +1

        Ты 100% прав, я же добавлю, что математически чистая функция - это не так уж и приятно. Даже если взять реакт, скажем у компонента 10 детей, а если обновилось только 1 его свойство, которое затрагивает только 1 ребенка, нужно идти в каждого из ребенков и исполнять его как чистую функцию, чтобы смотреть, не нужно ли что перерисовать. Поэтому и говорят, что "реакт на самом деле не реактивен". Чистые функции для отрисовки UI, которые все так боготворят, это на самом чистый фаб, просто хак оттого, что никто не знает, как правильно сделать. не легче ли каждому компоненту иметь свои свойства, и если эти свойства меняются, давать ему перерисовывать только свое дерево, причем реально только в тех местах, где надо?


        1. nikis05
          19.09.2023 12:25

          не легче ли каждому компоненту иметь свои свойства, и если эти свойства меняются, давать ему перерисовывать только свое дерево

          Скажу по секрету, именно так оно и работает :) Дерево перерисовывается только вниз от компонента, у которого поменялся стейт. Поэтому если обновилось только одно свойство, которое затрагивает только одного ребенка, исполнять нужно будет только этого ребенка. Но с точки зрения разработчика это все равно выглядит как f(x).

          причем реально только в тех местах, где надо

          Для этого и есть vDOM, чтобы автоматически искать те места, где надо.


          1. artdeco
            19.09.2023 12:25
            +1

            Нет, я неправильно сказал, не своего "дерева", а только своего уровня в дереве, то есть не лезть в перерисовку детей вообще. То есть не "исполнять нужно будет только этого ребенка" как ты говоришь, а "исполнять нужно будет только этого ребенка и все его дерево". С другой стороны, можно сделать так, что если у ребенка что-то изменилось, он сам перерисует тот кусок, который изменился. vDOM - очень неэффективный способ решения этой проблемы. Места искать не нужно, они должны быть уже известны за счет того, что в идеале мы можем знать, какое свойство влияет на какую отрисовку.


            1. nikis05
              19.09.2023 12:25
              +1

              Есть данные, нам надо из них делать элементы, и обновлять элементы когда данные меняются. Есть ровно два способа как это сделать:

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

              2. Самим определить, каким образом изменения данных превращаются в изменения элементов. Тут есть два варианта, оба со своими издержками - либо императивная лапша, которую сложно писать отлаживать. Либо какие-то декларативные шаблоны, как в Svelte. Шаблоны будут ограничены в том, какие конкретно способы изменения данных они поддерживают, потому что иначе мы возвращаемся к варианту 1 и нам опять нужен vDOM.

              В первом варианте нам никак не избежать перерисовки родительского дерева при изменении данных родителя. Дерево ребенка можно и не перерисовывать, если его данные не поменялись, эта особенность не является свойством vDOM как такового. В React ее можно при необходимости обойти мемоизацией. А в Flutter / Dart есть еще такая штука как const expression, позволяющая не перерисовывать те части дерева, которые не меняются вообще никогда. Так или иначе, в подавляющем большинстве случаев, отрисовка виртуального дерева - пренебрежимо дешевая операция.


              1. artdeco
                19.09.2023 12:25
                +1

                есть в общем 4 варианта, когда что-то меняется:

                1. показываем/прячем элемент (возможно, с каким-то эффектом)

                2. добавляем / убираем класс элемента (.Hidden, .Shown)

                3. модифицируем аттрибуты элемента (включая стиль)

                4. Обновляем список, из которого берутся данные для отображения

                возьмем простой метод компонент:

                function Render({propA, propB, list}) {
                  // some hook calculations
                  var [b]=useSomething([])
                  return (<div data-a={propA} disabled={propB}>
                    {list.map(a=><ListItem item={a} b={b} />)}
                  </div>)
                }

                Это твой любимый "неимперативный" метод. Только дело в том, что он такой же неимперативный, как и недекларативный. Настоящий декларатив -- это CSS, ты прописал пару правил, они распарсились и показались тебе, при этом ты вообще не знаешь, как. Компоненты вроде реакта -- это не декларативный код. Декларативный код подразумевает, что ты задал какие-то правила, и они магическим образом показываются. В примере выше нет ничего магического: если изменилось свойство и нужно лишь поменять аттрибут "data-a", помимо VDom о котором ты говоришь, будет перевыполнен ВЕСЬ код как самого компонента, включая хуки (вся стена хуков), так и детей, который находятся в списке. Это друг ни разу не декларатив, это просто сотейник со спагетти. Я на 100% за то, что не нужно писать императивный код, потому что веб страницы - это тип систем, которые остаются запущенными, в отличие от вон ноймановских программ, которые получили input и отдали output. Тут нужны стратегии по data-flow, но реакт - это не лучшая стратегия. VDom вообще не нужен. Представь, что метод Render можно проанализировать заранее, и выяснить, что data-a зависит от свойства propA, и поэтому когда propA меняется, мы исполним только ту часть, которая бы была ответственна за это. То есть функция компонента разбивается на 3 рендера:

                function RenderA({propA}) {
                  return (<div data-a={propA} />)
                }
                function RenderDisabled({propB}) {
                  return (<div disabled={propA} />)
                }
                function RenderList({list}) {
                  var [b]=useSomething([])
                  return (<div>
                    {list.map(a=><ListItem item={a} b={b} />)}
                  </div>)
                }

                Каждая из функций делает только свою часть по отрисовке, и реагирует только на определенное свойство, от которого зависит. Это, конечно, возможно только если у нас уже есть стандартный Домовский элемент, которым можно манипулировать. И сделать это очень даже можно, если только перестать думать в "функиональном" стиле, который является тупиком и ничего по-настоящему интересного, как выше, не дает, а уж тем более не является декларативным.


      1. nikis05
        19.09.2023 12:25
        +2

        Почему это вдруг делает его плохим - мне не понятно

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

        Плюс я пытаюсь отрефлексировать на тему почему веб компоненты "недооценены", почему недополучили хайпа / внимания. На мой взгляд это потому что они не являются технологией, идущей в фарватере тренда, а являются технологией, делающей работу со всяким там легаси чуть менее невыносимой. Такие технологии полезны и нужны, но совершенно естественно, что они привлекают меньше внимания и интереса.

        Мое утверждение про альфу и омегу - это не какая-то моя личная философия, это то, как оно работает, как на заре веба, так и сейчас

        Не спорю, только вот я к этому факту отношусь как к досадному техническому ограничению, возникшему по историческим причинам. Поэтому и работать с ним надо соответствующим образом - стыдливо прятать под слоем абстракций, как это делают декларативные фреймворки, а не плясать от него, как это делают веб компоненты. Кстати, думаю, в ближайшие лет 10 мы с вами увидим постепенное выдавливание обязательного HTML из веба, как сейчас видим постепенное выдавливание обязательного javascript через WebAssembly.

        Использовать нативный браузерный DOM API - это грех?

        Не не, я этого не говорил. Я сказал что это грех в определенной ситуации, и четко описал, в какой. Если у вас реакт приложение, то навешивать руками обработчики, когда можно обойтись без этого - грех. Использовать нативные компоненты - тоже грех. Потому что это протечка абстракции. Посылать запросы к БД - грех? Конечно нет. Посылать запросы к БД из слоя презентации - грех? Еще какой. Тут то же самое.

        авторы кучи либ говорят о отсутствии vDOM как о достоинстве а не о недостатке

        Естественно, потому что vDOM не является и не может являться достоинством сам по себе, а является необходимым элементом декларативного фреймворка. Говоря метафорически, авторы таких либ продают инновационные автомобили, которые не потребляют бензина, не шумят и не выбрасывают углекислый газ. Только вот они умалчивают, что водителю их автомобилей придется самому крутить педали.

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

        Это описание применимо к любому программированию чего угодно.

        такие штуки как накладные расходы на аллокацию и очистку памяти для иммутабельных объектов

        Все говорят про эти накладные расходы, но я не видел ни одного приложения где рендеринг vDOMа был бы главным баттлнеком, помимо ситуаций когда это был какой-то легко исправляемый баг, либо синтетический пример по типу "меняем местами 40000 div'ов". Если у вас 40000 div'ов, у вас это и на чистом JS будет лагать, ну сделайте вы виртуализацию, благо в декларативных фреймворках она элементарно делается. Почему-то при этом никто не обращает внимания на реальные накладные расходы, в виде накладных расходов часов разработчиков, ковыряющих императивную лапшу в поисках бага.


        1. i360u Автор
          19.09.2023 12:25
          +2

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


          1. nikis05
            19.09.2023 12:25
            +1

            Спасибо, взаимно - буду ждать ответа :)


          1. Gary_Ihar
            19.09.2023 12:25
            +2

            Отмечу, что не менее приятно читать ваш диалог


        1. i360u Автор
          19.09.2023 12:25
          +1

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

          С этим не соглашусь. Мне кажется, тренды рожденные в экосистеме Реакта напрямую связаны с большим количеством "свежей крови" в индустрии. Поскольку это наше айти стало самым эффективным социальным лифтом, к нам пришла куча народа, которую пришлось как-то подключить к процессам. И Реакт стал такой адаптационной площадкой, где некоторые, весьма поверхностные, идеи и привычный для многих DX, стали стандартом. Но стандартом только внутри Реакт-загончика, вовсе не для всей веб-экосистемы. После Реакта появилась уже куча решений, которые активно набирают свою популярность, и многое там идет наперекор реактовским трендам.

          Но есть еще тренды платформы. Новые стандарты, которые принимаются консорциумом. Новые подходы (типа JAMStack), которые позволяют решать задачи более эффективно. И тут уже веб-компоненты становятся технологией на острие прогресса, а Реакт - тормозным легаси.

          Не спорю, только вот я к этому факту отношусь как к досадному техническому ограничению, возникшему по историческим причинам. Поэтому и работать с ним надо соответствующим образом - стыдливо прятать под слоем абстракций, как это делают декларативные фреймворки, а не плясать от него, как это делают веб компоненты.

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

          Когда-то давно, мне тоже казалось, что иметь для решения, по сути, одной задачи, целых три разных языка и подхода, таких как HTML, CSS и JS - это какой-то перебор и ужасное неудобство. Поверьте, очень многие инженеры пытались родить "правильную" и "современную" замену HTML. И я пытался. Мне казалось, что HTML - ужасно избыточен и добавляет оверхед даже тупо на уровне количества символов в документе. Сперва я пошел по пути разработчиков Svelte - пытался сделать создать какой-то компактный способ описания DOM в JS объекте и выяснил такую интересную и контринтуитивную штуку: HTML - оказался компактнее а нативный парсинг значительно быстрее, создания элементов из JS рантайма. Говоря о DX, можно отметить, что ментальные модели, стоящие за HTML - на порядок проще и доступнее для широкой аудитории, чем любые альтернативы на сегодня. Ох рано вы HTML хороните.

          навешивать руками обработчики, когда можно обойтись без этого - грех.

          Вам не обязательно навешивать что-то руками с веб-компонентами.

          Только вот они умалчивают, что водителю их автомобилей придется самому крутить педали.

          Вот это просто неправда. Со стороны пользователя либы, ваш воркфлоу вообще ничем принципиально не отличается в случае если у вас нет vDOM. Я сам разработчик такой либы. Со стороны, вы просто не увидите разницы, пока не напишите бенчмарк. А с бенчмарком, разница будет не в пользу vDOM, и разница будет большая. Для страничек с парой кнопочек и формой, может и не важно это. Но если вы начнете делать редактор каких-нибудь таблиц с кучей ячеек - вот тогда всплывет в полный рост.

          Это описание применимо к любому программированию чего угодно

          Ну значит, у функциональщиков проблемы не только во фронте.

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

          Кто мешает сделать декларативный фреймворк на веб-компонентах? Их и сделано уже дофига, в моей статье есть ссылка. Разница с другими лишь в том, что этим ребятам не приходится тащить дополнительную логику для реализации именно компонентной модели, они ее получают "бесплатно" и в более производительном виде, вот и все.


    1. DeusX
      19.09.2023 12:25

      со старьем вроде Wordpress

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


    1. nin-jin
      19.09.2023 12:25
      -2

      Очень часто люди путают HTML и DOM. На тему альфы и омеги у меня даже есть статья: Карго-культ HTML в современном фронтенде.


    1. isumix
      19.09.2023 12:25

      Во-первых, HTML это удобная текстовая репрезентация объектной модели документа. Во-вторых, я считаю что react-native и подобные ему гибридные подходы скоро уйдут. Так как они по сути являются попыткой пере-изобретения велосипеда истинно кроссплатформенной среды вэб броузера. Поводом их создания было недостаточное количество поддерживаемых фич и скорости работы броузера. С тех времен много воды утекло и теперь 90% нативных приложений может быть реализовано как PWA https://whatpwacando.today/


  1. gohrytt
    19.09.2023 12:25

    Пробовал atomico для сайта с простейшим роутингом парой инпутов и парой кнопок на каждой странице. shadowroot был каждые два шага вложенности, после чего было принято решение не вы... и взять реакт.


  1. artdeco
    19.09.2023 12:25

    да кому нужны ваши веб-компоненты, если главная проблема -- не сами компоненты и их стили, а общение между ними, протокол которого напрочь отсутствует как концепт в текущей html 5 модели веб-компонентов. что значит общение? вот есть кнопка, я ее нажал, я хочу, чтобы изменилось состояние другого компонента, например, кол-во кликов. А если кол-во кликов больше 10, то я хочу изменить еще другое свойство еще другого компонента. В первом вопросе поможет событейная модель: onClick -> component.incrementClicks(). Со вторым поможет только фреймворк, и в этом все горе, что в html 5 просто не продумана реактивность, которая свойственна всем persistent системам (то есть тем системам, которые запускаешь и они продолжают работают, а не просто выводят результат). Сколько бы ни пилили сами компоненты, пока не реализуют eventual transconsistency (правильное название реактивности) на уровне протокола, они так и останутся никому не нужны.


    1. i360u Автор
      19.09.2023 12:25
      +3

      Да кому нужны эти ваши болиды Формулы 1, если у них нет экскаваторного ковша?

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


      1. artdeco
        19.09.2023 12:25
        +2

        Что значит не предназначен? Взаимодействие между компонентами - это фундаментальная проблема пользовательского интерфейса. Есть 3 уровня для веб-разработки: презентация (стили, классы), интеракция с пользователем (нажал кнопку -> что-то произошло) и коммуникация (передать сообщение другому компоненту / получить сообщение от другого компонента), напр, вышел из системы - поле комментариев погасло. Как вы можете говорить, что API веб-компонентов не предназначен для обмена данных между ними? А что тогда предназначено? Вернее, то что вы говорите это на данном этапе правда, и в этом и есть проблема: что внешний вид / интеракции можно спокойно писать и на чистом HTML/JS, а вот реактивную коммуникацию между компонентами никто не потрудился устроить, которая является самой актуальной проблемой. Ну и зачем они тогда нужны без протокола коммуникации?


        1. i360u Автор
          19.09.2023 12:25
          +2

          Глобальная коммуникация - это вопрос архитектуры вашего решения. У вас есть миллион возможностей: событийная модель, глобальные хранилища с синхронизацией на колбэках и прочие варианты pub/sub, готовые либы для управления состоянием (тысячи их), синхронные и асинхронные пакетные обновления, работа через транзакции и очереди, привязка к вебсокетам... Повторюсь: вам дают точку сборки, которая позволяет реализовать нужный именно вам сценарий и принцип. Например, Custom Events чем не протокол? Вы хотите чтобы вам дали одну единственную правильную архитектуру для всех возможных типов приложений?


          1. artdeco
            19.09.2023 12:25

            во-первых, не глобальная коммуникация, а локальная, то есть компонент-компонент, а не компонент -> хранилище состояния -> компонент. у моих компонентов уже есть состояния, зачем мне создавать какие-то там хранилища, и через них обмениваться? во-вторых, событейная модель подходит не до конца, потому что она не реактивна, зачем мне подписываться на какие-то там события, если значение переменной в состоянии одного компонента напрямую, по формуле, зависит от значения состояния в другом компоненте? Из вашей логики, мол вот вам стандарт "веб-компонентов", который по сути своей не привносит ровным счетом ничего (что такое "точка сборки"), а чтобы решить реальную, насущую проблему - делайте что хотите. Да я хочу чтобы мне дали единственную правильную архитектуру, иначе зачем вообще тогда делать специальный стандарт компонентов, если потом все равно приходится к нему прикручивать базовую функциональность обмена сообщениями между ними?


            1. nin-jin
              19.09.2023 12:25

              Кстати, я как-то делал прототип реактивности для DOM. Не очень удобно, конечно, но даже в таком виде её в браузеры так и не завезли.


              1. Mr_FatCat
                19.09.2023 12:25
                +2

                Заметил, что вы много спамите ссылками на ваш сайт. Лучше бы это были ваши статьи на хабре, которым можно было дать соответствующую оценку.


                1. nin-jin
                  19.09.2023 12:25

                  Не люблю повторяться. Мне не нужна ваша оценка. Но если вам очень хочется, то в конце есть ссылка и на копию на Хабре.


                  1. Mr_FatCat
                    19.09.2023 12:25
                    +2

                    Не люблю повторяться. 

                    Странный у вас посыл... Вроде первый раз с вами разговариваем.

                    Оценки на хабре позволяют отсеивать дезинформирующий контент или продвигать полезный.


                    1. nin-jin
                      19.09.2023 12:25
                      -3

                      Да вы похоже и на Хабре первый день.


                      1. Mr_FatCat
                        19.09.2023 12:25
                        +3

                        Что с вами не так? Можно же посмотреть, что я 13 лет на хабре )))

                        Вы очень много спамите и отвечаете на вопросы ссылками на ваш сайт - это дурной тон на хабре.


  1. codegentop
    19.09.2023 12:25
    +2

    Классная статья! Круто разъяснил, что веб-компоненты — это не враги фреймворкам, а как раз помощники. Я сам часто использую веб-компоненты для создания виджетов. Они легко "втыкаются" в разные проекты и не создают проблем. С ними всегда понятно, когда что происходит, и это реально удобно. Плюс, они хорошо ладят с HTML и CSS, так что можно быстро и просто их настроить. В общем, с ними работать — одно удовольствие.


  1. isumix
    19.09.2023 12:25

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

    React кстати был не совсем совместим с вэб компонентами, также в нем дублируется логика жизненного цикла, и еще он тяжеловесен.

    Некоторое время назад я начал разработку легковесной библиотеки для создания и обновления DOM. Фундаментально она схожа с React, но без этих недостатков. Так что предполагаю что она могла бы быть идеальным помошником для написания вэб компонентов https://github.com/fusorjs/dom