Комментарии 34
Если вы говорите про быстродействие — то где у вас инструменты, работающие на скорость обновления страницы? Оптимизировать создание 10К веб-компонентов, если уж они начнут тормозить — далеко не так проблемно (например: выкинуть веб-компоненты и переписать всё то же на ванильном html), как организовать хорошие схемы обновления, при котором изменения в развесистом многоуровневом стейте на 10К ключей не приведут к перерисовке всей страницы, если изменится что-то касающееся только корневого элемента. Или парочки элементов где-то посреди длинных и больших ветвей.
Хвалиться тем, что вы быстро создаете веб-компоненты — сомнительное достижение. Тем более, что веб-компоненты пока что всё равно гораздо более медленные, чем обычный DOM, и в критичных случаях оптимизация до упора — неизбежно выкинет и сами компоненты.
Где освещение вопросов компоновки элементов? Практически любые серьезные случаи вёрстки требуют циклов, которые у вас реализованы максимально примитивно (Изменились данные? Зафигачим новый innerHTML!), а ради чего-то непримитивного предлагается пойти почитать кусок исходного кода и поразмышлять о том, как оно работает. А работает оно всё равно очень странным образом, добавление или удаление одного элемента из массива — перерисует вообще всё. Не очень понятно, где там performant.
А еще чуть более серьезные случаи часто требуют выражения через рекурсию (или нагораживание костылей ради того, чтоб от рекурсии избавиться, но у вас-то для людей всё написано, верно?) — про неё вообще примерно никак не упомянуто.
Стилизация: тут нам сходу предлагается принять в объятья shadow DOM, который в настоящий момент убог и не масштабируется. Стилизация компонентов с верхнего уровня через переменные — в реальности работает только тогда, когда эти компоненты никто кроме вас не потребляет, и наперед известно, что вообще вам понадобится перекрашивать, а что — никогда нет.
Ну и в 2020 году это всё написано в JS (с многочисленными // @ts-ignore в коде, что отдельно доставляет).
Нет, мне конечно тоже не нравится, что парни, делающие LitElement — категорически не хотят выкидывать из него полифиллы и прочую рухлядь, но это далеко не так страшно, чтоб ради победы над этим делать очередной очень велосипедистый велосипед.
PS: Всё вышенаписанное — это, к слову, не попытки придраться к чему-нибудь, а те проблемы, которые у меня как у фронтэндера уже больше пяти лет вызывают максимальную боль; и соответственно на эти аспекты инструментов я и смотрю в первую очередь.
Хвалиться тем, что вы быстро создаете веб-компоненты — сомнительное достижение. Тем более, что веб-компоненты пока что всё равно гораздо более медленные, чем обычный DOM, и в критичных случаях оптимизация до упора — неизбежно выкинет и сами компоненты.
Где освещение вопросов компоновки элементов? Практически любые серьезные случаи вёрстки требуют циклов, которые у вас реализованы максимально примитивно (Изменились данные? Зафигачим новый innerHTML!), а ради чего-то непримитивного предлагается пойти почитать кусок исходного кода и поразмышлять о том, как оно работает. А работает оно всё равно очень странным образом, добавление или удаление одного элемента из массива — перерисует вообще всё. Не очень понятно, где там performant.
А еще чуть более серьезные случаи часто требуют выражения через рекурсию (или нагораживание костылей ради того, чтоб от рекурсии избавиться, но у вас-то для людей всё написано, верно?) — про неё вообще примерно никак не упомянуто.
Стилизация: тут нам сходу предлагается принять в объятья shadow DOM, который в настоящий момент убог и не масштабируется. Стилизация компонентов с верхнего уровня через переменные — в реальности работает только тогда, когда эти компоненты никто кроме вас не потребляет, и наперед известно, что вообще вам понадобится перекрашивать, а что — никогда нет.
Ну и в 2020 году это всё написано в JS (с многочисленными // @ts-ignore в коде, что отдельно доставляет).
Нет, мне конечно тоже не нравится, что парни, делающие LitElement — категорически не хотят выкидывать из него полифиллы и прочую рухлядь, но это далеко не так страшно, чтоб ради победы над этим делать очередной очень велосипедистый велосипед.
PS: Всё вышенаписанное — это, к слову, не попытки придраться к чему-нибудь, а те проблемы, которые у меня как у фронтэндера уже больше пяти лет вызывают максимальную боль; и соответственно на эти аспекты инструментов я и смотрю в первую очередь.
0
где у вас инструменты, работающие на скорость обновления страницы?
Странно, что вы их не заметили. github.com/foxeyes/holiday-benchmark/blob/master/app/main.js#L22 — тут есть пример обновления, и это обновление, происходит значительно быстрее чем у того-же LitElement.
Хвалиться тем, что вы быстро создаете веб-компоненты — сомнительное достижение
Отчего же сомнительное? Вы серьезно?
Тем более, что веб-компоненты пока что всё равно гораздо более медленные, чем обычный DOM
Это с чего вдруг? Из бенчмарков видно, что это не так. Уж точно не так категорично, ибо создание дополнительных узлов со стилями внутри Shadow DOM — конечно несет дополнительные издержки, но простой компонент-контейнер со стилизацией «снаружи» сильно по скорости не отличается от обычного div. Как и компоненты-контейнеры из других фреймворков, с более сложной структурой, не сильно отличаются от аналогичных веб-компонентов, которые быстрее. А вот в механизмах работы с темплейтами и биндингами уже, как раз, большая разница.
Где освещение вопросов компоновки элементов?
Эммм… все там. Возможно, я и упустил что-то, ибо все и сразу не захватишь, это все требует значительного времени… Просто открою вам один секрет, innerHTML — это самый простой способ и, очень часто, самый эффективный. Особенно, когда вы имеете дело с коллекциями, создающимися один раз для текущего вида. Или, когда элементов не много. Как можно работать с большими коллекциями — я показывал в примере выше, вроде ничего сложного. Суть моего подхода, которую вы не можете принять, в том, что для каждого случая с циклами — хорош свой подход, и плох один — универсальный (сильно увеличивает толщину ваших абстракций).
Стилизация: тут нам сходу предлагается принять в объятья shadow DOM, который в настоящий момент убог и не масштабируется.
Об этом мы с Вами уже дискутировали. С тех пор мое мнение о том, что вы глубоко заблуждаетесь — не изменилось. Показываю как расшарить стили для Shadow DOM:
const COMMON_CSS = /*css*/ `
color: black;
padding: 10px;
`;
const TEMPLATE = /*html*/ `
<style>
:host {
${COMMON_CSS}
}
</style>
<div>Бла бла бла</div>
`;
Без CSS-переменных, если вы не успели с ними подружиться. Стилизуйте как хотите, с любого уровня. Без протечек и повторения кода. Пожалуйста.
Ну и в 2020 году это всё написано в JS (с многочисленными // @ts-ignore в коде, что отдельно доставляет).
Я использую TS для статического анализа в обязательном порядке и для всех проектов. Но принципиально не пишу на TS при этом, используя аннотации типов в формате JS Doc. Это позволяет мне эффективно работать без пересборок, сорсмапов и прочего, что мне мешает. @ts-ignore — в бенчмарках это, кхм, абсолютно нормально, особенно когда используются экспериментальные API.
Нет, мне конечно тоже не нравится, что парни, делающие LitElement — категорически не хотят выкидывать из него полифиллы и прочую рухлядь, но это далеко не так страшно, чтоб ради победы над этим делать очередной очень велосипедистый велосипед.
Разница в производительности до 2-х раз — для меня достаточная причина. Контроль над DOM — тоже достаточная. Удобство работы с шаблонами — тоже.
+1
тут есть пример обновления, и это обновление, происходит значительно быстрее чем у того-же LitElement
Я даже целый абзац написал про то, что имеется в виду, но вы каким-то образом этого всего не прочли. Меня стейт-менеджмент в приложении к хоть сколько-нибудь сложной структуре интересует (не надо отвечать, что у вас стейт-менеджмент есть, пожалуйста), а не то, как вообще изменить стейт одного конкретного компонента.
Это с чего вдруг? Из бенчмарков видно, что это не так.
А где у вас бенчмарк на vanilla js?
Ну и насчёт «с чего» — во-первых абстракции небесплатны, а во-вторых — некоторые вещи в вебкомпонентах происходят далеко не самым удобным образом. Например, всё содержимое всех shadow root жадно обрабатывается браузером. Проще говоря, если у вас есть вебкомпонент с shadow root, подключенный в дерево — всё его содержимое будет парситься и обрабатываться браузером, даже если это всё висит в глубоком display: none. Из-за чего одна и та же по логической структуре страница может сильно грузить браузер просто потому, что на ней есть теневой DOM, против той, на которой его нет.
простой компонент-контейнер со стилизацией «снаружи» сильно по скорости не отличается от обычного div
Рассуждать о производительности в терминах «сильно» и «несильно» — лучше не стоит. А то ниже по тексту у вас «до 2х раз» — и это вдруг для вас офигенно, а тут — «сильно не отличается» (потому что вы не измеряли, скорее всего) и неважно.
Просто открою вам один секрет, innerHTML — это самый простой способ и, очень часто, самый эффективный.
Открою вам один секрет — этот «самый простой и очень часто эффективный» способ прост и эффективен в конкретных рамках. Как, собственно, практически все простые и эффективные способы.
И чем оно проще и эффективнее в границах применимости, тем сложнее с этим что-либо сделать вне границ применимости. Вы считаете, что ваш дефолтный innerHTML в основном достаточен? Ну считайте — а мой опыт говорит мне о том, что самые жесткие затыки производительности случаются как раз тогда, когда кто-нибудь «простой и эффективный» innerHTML через компонентность размажет по куче циклов и уровней DOM. И внезапно окажется, что сто раз по сто раз сделать innerHTML не так уж и просто и эффективно, особенно, когда в реальности надо всего лишь сделать 100 изменений, а не 100 по 100.
Суть моего подхода, которую вы не можете принять, в том, что для каждого случая с циклами — хорош свой подход, и плох один — универсальный (сильно увеличивает толщину ваших абстракций).
Я вам об этом и пишу — где ваше многообразие подходов-то, в самой библиотеке? Благо их там буквально два-три можно придумать, с одного полюса «все выкинули и нарисовали снова», с другого — обнаружение изменений стейта и минимум изменений в самом DOM, ну и, возможно, какой-то компромиссный вариант. Это как раз то, чему следует быть в крутом фреймворке для людей.
У вас же пока что два варианта — дефолтный на первом полюсе, второй — на втором полюсе строго для неизменного массива, и на первом для всего остального.
Показываю как расшарить стили для Shadow DOM
Отлично, выше по тексту мы наоптимизировали на скорости, а теперь давайте бухнем инлайновую подстановку по одной на каждый вид компонента, чтоб юзеры качали это всё себе. Как раз всё обратно и замедлим для баланса.
Это я даже не говорю про то, что у нормальных людей стили лежат в css. А вы такие приходите с вашими компонентами и говорите человечьим голосом: «а вы, добрые люди, вытащите ваши темы из css, распихайте их по строкам, и подоткните в мою либу компонентов».
Как там у вас в заглавии-то отличнейше написано?
Но затем, все, снова и снова, начинает упираться в избыточные зависимости, лишние сущности и попытки решить проблемы, которые разработчики сами же и создали.
Всё, что я от вас слышу про shadow DOM — это мужественное решение проблем, созданных самой shadow DOM.
Контроль над DOM — тоже достаточная. Удобство работы с шаблонами — тоже.
Вы не показали никаких преимуществ в контроле на DOM и в работе с шаблонами относительно других шаблонизаторов.
0
Отлично, выше по тексту мы наоптимизировали на скорости, а теперь давайте бухнем инлайновую подстановку по одной на каждый вид компонента, чтоб юзеры качали это всё себе.
Что, простите, качали? Зачем на каждый вид? Что за бред?
Простите, я сейчас на личности перейду: я часто встречаю ваши комментарии на Хабре, и часто их плюсую. Тот ваш пост про компоненты я тоже плюсанул, хоть и не согласен сильно с частью про Shadow DOM. Но каждый раз, когда нам приходится общаться друг с другом непосредственно — начинается срач с длинными простынями, в котором я не вижу ничего конструктивного. Я предлагаю закончить с этим. Можно просто принять тот факт, что есть люди с разным опытом и разной практикой, идущие разными путями.
На конкретные вопросы по библиотеке, о том, как сделать что-то конкретное, я отвечу.
+1
Что, простите, качали? Зачем на каждый вид? Что за бред?
Эм, стили? Те самые, которые вы подтыкаете? Я не понимаю, что вы тут не понимаете.
Предположим, у юзеров вашей библиотеки есть некий theme.css, который раскрашивает ваши компоненты так, как им надо. Дальше есть два варианта: вы или подтыкаете этот theme.css полностью в стиль каждого компонента через импорт, или вы предлагаете юзерам вашей библиотеки разбить его на кусочки — для каждого компонента своя часть — и подтыкаете все эти части к соответствующим компонентам примерно так, как в вашем предыдущем комментарии.
В обоих случаях вы всё так же загрузите весь объем theme.css (повторы браузер, разумеется, заново грузить не будет), в обоих случаях вы лишитесь преимуществ ранней загрузки css, потому что оно будет у вас не в <head>, а ниже; в обоих случаях вы лишитесь оптимизаций CSSOM, потому что для каждого shadow root итоговые стили будут посчитаны отдельно. Единственный плюс теневого DOM — изоляцию стилей — вы фактически выкидываете вон, потому что повальное подтыкание какого-то общего css с верхних уровней приложения — это то же самое, как если бы вы просто обычным образом подключили css на страницу. Только с кучей добавочных минусов, вызванных использованием теневого DOM.
-2
import {COMMON_CSS} from '../../css/common-css.js';
const TEMPLATE = /*html*/ `
<style>
:host {
color: ${COMMON_CSS[currentTheme].textColor};
padding: ${COMMON_CSS[currentTheme].paddng};
}
</style>
<child-component></child-component>
`;
Скажите, это полностью или порезано на кусочки? И в какой момент тут нарушается изоляция?
+1
Это — вообще никак не отличается от css variables и имеет всё те же проблемы. Завтра мне нужен будет margin, послезавтра outline, послепослезавтра еще что-нибудь — и что мне делать, писать в спортлото или пачтить чужую библиотеку?
-1
Ок, а когда вам нужен margin или outline с обычным CSS, куда вы обычно пишите?
0
В css пишу, сразу после селектора, выбирающего мне нужный компонент.
0
Приведите пример.
0
Серьезно?
web-component {
background-color: white;
}
web-component child-component {
background-color: gray;
}
0
export const COMMON_CSS = {
day: {
webComponent: /*css*/ `
:host {
background-color: white;
outline: none;
margin: 2px;
}
child-component {
background-color: gray;
}
`,
},
night: {
...
},
};
const TEMPLATE = /*html*/ `
<style>${COMMON_CSS[currentTheme].webComponent}</style>
<child-component></child-component>
`;
0
См. https://habr.com/ru/post/485688/#comment_21201010
Мужественная борьба с shadow DOM, в результате которой немногочисленные плюсы пропадают, а многочисленные минусы — все остаются. В этом конкретном случае (в каждый компонент его собственный кусочек) — изоляция остаётся, но по производительности это самый удручающий вариант: множество кусков css без особо ранней загрузки, множество shadow root, каждый из которых обсчитывается отдельно; а юзерам вашей библиотеки еще дополнительно надо сидеть и переносить стили из css в POJO по категориям.
Мужественная борьба с shadow DOM, в результате которой немногочисленные плюсы пропадают, а многочисленные минусы — все остаются. В этом конкретном случае (в каждый компонент его собственный кусочек) — изоляция остаётся, но по производительности это самый удручающий вариант: множество кусков css без особо ранней загрузки, множество shadow root, каждый из которых обсчитывается отдельно; а юзерам вашей библиотеки еще дополнительно надо сидеть и переносить стили из css в POJO по категориям.
0
Это какие плюсы у меня пропали? Инкапсуляция? Возможность управлять темами? Вычислять свойства? Может быть стили у меня разбросаны по разным местам? Или что-то повторяется? Или я изобретаю франкенштейнов, типа БЭМ, чтобы мой проект случайно не развалился, когда кто-то неосторожно написал в «спортлото»?
0
Окей, хорошо, на безрыбье инкапсуляции css мне и вправду нечего возразить — если инкапсуляция реально критична, то придётся жить с shadow DOM, потому что все остальные решения в любом случае еще хуже (а shadow DOM может таки со временем доработают).
Другое дело, что критична она тогда, когда проект становится весьма большим, а тогда же критичным становится и быстродействие, с которым у shadow DOM всё не суперски (впрочем, опять же, альтернатива — только обычный css, потому что все другие решения еще более медленные).
Другое дело, что критична она тогда, когда проект становится весьма большим, а тогда же критичным становится и быстродействие, с которым у shadow DOM всё не суперски (впрочем, опять же, альтернатива — только обычный css, потому что все другие решения еще более медленные).
0
Как по вашему, насколько компонент с Shadow DOM медленнее рендерится, чем просто DOM элемент с такими-же стилями? Если вы пишите «всё не суперски», насколько действительно велика проблема?
+1
Поскольку вы молчите, отвечу сам. Я набросал по быстрому такие тесты:
github.com/foxeyes/shadow-benchmark
На моей машине чистые издержки на ShadowRoot — примерно 10% скорости.
На внутренние стили с отдельным узлом падение скорости уже значительные, но затраты примерно соответствуют затратам на дополнительный узел DOM.
В итоге, конечно, веб-компоненты добавляют накладные расходы, но ничего критичного я не наблюдаю. Тем более, что обычные ноды никто не отменял, ShadowRoot у вас в проекте будет не везде, а значит затраты возрастают не линейно и, тем более, не экспоненциально. В итоге, мы имеем обычный инженерный компромисс: на одной чаше весов удобство и инкапсуляция и небольшая просадка по скорости (относительно оптимизированного ванильного html, без библиотек), на другой — чуть более высокая скорость + препроцессоры со своим синтаксисом, монструозный БЭМ и длинные простыни CSS в далеке от места применения.
github.com/foxeyes/shadow-benchmark
На моей машине чистые издержки на ShadowRoot — примерно 10% скорости.
На внутренние стили с отдельным узлом падение скорости уже значительные, но затраты примерно соответствуют затратам на дополнительный узел DOM.
В итоге, конечно, веб-компоненты добавляют накладные расходы, но ничего критичного я не наблюдаю. Тем более, что обычные ноды никто не отменял, ShadowRoot у вас в проекте будет не везде, а значит затраты возрастают не линейно и, тем более, не экспоненциально. В итоге, мы имеем обычный инженерный компромисс: на одной чаше весов удобство и инкапсуляция и небольшая просадка по скорости (относительно оптимизированного ванильного html, без библиотек), на другой — чуть более высокая скорость + препроцессоры со своим синтаксисом, монструозный БЭМ и длинные простыни CSS в далеке от места применения.
+1
Немного глубже раскрою тему с innerHTML:
У веб-компонентов, есть одна очень важная особенность: они сами могут быть добавлены в DOM через innerHTML. Со всей своей логикой и возможностью самостоятельно подписаться на нужные данные, и отвечать за их обновление. Также, они могут отвечать за действия, которые необходимо выполнить при их удалении, например за очистку памяти. И они могут самоуничтожаться при необходимости. Это может кардинально изменить то, как вы организуете то, что вы называете «компоновкой».
У веб-компонентов, есть одна очень важная особенность: они сами могут быть добавлены в DOM через innerHTML. Со всей своей логикой и возможностью самостоятельно подписаться на нужные данные, и отвечать за их обновление. Также, они могут отвечать за действия, которые необходимо выполнить при их удалении, например за очистку памяти. И они могут самоуничтожаться при необходимости. Это может кардинально изменить то, как вы организуете то, что вы называете «компоновкой».
+1
У веб-компонентов, есть одна очень важная особенность: они сами могут быть добавлены в DOM через innerHTML.
А что, это могло быть кому-то не очевидно?
0
Видимо тем, кто боится что придется перерендерить innerHTML целиком при изменении одного из элементов массива с данными…
0
Степень страха в этом случае у нормального разработчика всецело определяется тем, сколько DOM тянет с собой этот самый «один из элементов массива с данными». Я еще могу позвать сюда товарища khim, который вам быстро в популярных выражениях объяснит, что невозможность пролистать бесконечную ленту на patreon.com дальше нескольких страниц назад — это в конечном счете история того, как кто-то очень храбрый не побоялся перерендерить кое-что целиком. Впрочем, там это всё еще усугублено реактом — на каком-нибудь «сверхбыстром» фреймворке такой тупой прием продержался бы не 5-8 страниц, а 20-30, но итог будет точно такой же.
0
Вы видимо не поняли. Рендер изменений будет только там, где они, непосредственно, произошли. Именно это кому-то не очевидно.
+1
Это вот здесь-то?
Откуда тут «рендер изменений только там <...>», когда тут полностью шаблон массива меняется?
И в вашем «For other performance sensitive cases you can use this component.» всё то же самое, если вы будете мутировать сам массив — нет переделки там только тогда, когда массив у вас иммутабелен, а меняется только его содержимое.
Я даже не буду говорить, что иммутабельные массивы удобны далеко не всегда.
class MyComponent extends HdElement {
constructor() {
super();
this.state = {
html: '<div>Initial Content</div>',
};
}
set data(data) {
this.setStateProperty({
'html': data.map(item => `<data-item>${item.text}</data-item>`).join(''),
});
}
}
MyComponent.template = /*html*/ `
<div class="menu" bind="innerHTML: html"></div>
`;
Откуда тут «рендер изменений только там <...>», когда тут полностью шаблон массива меняется?
И в вашем «For other performance sensitive cases you can use this component.» всё то же самое, если вы будете мутировать сам массив — нет переделки там только тогда, когда массив у вас иммутабелен, а меняется только его содержимое.
Я даже не буду говорить, что иммутабельные массивы удобны далеко не всегда.
-1
Хм, конечно не здесь. Почему вообще вы выбрали именно этот кусок кода, если сами нашли правильный? Тем не менее, это далеко не все способы, для сложных случаев (графы данных) я предпочитаю использовать хранилища с подпиской по уникальным ключам.
+1
Почему вообще вы выбрали именно этот кусок кода, если сами нашли правильный?
Во-первых, потому что он не правильный — если уж оптимизировать рендер, то делать это вокруг иммутабельности массива (а не количества изменений в DOM) — это какой-то местячковый случай.
Во-вторых, еще раз обращаю ваше внимание на то, что этим всем подходам, благо их немного, следует быть реализованными в библиотеке, а не «ну это вы сами напишите, если надо».
-2
Документация выполнена в удивительном стиле ))
+1
Замечательный проект, но есть вопрос по поводу бенчмарков.
В вашем тестовом компоненте объявлено только одно свойство, а что будет если их там будет несколько?
defineAccessor вызывает синхронное обновление, то есть вот эта итерация по байндингам будет выполняться на каждое свойство.
Поэтому, как мне кажется, если переписать бенчмарк и добавить в тестовый компонент больше свойств, то React и lit-element выберутся вперед.
0
Да, обновления синхронные, и именно поэтому, в том числе, они работают быстрее. Браузер сам не начинает рендер до окончания синхронного цикла. Тем не менее, и для асинхронного обновления, когда это нужно, имеется метод: setStatePropertyLater (при его использовании скорость приближается к LitElement).
Не выберутся, проверено. Но я внесу данный момент в бенчмарки чтобы не оставаться голословным.
Спасибо за отзыв.
React и lit-element выберутся вперед
Не выберутся, проверено. Но я внесу данный момент в бенчмарки чтобы не оставаться голословным.
Спасибо за отзыв.
0
И еще один вопрос возник: а как у вас делается условный рендеринг компонента? Что-то вроде этого:
if(color == 'blue') {
return <BlueButton />
} else {
return <RedButton />
}
0
При первичном определении шаблона:
Динамически:
Или, что будет более правильно:
<div>
${color === 'blue' ? `<blue-btn></blue-btn>` : `<red-btn></red-btn>`}
</div>
Динамически:
<div bind="innerHTML: html.currentColorButton"></div>
Или, что будет более правильно:
<div>
<my-btn bind="textContent: actualButtonText; @color: actualButtonColor"></my-btn>
</div>
+1
Вариант с innerHTML оригинальный, работать будет, но опять возникает вопрос производительности. innerHTML знаменит как источник замедления рендеринга.
0
Это тонкий момент, который мне, видимо, следует описать подробнее, возможно даже отдельный материал этому посвятить. Вкратце: если innerHTML используется для участков DOM, которые должны быть созданы один раз на время всей жизни компонента — это вполне эффективный способ. Если менять динамически — то зависит от сложности структуры внутри. Например, вывести пункты выпадающего списка — вполне сгодится. Если мы динамически меняем сложноструктурированные данные — то эффективные апдейты могут становится частью логики дочерних элементов, которые могут сами обновлять свои данные. То есть одно универсальное, но громоздкое решение, я предлагаю декомпозировать примерно в соответствие с композицией самих данных. Я планирую сделать примеры.
0
Для скорости лучше использовать innerDOM:
Подробнее тут: holiday-js.web.app/?templates
const DATA = [
{
firstName: 'John',
secondName: 'Snow',
},
{
firstName: 'Jane',
secondName: 'Flower',
},
];
class MyComponent extends HdElement {
constructor() {
super();
this.state = {
list: {
dom: this.prepareDomFragment(DATA, PersonCard, null, 'dataProperty'),
},
};
}
}
MyComponent.template = /*html*/ `
<div class="list" bind="innerDOM: list.dom"></div>
`;
Подробнее тут: holiday-js.web.app/?templates
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Публикации
Изменить настройки темы
MyApp extends Holiday