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  
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 ElementClass extends HTMLElement {}

  • регистрация элемента
    v.0: window.document.registerElement('my-element', MyElement)
    v.1: window.customElements.define('my-element', MyElement)

  • промис момента регистрации элемента
    v.1: customElements.whenDefined('my-element')

  • определение конструктора класса элемента по его имени:
    v.1: customElements.get('element-name')

  • жизненный цикл элемента:

  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 : примеры

Проекты:

Примеры:

Ссылки

comments powered by Disqus