Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
где у вас инструменты, работающие на скорость обновления страницы?
Хвалиться тем, что вы быстро создаете веб-компоненты — сомнительное достижение
Тем более, что веб-компоненты пока что всё равно гораздо более медленные, чем обычный DOM
Где освещение вопросов компоновки элементов?
Стилизация: тут нам сходу предлагается принять в объятья shadow DOM, который в настоящий момент убог и не масштабируется.
const COMMON_CSS = /*css*/ `
color: black;
padding: 10px;
`;
const TEMPLATE = /*html*/ `
<style>
:host {
${COMMON_CSS}
}
</style>
<div>Бла бла бла</div>
`;
Ну и в 2020 году это всё написано в JS (с многочисленными // @ts-ignore в коде, что отдельно доставляет).
Нет, мне конечно тоже не нравится, что парни, делающие LitElement — категорически не хотят выкидывать из него полифиллы и прочую рухлядь, но это далеко не так страшно, чтоб ради победы над этим делать очередной очень велосипедистый велосипед.
тут есть пример обновления, и это обновление, происходит значительно быстрее чем у того-же LitElement
Это с чего вдруг? Из бенчмарков видно, что это не так.
простой компонент-контейнер со стилизацией «снаружи» сильно по скорости не отличается от обычного div
Просто открою вам один секрет, innerHTML — это самый простой способ и, очень часто, самый эффективный.
Суть моего подхода, которую вы не можете принять, в том, что для каждого случая с циклами — хорош свой подход, и плох один — универсальный (сильно увеличивает толщину ваших абстракций).
Показываю как расшарить стили для Shadow DOM
Но затем, все, снова и снова, начинает упираться в избыточные зависимости, лишние сущности и попытки решить проблемы, которые разработчики сами же и создали.
Контроль над DOM — тоже достаточная. Удобство работы с шаблонами — тоже.
Отлично, выше по тексту мы наоптимизировали на скорости, а теперь давайте бухнем инлайновую подстановку по одной на каждый вид компонента, чтоб юзеры качали это всё себе.
Что, простите, качали? Зачем на каждый вид? Что за бред?
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>
`;
web-component {
background-color: white;
}
web-component child-component {
background-color: gray;
}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>
`;
У веб-компонентов, есть одна очень важная особенность: они сами могут быть добавлены в DOM через innerHTML.
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>
`;Почему вообще вы выбрали именно этот кусок кода, если сами нашли правильный?
Замечательный проект, но есть вопрос по поводу бенчмарков.
В вашем тестовом компоненте объявлено только одно свойство, а что будет если их там будет несколько?
defineAccessor вызывает синхронное обновление, то есть вот эта итерация по байндингам будет выполняться на каждое свойство.
Поэтому, как мне кажется, если переписать бенчмарк и добавить в тестовый компонент больше свойств, то React и lit-element выберутся вперед.
React и lit-element выберутся вперед
И еще один вопрос возник: а как у вас делается условный рендеринг компонента? Что-то вроде этого:
if(color == 'blue') {
return <BlueButton />
} else {
return <RedButton />
}<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>
Вариант с innerHTML оригинальный, работать будет, но опять возникает вопрос производительности. innerHTML знаменит как источник замедления рендеринга.
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>
`;
MyApp extends Holiday