Pull to refresh

Comments 6

Видимо надо ещё немного подождать, пока они до конца устаканяться

Они уже давно это сделали)

Тёма интересная и, возможно, когда-то пригодится. Но, пока, реального профита от этого не видно. Возможно, если нужен очень сложный компонент, который используется и здесь и там, это пригодится.

А, в общем, спасибо за статью.

Превосходная статья. Добавил в закладки. Несколько вопросов.
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>.

Sign up to leave a comment.

Articles