Загрузите необходимые стили в shadow-dom

#javascript #html #css #web-component #shadow-dom

Вопрос:

Мне нравится идея инкапсуляции стилей теневого dom, но я хотел бы включить базовые стили в каждый теневой dom (сброс, типографика и т. Д.).

  <head>
 <link rel="stylesheet" href="core.css">
 ...
 </head>

 <my-component></my-component>
 <script>
   
   customElements.define('my-component', class MyComponent extends HTMLElement {
     ...
     connectedCallback() {
        this.shadow = this.attachShadow({mode: 'open'});
        const linkElem = document.createElement('link');
        linkElem.setAttribute('rel', 'stylesheet');
        linkElem.setAttribute('href', 'core.css');

        // applying exiting "core.css" to current shadow dom 
        this.shadow.appendChild(linkElem);
    }
   });
 </script>
 

Так core.css как был вызван (связан) дважды, повлияет ли это на производительность?

Ответ №1:

Вы можете попробовать использовать Конструктивные объекты таблиц стилей

С помощью этого подхода вы можете определить глобальные стили, а затем использовать их со shadowRoot.adoptedStylesheets следующими:

 import {
    resetSheet,
    headlinesSheet,
    coreSheet,
} from '/style-system.js';
import {
    myComponentStyles,
} from './styles.js';

// ...

    connectedCallback() {
        // Only compose styles once
        if (!this.shadowRoot.adoptedStyleSheets.length) {
            this.shadowRoot.adoptedStyleSheet = [
                // global stylesheets
                resetSheet,
                headlinesSheet,
                coreSheet,
                // specific sheet for this component
                myComponentStyles
            ]
        }
    }
 

Основными преимуществами этого подхода по сравнению с тем, который вы используете (создание элементов связи с каждым компонентом), являются:

  • Вы можете совместно использовать глобальные стили для нескольких компонентов, определив их один раз
  • Вы загружаете только стили, используемые этим визуализируемым компонентом, и это снижает производительность, поскольку он лениво загружает таблицы стилей
  • Вы можете динамически изменять эти глобальные стили (поскольку они являются компонентом JS) без необходимости внесения изменений в несколько элементов, внося более разрозненные изменения

Поскольку это совершенно новый подход, я бы рекомендовал вам прочитать следующие статьи, чтобы получить более основательные знания о Constructable Stylesheet Objects

  1. Конструктивные Таблицы Стилей
  2. В Любом Случае, Зачем Кому-То Использовать Конструктивные Таблицы Стилей?
  3. Внедрите систему проектирования внутри своих веб-компонентов с помощью конструктивных таблиц стилей

Комментарии:

1. Отлично! Но сейчас это поддерживается только в chrome 🙁 caniuse.com/mdn-api_document_adoptedstylesheets

2. Хм, это позор, извини, что не знал этого, хотя что-то действительно классное, что нужно искать в ближайшие несколько недель/месяцев. Удачи тебе в этом, приятель

3. Свяжите файл css с каждым компонентом. Если вы столкнетесь с проблемами производительности, у вас, скорее всего, будет много других проблем. Построенные таблицы стилей-это будущее решение

Ответ №2:

Браузер будет кэшировать запрос core.css , так что на самом деле это не приведет к снижению производительности, но, поскольку таблица стилей будет загружаться асинхронно, вы можете получить вспышку нестилированного контента (FOUC), пока браузер впервые загружает css.

Один из возможных способов обойти это-предварительно загрузить файл css в свой документ <head> , чтобы он (вероятно, поскольку предварительная загрузка-это всего лишь «подсказки» для браузера) был доступен к моменту анализа вашего теневого DOM:

 <link rel="preload" href="core.css" as="style">