Declarative Shadow DOM (DSD) — это современный подход к созданию теневого DOM, который упрощает работу с компонентами веб-компонентов и улучшает производительность за счёт оптимизированного рендеринга на стороне браузера. В отличие от классического Shadow DOM, где содержимое компонента генерируется динамически через JavaScript, DSD позволяет описывать структуру теневого DOM декларативно прямо в HTML, что снижает нагрузку на рендеринг и ускоряет загрузку страниц.
Декларативность Декларативный подход предполагает, что структура компонента задаётся заранее и не требует динамической генерации через JavaScript. В DSD HTML-теги и элементы Shadow DOM указываются как часть разметки:
<my-component>
<template shadowroot="open">
<style>
p {
color: blue;
}
</style>
<p>Привет из теневого DOM</p>
</template>
</my-component>
Здесь <template shadowroot="open"> автоматически
создаёт теневой DOM при рендеринге компонента. Атрибут
shadowroot может принимать значения open или
closed, управляя доступностью Shadow DOM через
JavaScript.
Производительность Декларативный теневой DOM позволяет браузеру сразу построить дерево компонента при загрузке страницы, без необходимости выполнения сложной логики в JS. Это особенно важно для критических компонентов на страницах с большим количеством интерактивных элементов.
Поддержка Stencil Stencil автоматически
компилирует компоненты с поддержкой Declarative Shadow DOM. Для
использования DSD достаточно включить опцию
declarativeShadowDOM в конфигурации:
import { Config } from '@stencil/core';
export const config: Config = {
namespace: 'app',
outputTargets: [
{
type: 'www',
},
],
experimental: {
declarativeShadowDOM: true
}
};
После включения этой опции компоненты будут компилироваться с учётом декларативного подхода, а браузер сможет создавать теневой DOM напрямую из HTML без промежуточного JS.
Определение компонента В Stencil компонент с Declarative Shadow DOM создаётся так же, как обычный веб-компонент:
import { Component, h } from '@stencil/core';
@Component({
tag: 'my-component',
shadow: true
})
export class MyComponent {
render() {
return (
<p>Привет из Stencil</p>
);
}
}
При включённом declarativeShadowDOM Stencil преобразует
JSX в декларативный <template shadowroot> при сборке,
что позволяет избежать динамического создания Shadow DOM в
рантайме.
Стилизация теневого DOM Стили можно задавать прямо внутри шаблона Shadow DOM или использовать глобальные CSS-переменные для взаимодействия между компонентами:
<template shadowroot="open">
<style>
:host {
display: block;
font-family: sans-serif;
}
p {
color: var(--primary-color, black);
}
</style>
<p>Стилизованный текст</p>
</template>
:host позволяет управлять стилями корневого элемента
компонента, а CSS-переменные обеспечивают гибкую тему и возможность
переопределения внешними стилями.
Интеграция с другими компонентами DSD упрощает
композицию компонентов. Внутри <template shadowroot>
можно вставлять дочерние веб-компоненты, и браузер корректно создаст их
теневой DOM при парсинге страницы:
<my-card>
<template shadowroot="open">
<my-button>Нажми меня</my-button>
</template>
</my-card>
Важное преимущество — все дочерние компоненты создаются декларативно и могут быть кэшированы браузером.
<template>: все вычисления и условия
необходимо выполнять в основном компоненте Stencil, так как DSD
создаётся при парсинге HTML и не может содержать JS-код.render() и JSX.Declarative Shadow DOM в Stencil значительно упрощает работу с веб-компонентами, ускоряет загрузку страниц и облегчает интеграцию компонентов в крупные проекты с большим количеством повторяющихся элементов интерфейса.