Comments 6
https://habr.com/ru/articles/968384/#comment_29145688
У веб компонентов много проблем архитектурных, давайте лучше на $mol писать, те же веб компоненты, только сильно прокачаннее
Видимо надо ещё немного подождать, пока они до конца устаканяться
Тёма интересная и, возможно, когда-то пригодится. Но, пока, реального профита от этого не видно. Возможно, если нужен очень сложный компонент, который используется и здесь и там, это пригодится.
А, в общем, спасибо за статью.
Превосходная статья. Добавил в закладки. Несколько вопросов.
1) судя по коду, вы не используете attributeChangeCallback. Не рассматривали ли Вы такой алгоритм.
Создаем общую функцию рендера, в которой мы сравниваем значения атрибутов, и если изменились, только тогда меняем часть DOM. Ну и плюс у нас однозначно будет какая-то общая логика. Т.е. что-то такое:
```
render() {
if (this.hasChanged("attr1")) {
this.doSmth1(); // какая-то тяжелая операция
}
if (this.hasChanged("attr2")) {
this.doSmth2();
}
// общая логика для любого рендера
}
А в attributeChangeCallback мы добавляем батчинг операций с помощью очереди микрозадач. Что-то такое:
```
attributeChangedCallback(
name: string,
oldValue: string | boolean,
newValue: string | boolean,
) {
if (oldValue === newValue) return;
this.lastChangedAttr = name;
queueMicrotask(() => {
if (this.lastChangedAttr !== name) return;
// prerenderAttrs - Map, в которой хранятся значения атрибутов
// (синхронизированных свойств) ДО рендера
// сравнение изменений в функции рендера идет с соответстующим значение в нем
const noChanges = [...this.prerenderAttrs.entries()]
.every(([attr, value]) => this[attr] === value);
if (noChanges) return;
this.render();
this.lastChangedAttr = "";
this.prerenderAttrs
.forEach((value, attr) => this.prerenderAttrs.set(attr, this[attr]));
});
}2) насколько легко использовать adoptedStyleSheets при разработке? Насколько я помню, ссылку на соответствующий файл в девтулзах не найти (даже в FF). Не рассматривали ли использование какого-либо статического свойства 'defaultStyles`, в котором вы можете хранить, к примеру, тег style, ссылку на таблицу и т.п. Которое можно переписать на любом проекте (до инициализации компонента).
Превосходная статья.
Спасибо, приятно слышать.
Не рассматривали ли Вы такой алгоритм.Создаем общую функцию рендера, в которой мы сравниваем значения атрибутов, и если изменились, только тогда меняем часть DOM.
Нет. Тут дело видимо в некорректных ассоциациях. Веб-компонент, это не реакт компонент, ему не нужно «ререндерится». Более того, сам ререндер в каком-то реакте тоже вводит в заблуждение. В реальности (на примере реакта) все устроено так: рендерится компонент, элементы вставляются в DOM, последующие ререндеры это изменение свойств/атрибутов уже вставленных в DOM элементов.
Тоже с веб-компонентом. То, что вы подразумеваете под рендером это вставка в DOM, и это происходит один раз – element.shaddowRot.innerHtml = someHtml. Это все. Изменение атрибута это просто изменение атрибута. При использовании с тем же реактом, это означает что произошли какие-то изменения, реакт ререндерит то, что у него называется компонентом, что в действительности приводит к вызову setAttribute у нашего элемента (и у других в разметке).
А в attributeChangeCallback мы добавляем батчинг операций с помощью очереди микрозадач. Что-то такое:
Это ничего не даст кроме дополнительной сложности или потребления памяти.
2) насколько легко использовать adoptedStyleSheets при разработке?
Никаких проблем. В нем хранятся стили перенесенные из lightDom, то есть их можно смотреть там. При дебаге (по крайней мере в хроме) adoptedStyleSheets доступны для просмотра.
Не рассматривали ли использование какого-либо статического свойства
Конечно, это упомянуто в статье: loadCssFromUrls и loadCssFromDocumentStyleSheets. Первый как раз вставит импорты соответствующих ссылок во внутренний <style>.
Ultimate guide по веб-компонентам