Web Components
Shadow DOM, Custom Elements, HTML Templates, HTML Imports
Вебкомпоненты:
- предоставляют нативные (браузерные) средства разработки пользовательских компонент
- cодержат средства описания шаблона, стилей и логики компонента, а также механизм их инкапсуляции в единую независимую сущность.
Пилотные варианты спецификаций W3C Web Components: были реализованы 4 года назад в Google Chrome
За это время произошли глобальные изменения в архитектуре веб-приложений:
- устарела концепция “веб-сайт”
(веб-приложение с серверным рендерингом страниц, где фронтенд-технологии применялись для интерфейсных улучшений) - на смену ей пришла концепция “spa-приложение”,
в которой произошло разделение на бекенд и фронтенд, которые взаимодействуют через API
Для построения фронтенда как независимой архитектурной части web-приложения стало необходимо применять общепринятые архитектурные принципы и решения:
- модели, контроллеры, представления, логику их взаимодействия
- роутинги, хранилище состояния приложения
- выделять реиспользуемые модули и компоненты
Все это послужило толчком для создания средств для реализации этих принципов и решений. Появились и широко используются:
- системы сборки (Grunt/Gulp/Webpack)
- транспайлеры (Babel/TypeScript)
- css-препроцессоры (LESS/SASS/SCSS/PostCSS)
- библиотеки CSS-in-JS
- высокопроизводительные js-фреймворки (Angular/React/Ember),
предоставляющие свои реализации архитектурных решений
Этот прогресс нивелировал актуальность вебкомпонентов и сейчас необходимость их применения кажется очень сомнительной. Действительно, все перечисленные выше средства в совокупности позволяют решить задачу разработки UI-компонент с инкапсулированными шаблоном, стилями, логикой и состоянием.
Какое место претендуют занять вебкомпоненты в современном стеке фронтенд-технологий? Зачем и как применять вебкомпоненты в jquery/angular/react/<ваш_фреймворк>-приложениях?ваш_фреймворк>
Web Components: развитие
Развитие фронтенд-тулинга форсировало прогресс браузерных технологий.
Ускорилась разработка w3c/ecmascript-стандартов и их имплементация в браузерах.
Стек стандартов Web Components тоже не остался без внимания.
За прошедшие 4 года с момента экспериментальной реализации стека Web Components в Google Chrome:
- вышли новые версии спецификаций Shadow DOM v1 и Custom Elements v1
- HTML Templates были реализованы во всех основных браузерах, кроме IE
- вышел Polymer v.2
Shadow DOM v1 | |
Custom Elements v1 | |
HTML Templates | |
HTML Imports | |
Polymer v2 |
Shadow DOM: v.0
vs v.1
Наибольшие изменения претерпела спецификация Shadow DOM
-
создание shadow root
v.0:
element.createShadowRoot()
v.1:
element.attachShadow({ mode: ... })
-
поддержка множественных shadow root
v.0:
поддерживается
v.1:
не поддерживается -
closed shadow root
v.0:
не поддерживается, shadow root постоянно доступен извне:e.shadowRoot
v.1:
режим задается:element.attachShadow({ mode: 'open' || 'closed' })
работа геттеровe.shadowRoot
,e.assignedSlot
зависит от режима -
shadow host
v.0:
любой элемент может стать shadow host
v.1:
список элементов регламентирован -
механизм распределения контента - позиции отображения контента из другого дерева:
v.0:
Insertion points
v.1:
Slots
Custom Elements v.0
vs v.1
-
появление в браузерах поддержки es6 классов позволяет описывать пользовательский элемент v0 и v1 в виде класса:
class MyElementClass extends HTMLElement {}
-
регистрация элемента
v.0:
window.document.registerElement('my-element', MyElementClass)
v.1:
window.customElements.define('my-element', MyElementClass)
-
промис момента регистрации элемента
v.1:
customElements.whenDefined('my-element')
-
определение конструктора класса элемента по его имени:
v.1:
customElements.get('my-element')
-
жизненный цикл элемента:
Custom Elements v0 | Custom Elements v1 | |
---|---|---|
создание экземпляра | createdCallback |
constructor |
добавление в DOM | attachedCallback |
connectedCallback |
изменение атрибутов | attributeChangedCallback |
attributeChangedCallback |
добавление в чужой DOM | — | adoptedCallback |
удаление из DOM | detachedCallback |
disconnectedCallback |
Сизифов труд
Вопрос:
Кто делал свою реализацию дроп-дауна на:
- vanila-js
- JQuery
- NockoutJS
- AngularJS
- ReactJS
- Angular2
Не пора ли остановиться?
Написаны десятки UI-фреймворков, содержащие тысячи компонент.
Подсчет человеко-часов, затраченных на этот титанический труд,
не поддается оценке.
Почему не написан UI-фреймворк, который можно использовать с любым фреймворком уровня приложения?
Один UI-фреймворк всеже есть и его использует каждый из нас.
Вопрос:
Какой это фреймворк?
Это нативные UI-компоненты браузера.
Нативные UI-компоненты браузера
<button />
<input type="text"/>
<input type="checkbox" />
<input type="radio" />
<textarea />
<select />
<video />
...
Используя каждый из них вы не сомневаетесь будет ли он работать в вашем фреймворке.
Вопрос:
Что под капотом этого “фреймворка”?
Если открыть отладчик, включить Show user agent shadow DOM
и проинспектировать стандартные компоненты браузера
- вы увидете что скрыто “под капотом”.
Да, это вебкомпоненты.
Почему эти компоненты работают везде?
— реализованы на более низком уровне, чем js-фреймворк
— используется Shadow DOM для изоляции собственного DOM-дерева и его стилей
— компонент предоставляет js-api и api атрибутов
для взаимодействия с внешней средой
Имплементация стека стандартов Web Components предоставляет стандартное api, позволяющее использовать эти “низкоуровневые” инструменты для создания собственных компонент.
Web Components vs JS-framework
Сравнения по функционалу Web Components vs JS-framework
корректны в той же степени,
что и сравнение колеса с автомобилем
- тема одна и таже, на этом сходства заканчиваются.
Относительно современных js-фреймворков по функционалу вебкомпоненты наиболее близки к ReactJS:
- “из коробки” не содержат механизмов, типичных для application-фреймворков (фреймворков уровня приложения), таких как Angular, Ember: роутинги, контроллеры, модели, хранилища состояния, …
- предоставляют лишь инструменты для создания компонент, не более того
Основное назначение application-фреймворка:
— предоставить средства создания инфраструктуры приложения.
Назначение вебкомпонентов:
— предоставить средства создания компонент.
Не пора ли начать использовать инструменты по их прямому назначению?
JS-фреймворки: проблемы миграции
Причины:
— развитие application-фреймворков динамично, хочется использовать
самый прогрессивный
— заказчики продукта определяют использумый стек фреймворков и технологий.
Проблемы накатывают лавиной:
— выбор application-фреймворка подразумевает и выбор ui-фреймворка
(для Angular-приложения - ui-фреймворк на Angular, …)
— смена фреймворка приложения приводит к замене наработанной базы ui-компонент
— издержки на адаптацию, стилизацию, отладку и тестирование
На практике произошло:
— purejs ➛ jquery
— jquery ➛ KnockoutJS / jquery ➛ AngularJS / jquery ➛ ReactJS / jquery ➛ Angular2
— AngularJS ➛ Angular2
Причем заказчик считает что:
— необходимые ui-компоненты можно заимствовать из числа уже реализованных
— задача сводится к тривиальной стилизации
— доводы о трудозатратах на разработку не убедительны
Таким образом, от пректа к проекту, повторяется процесс разработки ui-библиотеки.
Не пора ли остановиться?
Web Components или JS-framework?
Это выбор: что мне выбрать: колеса или автомобиль?
Ответ очевиден: автомобиль с колесами
А лучше: автомобиль с колесами, которые можно менять и сменный комплект
Вам не придется делать этот выбор.
Нет необходимости отказываться от любимого фреймворка в пользу вебкомпонентов и наоборот.
Вебкомпоненты по своей сути можно использовать с любым js-фреймворком уровня приложения и ui-фреймворком:
-
с точки зрения фреймворка вебкомпоненты ничем не должны отличаться от нативных, т.к. реализуются на более низком уровне, чем фреймфорк (механизмами браузера)
-
фреймворки используют virtual DOM, реализованный уровнем выше, чем Shadow DOM
-
Shadow DOM вебкомпонентов не прозрачен для virtual DOM
-
вебкомпоненты работают со своим Shadow DOM, не влияют на virtual DOM фреймворка
-
внутренние процессы вебкомпонентов процессы изолированы от внешнего влияния и сами не влияют на внешнюю среду фреймворка
-
взаимодействие с внешней средой фреймворка через js-api вебкомпонента и его атрибуты
Использование библиотеки ui-вебкомпонент стало бы разумным решением.
Вебкомпоненты предоставляют возможность использовать единую оттестированную,
стабильную ui-билиотеку, которую можно использовать в качестве bootstrap
для любого web-приложения.
Polymer: миссия
Polymer предоставляет возможность использовать вебкомпоненты уже сегодня.
Возможности:
-
создание пользовательских элементов:
— регистрация пользовательского элемента, его ассоциация с именем и классом, описывающим жизненный цикл и логику работы элемента
— управление жизненным циклом элемента
— использование property-api элемента для его интеграции с Polymer data system -
использование Shadow DOM в polymer-компонентах позволяет создать:
— изолировать DOM-дерево пользовательского элемента
— создать DOM-дерево пользовательского элемента на основе DOM-template -
система событий
— декларативный синтаксис для добавления event listeners для элементов shadow DOM дерева
— библиотека для обработки событий-жестов -
Data system — data binding для свойств и атрибутов
— property observers
— computed properties.
Polymer: улучшения в 2.0
-
улучшена функциональная совместимость с библиотеками и фреймворками
— убрана необходимость использования Polymer.dom для манипуляций с DOM
— код Shadow DOM-полифила «shady DOM» выведен из Polymer
— для манипуляций с DOM используется стандартный API спецификации Shadow DOM -
улучшения в Data system
— упрощение распространения данных через/между элементами
— упрощение отладки распространения данных -
стандартизация
— поддержка спецификаций Shadow DOM v.1, Custom Elements v.1
— использование ES6 классов и стандартных методов спецификации Custom Elements v.1 для описания polymer-компонента
— жизненный цикл polymer-компонента соответствует Custom Elements v.1
Polymer: под капотом
Пока поддержка стека Web Components реализована не всеми браузерами, Polymer использует набор полифилов, объединенных в пакет webcomponents-lite.js:
— полифилы Shadow DOM:
Shady DOM,
Shady CSS
— полифилы
Custom Elements,
HTML Imports,
HTML Templates
Shady DOM:
зачем понадобился еще один полифил Shadow DOM?
Главная задача полифилов Shadow DOM заключается в изоляции теневого DOM (исключение влияния извне и наоборот).
- существующие полифилы Shadow DOM достаточно сложны и медленны в работе.
- Shady DOM представляет собой shim для Shadow DOM
(т.е. более легковесное чем полифил) - реализует (с некоторыми ограничениями) изоляцию теневого дерева без потерь производительности
- предоставляет API в соответствии со спецификацией Shadow DOM.
Все эти полифилы реализованы с учетом:
— минимизации потерь производительности
— максимальной совместимости по API со стеком стандартов Web Components
— перехода на использования браузерных реализаций вебкомпонентов при их наличии
— упрощения использования Polymer с другими библиотеками и фреймворками
Совместимость по API со стеком стандартов Web Components позволяет переключаться на использования браузерных реализаций вебкомпонентов при их наличии.
Polymer CLI
Входит в тренд предоставление CLI-клиента для фреймворка. Впервые CLI был реализован в Ember (2013), затем Angular (2015), Polymer (2016)
- предоставляет boilerplate-генератор для 2-х типов проектов: компонент и приложение
- предоставляет линтер, development server, test runner, сборщик проекта
- использует Bower для управления зависимостями
( для плоского дерева зависимостей Bower упрощаются относительные пути в импортах компонент )
Библиотеки UI-компонент
WEBCOMPONENTS.ORG
— единый репозиторий UI-компонент, созданных на базе технологий вебкомпонентов и Polymer:
- PolymerElements
(elements.polymer-project.org) - GoogleWebComponents
компоненты для работы с сервисами Google (входил в состав elements.polymer-project.org) - Vaadin
Кто использует вебкомпоненты/Polymer?
- Google
— толкает локомотив прогресса, основной разработчик стандартов
— давно использует вебкомпоненты/Polymer в своих продуктах - пользователи Angular2
— режим изоляции шаблонов “Shadow DOM” - Vaadin и его компоненты
— Works on any HTML5 based stack
— Supports Polymer and Angular 2 data binding
Web Components / Polymer : примеры
Проекты:
- Google Earth
— анонс - Новый интерфейс Youtube:
— анонс, как включить - Youtube Gaming
- Google Music, Google Sites, Polymer’s Element Catalog, Polymer Summit, Zeplin.io
- Who’s using Polymer?
Примеры:
- WEBCOMPONENTS.ORG
- Polymer Summit on Codelabs Google Developers: 2015, 2016
- PWA Google I/O 2016:
— анонс, исходники - PWA Polymer News:
— анонс, документация к проекту, исходники
Ссылки
- Custom Elements v1: Reusable Web Components
- Shadow DOM v1: Self-Contained Web Components
- Позвольте представить, Shadow DOM API на основе слотов
- About Polymer 2.0
- Теневой DOM (Shady DOM)
-
Диалог:
— Невыполненные обещания веб-компонентов
— Размышления по поводу невыполненных обещаний веб-компонентов - полная коллекция ссылок к докладу