Комментарии 55
а если использовать Lit ? он по сути же добавляет реактивность, думаю конечно поверх этих всех костылей, но всё же
скорость должна быть поидее меньше там всё равно
хотелось бы сравнения, в общем
Реактивность может быть реализована с помощью внешних библиотек, например, mobx.
Код под спойлером
const { observable, autorun, action } = mobx;
class ReactiveCounter extends HTMLElement {
constructor() {
super();
// Создаём наблюдаемое состояние
this.state = observable({
count: 0,
});
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<div>
<button id="decr">−</button>
<span class="value" id="display">0</span>
<button id="incr">+</button>
</div>`;
this.displaySpan = this.shadowRoot.getElementById('display');
this.incrBtn = this.shadowRoot.getElementById('incr');
this.decrBtn = this.shadowRoot.getElementById('decr');
this.increment = action(() => {
this.state.count++;
});
this.decrement = action(() => {
this.state.count--;
});
this.incrBtn.addEventListener('click', this.increment);
this.decrBtn.addEventListener('click', this.decrement);
// Настраиваем реакцию: при изменении state.count обновляем текст
this.disposeAutorun = autorun(() => {
this.displaySpan.textContent = this.state.count;
});
}
// При удалении компонента из DOM отписываемся от реакций
disconnectedCallback() {
if (this.disposeAutorun) {
this.disposeAutorun();
}
this.incrBtn.removeEventListener('click', this.increment);
this.decrBtn.removeEventListener('click', this.decrement);
}
}
// Регистрируем кастомный элемент
customElements.define('reactive-counter', ReactiveCounter);если честно, выглядит ужасно больно, очень много бойлерплейта
mobx неплох, это единственная альтернатива $mol'у в плане реактивности
но $mol далеко не только про реактивность
Не знаю почему вас удивил низкоуровневый код на js. Это база.
не удивил
привык к другой абстракции просто
Скрытый текст
namespace $.$$ {
export class $bog_counter extends $.$bog_counter {
@ $mol_mem
count(next?: number) {
return next ?? 0
}
count_str() {
const val = this.count()
if (val === 3) $mol_fail(new Error('Three is not allowed!'))
return String(val)
}
incr() {
this.count(this.count() + 1)
}
decr() {
this.count(this.count() - 1)
}
}
$mol_view_component($bog_counter)
}
$bog_counter $mol_view
sub /
<= Decr $mol_button_minor
title \−
click? <=> decr? null
<= Value $mol_paragraph
title <= count_str \0
<= Incr $mol_button_minor
title \+
click? <=> incr? null

тут ошибка - такое же состояние как и любое другое, при нажатии на плюс или минус произойдет перерасчёт, и появится следующее значение

mobx тихо схавал ошибку, в результате пользователь видит
2, нажимает еще раз - видит снова 2 - нажимает еще раз - видит 4
что выглядит как баг
при этом ошибку если бы мы хотели исправить пришлось бы оборачиравать в try catch
Спасибо за публикацию! Полезно.
Добавлю.
Например, в такой наивной реализации свойства могут быть только строковыми.
Строковые, потому что вы setAttribute используете, что необязательно. А так, у классов веб-компонент возможности такие же, как и у обычных js-классов. Вот пример когда свойство - объект. Специально добавил connectedCallback, чтобы отобразить его в виде текстовой ноды.
class MyFoo extends HTMLElement {
connectedCallback() {
this.textContent = this.bar.foo;
}
bar = { foo: 1337 };
}
globalThis.customElements.define("my-foo", MyFoo);
const element = new MyFoo();
console.log(element.bar.foo);
// 1337
значит хорошие сапоги, надо брать(c)
Ну те придумали как всегда сферическую проблему и донкихотите?)
Зачем JSON хранить в атрибуте? Вас кто-то заставляет?
Чтобы не было конфликтов, достаточно, чтобы у тэгов был свой префикс для каждого модуля - и это нормально.
Ну и да, естественно, когда вы делаете дичь, ее трудно делать - и это тоже вполне нормально.
Веб-компоненты - это одно из самых ожидаемых и удачных нововведений (особенно с возможностью изоляции через shadowdom) в браузерах, и да, если пытаться не понимать их, и тыкать каменным топором, как вы привыкли - будет больно.
Я рассмотрел далеко не все проблемы веб-компонент
Вы рассмотрели лишь свое непонимание и старые подходы к новой технологии - не надо пинять на технологию, если руки кривые.
префиксы поддерживаются руками ? есть ли тут человеческий фактор ? человек не надёжен
может будут реальные аргументы ? без топоров и кривых рук
можем к примеру сделать две реализации и сравнить, сейчас это несложно с нейронками, как вам такой формат ?
Реальные аргументы про что? Про то, что в статье абсолютно надуманная дичь типа впихивания JSON в атрибуты? Для этого какие-то аргументы нужны, серьезно?
Что значит поддерживается руками? Это можно сделать автоматизировано без каких-либо проблем, в том числе и при сборке.
Можете даже свой кастомный префикс впихнуть в библиотеку, если необходимо и библиотека грамотно написана.
Внезапно использование внутри одного скопа одинаковых наименований приводит к конфликту наименований - как так?! Никогда такого ведь не было, и вот опять!
А если серьезно - а как должно было-бы быть? Браузер должен разруливать нейминг за программиста? )
Нейминг давно разрулен. MS это еще во времена СОМ сделала - все имена -это GUID. :)
У свидетелей веб-компонент универсальные ответы на претензии к скорости:
А вы не используйте аттрибуты.
А вы не используйте ShadowDOM.
А вы не разбивайте приложение на веб-компонеты.
Проще говоря: не используйте веб-компоненты, иначе получите тормоза даже на таком тривиальном интерфейсе, как у Ютуба.
В эталонном бенчмарке js-framework-benchmark реализация на Lit стабильно идет рядом с React и Vue по скорости рендеринга.
Иронично, что собственно компоненты там и не используются, если не считать однократный бутстрап приложения, конечно. Да и нашли на кого ровняться - вот вам принципиально недостижимая для веб-компонент эффективность:

Безотносительно вашей безграмотности в коде, приводить в пример скорости работы веб-компонент бенчмарк, где собственно веб-компоеннты и не задействованы - верх глупости. Особенно иронично, что в $mol используются только компоненты.
Ни бизнесу, ни, тем более, пользователю не нужны ваши честные 100К DOM элементов через минуту. Но если вы пройдёте ещё глубже по моей ссылке в Телеграм, то обнаружите, что прикрутить виртуализацию к чему попало не так-то просто, а если посетите ещё и портал так нещадно продаваемого вам велосипеда, то даже узнаете почему.
В вашем нейрослопе васм с тяжелыми вычислениями исполняется в основном потоке, а не в воркере. В принципе, это все, что читателям нужно знать про «ваши» комментарии.
Я бы предложил вам продолжить диалог лет через 5, когда вы хоть чему-то научитесь и поймёте, какую чушь сейчас несёте, да боюсь в век нейросетей это произойдёт примерно никогда.
У вас похоже контекстного окна не хватает домотать до конца статьи на MDN, где располагается информация о поддержке браузерами. В следующий раз, когда захотите испражниться, воспользуйтесь туалетом, а не интернетом.
Разумеется они проблему не решают, а лишь усугубляют. Ибо заставляют всех авторов компонент бороться с поведением по-умолчанию путем обмазывания всех элементов уникальными part-ами и километровыми exportpart-маппингами, чтобы потом навешивать на каждый из них свои стили через километровые селекторы.
бенч плох значит)
пользователю нужно что приложение работало быстро, а как не важно
виртуализация позволяет добиться этой задачи, странно что бенч её запрещает
Это буквально разные бенчи
Вы как будто на чемпионат по велогонкам на спорткаре приехали - а почему бы и нет, главное ж добраться первым
Пользователю плевать)
Так что аналогия не работает, в гонках пользователю не плевать
Классическая история в сравнениях $mol - все в одинаковых условиях, кроме, собственно, $mol.
Ничего личного, но, кажется, если человек не понимает, что в бенче все должны быть в равных условиях, то это профнепригодность уже
Не помню, чтобы я запрещал кому-то в своих бенчмарках виртуализировать рендеринг. Но если вы интересуетесь специальными олимпиадами, то предлагаю вам в своих запретить и VDOM, и IDOM, и пусть все пересоздают весь DOM с нуля, чтобы быть в по-настоящему равных условиях.
не не
это только в этом бенче на рендер так)
в остальных то одинаково
например как тут на глубокое сравнение обьектов, обычный js ( как и почти везде это js )
https://t.me/giper_dev/11/291
Ну, так-то можно отрендерить те же веб-компоненты на весь экран и по скроллу менять textContent. Но это другой бенчмарк будет.
абсолютный vendor lock-in
Страхи про vendor lock-in преувеличены. Любой фрейморк это vendor lock. Взять и переписать большой проект с React на Vue будет не сильно проще чем на $mol. Да и в целом экономически это часто не целесообразно, лучше новый проект на другой технологии начать и сравнить. Npm в моле не запрещён.
они ищут стандарт платформы, а не очередной проприетарный фреймворк
У mol лицензия MIT с начала существования, никакого проприоретатного ПО тут нет.
В моле используются те же самые стандарты. Точка.
Если коротко, вы описываете весь интерфейс на js. View.tree тут чисто для удобства
Да и "стандарты" - это рекомендации, не стоит себя ограничивать в поисках решений

отказ от нативной интероперабельности
Мол не отказывается от интерполаберности. Мол-компонент можно превратить в веб компонент и использовать его везде. Не очень полезно но можно. Банд в таком же формате как и у остальных
Зато вот внутри экосистемы мола "безшовность" работает гораздо интереснее. Можно по имени вытащить любой компонент из любого другого проекта. Как из UI кита. Даже из другого репозитория.
Нативная "безшовность" тоже по большей части миф. Одних веб компонентов зачастую недостаточно, иначе зачем lit ? А привязку к фрейморку мы уже обсудили
предсказуемая стоимость найма,
Это когда в разных компаниях на одну ту же позицию зп может быть как 200 так и 400 ? Миф какой то, товарищи. Разработчик на моле не будет получать в несколько раз больше сеньера из за другой технологии. Это как говорить что разработчик на solidjs будет получать больше ( или меньше ) чем на реакте. С чего бы? Задачи то одинаковые
стабильный фундамент платформы.
Мол живёт более 10 лет причем на versionless без ломаний обратной совместимости
В индустрии могут параллельно жить разные подходы. Отрицать это - обычный снобизм.
Согласен. Но у нас общая задача - нарисовать производительный приятный офлайн интерфейс для пользователя, согласны ? И $mol тут давно по всем параметрам выигрывает, так как поддерживает это всё из коробки.
Да, вы можете скачать либу для виртуализации и настроить воркеры. Только вам придется делать это на каждом проекте, руками, а человек ленив ( иначе у нас были бы только хорошие интерфесы, правда ? )
Поэтому так важно что бы это было из коробки по умолчанию, поэтому я топлю за $mol а не за любой другой фреймворк, где нужно прикладывать кратно больше усилий - для достижения таких же результатов
Автор как обычно пытается выставить другие технологии в плохом свете, потому что есть прекрасный $mol
Да нет
сделал тут сравнение https://github.com/b-on-g/todomvc-compare
на примере TodoMVC: $mol vs Lit vs Symbiote.js

Эти проблемы существуют только у вас в голове. Крупнейшие компании в мире успешно внедряют веб-компоненты и видят реальный рост производительности.
О, интерфейс Ютуба уже перестал лагать на отрисовке 9 карточек я так понимаю?

ну да, конечно
вот например автор solid.js говорит о том же самом
fundamental problem with Web Components is that they are built on Custom Elements.
Забавно, что вы привели ссылку на статью, как раз защищающую веб компоненты, где автор полемизирует с автором приведенной цитаты. Она даже называется "Веб компоненты - в порядке".
Ещё забавнее, что в конце он ссылается прекрасное эссе по теме: https://www.baldurbjarnason.com/2024/liskovs-gun/
сделал тут сравнение https://github.com/b-on-g/todomvc-compare

В реализации от ангуляра есть прикольный момент, когда компонент удаляется из дом они вызывают дестрой, видимо не знают в какой еще момент это сделать.


Что не так с веб-компонентами?