Серия Lit library - 1: Глубокое погружение в библиотеку lit-html
Цель этой серии блогов — углубиться в библиотеку Lit и получить всестороннее представление о ее уникальных функциях и о том, чем она отличается от других библиотек и фреймворков на рынке.
Эта серия разделена на три части, посвященные таким темам, как
1. Как работает lit-html?
2. Как Lit Element выполняет пакетное обновление DOM?
3. Сравнение и бенчмаркинг Lit с другими фреймворками и библиотеками, а также его возможные варианты использования.
В этом конкретном блоге мы сосредоточимся на изучении lit-html и его внутренней работы. Но прежде чем углубляться в lit-html, давайте сначала рассмотрим саму библиотеку Lit.
Что такое Лит?
Lit — это легкая библиотека веб-компонентов, занимающая около 5 КБ.
Он специально разработан для эффективной и быстрой разработки компонентов пользовательского интерфейса с использованием спецификаций веб-компонентов и еще больше повышает производительность за счет внедрения пакетных обновлений в DOM.
На самом деле, согласно общедоступному тесту, проведенномуhttps://krausest.github.io/js-framework-benchmark/index.html, Lit Element продемонстрировал более высокую производительность по сравнению с React.
Чтобы узнать больше о Lit Element, вы можете посетить их официальный сайт по адресуhttps://lit.dev/. Тем не менее, в этой серии статей основное внимание уделяется пониманию того, как работает Lit Element и как он реализуется.
Lit Element построен на основе lit-html, библиотеки шаблонов, используемой для создания шаблонов и логики пакетного обновления DOM. Lit Element расширяет lit-html, предоставляя дополнительные функции для пакетных обновлений.
Создание шаблона lit-html:
lit-html — это библиотека шаблонов JavaScript, которая позволяет создавать шаблоны с использованием литералов с тегами JavaScript и функций тегов, используя собственные функции JavaScript и веб-компоненты.
В отличие от JSX или других библиотек шаблонов, lit-html не требует этапа сборки для преобразования шаблонов или синтаксиса, специфичных для фреймворка, в шаблоны или синтаксис, совместимые с браузером, поскольку он напрямую использует собственные функции JavaScript.
Создадим шаблон с помощью библиотеки lit-html:

В этом примере мы импортируем две функции из библиотеки lit-html:
1. html
, которая является функцией тега.
2. render
, который используется для рендеринга шаблона в DOM.
Затем мы определяем вызываемую функцию myTemplate
, которая принимает аргумент name
.
Шаблон определяется с помощью html
функции тега, заключенной в обратные галочки (``), и содержит фрагмент HTML <div>Hello, ${name}</div>
.
Это ${name}
заполнитель, который можно динамически заменить значением во время выполнения на основе аргумента, переданного в функцию myTemplate
.
Функция тега html
возвращает TemplateResult
объект, представляющий шаблон, который можно отобразить в DOM.
В следующих разделах мы рассмотрим функцию тега JavaScript и то, как функция тега html реализована в библиотеке lit-html.
В последней строке кода мы вызываем render
метод, который отображает шаблон.
Метод render
принимает два аргумента:
а) TemplateResult
объект, представляющий шаблон для визуализации.
б) Ссылка на элемент DOM, в котором будет отображаться шаблон.
Функция тега в JavaScript:
Примечание. Если вы уже знакомы с функциями тегов, этот раздел можно пропустить.
Функция тега в JavaScript — это особый тип функции, который можно использовать для обработки литералов шаблонов, представляющих собой строки, заключенные в обратные кавычки (``).
Функция тега вызывается непосредственно перед вычислением литерала шаблона и получает литерал шаблона и его интерполированные значения в качестве отдельных аргументов.
Например, рассмотрим следующий код:
var name = "Whatfix";
function sayHello(literalString, ...values) {
console.log(literalString); //Output: ['Hello, ', '', raw: Array(2)]
console.log(values); //Output: ['Whatfix']
}
sayHello`Hello, ${name}`;
а. Массив статических частей шаблонного литерала: literalString
.
В нашем примере значение literalString
параметра равно['Hello, ', '', raw: Array(2)]
б. Один или несколько аргументов, соответствующих количеству выражений в помеченном литерале: values
. В нашем примере мы используем оператор распространения ( ...
), чтобы представить его в виде массива. Его значение равно ['Whatfix']
, которое содержит значения выражений, используемых в литерале шаблона.
Глубокое погружение в метод html:
Вот реализация html
функции тега из lit-html
репозитория —https://github.com/lit/lit. (Я сделал некоторые улучшения в коде, удалив ненужные части, чтобы сделать его более понятным).
const html =
<T extends ResultType>(type: T) =>
(strings: TemplateStringsArray, ...values: unknown[]): TemplateResult<T> => {
return {
['_$litType$']: type,
strings,
values,
};
};
Затем он формирует объект, известный как TemplateResult
, с тремя параметрами и возвращает его.
Три параметра TemplateResult
включают _$litType$, строки и значения[].
а. Параметр _$litType$ содержит тип.
б. Параметр strings содержит массив статических частей литералов.
в. Параметр values[] содержит значения динамических частей литерала.
В нашем предыдущем примере (Шаблон — A) myTemplate("whatfix”)
метод вернет:
{
_$litType$: 1,
strings: ["<div>Hello, ", "</div>", raw: Array(2)],
values: ["whatfix"]
}
Глубокое погружение в метод рендеринга:
Метод рендеринга в lit-html отвечает за рендеринг компонента в пользовательском интерфейсе.
Он принимает три аргумента:
а. value — значение TemplateResult
, сгенерированное функцией тега html, как обсуждалось в предыдущем разделе.
б. container — ссылка на элемент DOM, в котором будет отображаться шаблон.
в. options — в целях упрощения этот аргумент можно игнорировать, чтобы лучше понять процесс.
Мы можем визуально понять работу метода рендеринга в нашем примере, используя блок-схему.

Далее давайте обработаем наш пример компонента, Шаблон A, используя вышеупомянутую блок-схему. Поскольку мы уже сгенерировали TemplateResult
объект с помощью функции тега html, как обсуждалось в предыдущем разделе, теперь мы можем приступить к процессу рендеринга.
Объект TemplateResult
для нашего примера компонента Template A будет иметь следующую структуру:

Следующий шаг включает в себя создание <template>
элемента из TemplateResult
объекта.
В нашем примере компонента Template A, который включает в себя динамическую часть, представленную {name}
, мы генерируем случайное девятизначное число и добавляем его в качестве узла комментария вместо {name}
.
В результате <template>
элемент будет выглядеть следующим образом:

The subsequent step involves cloning the template element and updating the dynamic parts, either during the first-time rendering or subsequent updates. The cloning the template element happens only in initial render of the component.
The resulting structure will appear as follows:
Then using the second argument passed to the render method, we are adding the final component structure in the Document.
Conclusion:
In this blog, we’ve explored the internal workings of lit-html. In the next part of this series, we’ll delve deeper into the batching operations performed in the lit library with lit elements.