Библиотека Polymer, скажу с предубеждением, хорошая, код получается красивый и чистый, а вот падение производительности во всё ещё популярном браузере Firefox — то что не сделает её популярной в ближней перспективе, по моему мнению. Ибо кому оно надо возится, если есть другие, более работающие вещи, а поиски в этих ваших в интернетах решения не дают.
Однако может всё же можно что-то сделать? Так точно. Можно!
Если вы дочитали до этого места и не утратили интереса, то скорее всего вы в курсе, что такое Polymer в текущей своей второй версии и как именно он объявляет зависимости и полифилы. Тег <link rel="import">, который для этого используется, и есть корень проблемы, он не поддерживается и никогда не будет поддерживается в Firefox.
После загрузки страницы подтягивается содержимое по ссылкам , происходит разбор и исполнение содержимого, только после этого компоненты становятся доступны и начинают отображаться, в результате мы имеем в зависимости от скорости соединения от полусекунды полностью или частично недоступное приложение, что просто некрасиво.
Что с этим делать, спросите вы? Может есть сборочные инструменты какие? Может команда малоизвестной корпорации уже постаралась?
Сборочный инструмент есть, но в результате у нас не несколько, а один <link rel="import">, в котором ассорти html и тегов script.
Постойте, а как же билд в один js? А никак! Или всё же как-то?
Очередная новость от команды разработчиков была про подготовку третьей версии
Imports use ES6 import syntax, not <link rel="import">.
Templates are defined by providing a template getter that returns a string—not the <dom-module> and <template> elements.
Чистый JS, короче. А теперь посмотрим, как он сделан. Ведь свои компоненты мы всегда можем переписать, а что делать с вендорными iron и paper, например.
Для начала посмотрим, что с ними сделали наши друзья.
iron-icon
iron-form
Они просто автоматически сконвертировали компоненты в чисто яваскриптовые.
Перенесли шаблоны из тега в свойство объекта и обернули компоненты в функцию автоматического добавления.
Ну так любой сможет, поэтому давайте попробуем сами.
Для начала соберём файлы с компонентами в один штатным polymer build, а затем натравим на результат gulp и попробуем получить js.
let cheerio = require('gulp-cheerio');
...
.pipe(cheerio(
{
run: function ($) {
$('body > div > *').each(function () {
if (this.tagName === 'script') {
return;
}
let $this = $(this);
if (this.tagName === 'dom-module') {
let script = $this.children('script').html();
let template = $this.children('template').html();
if (template && script) {
script = script.replace('Polymer({', "Polymer({_template:`" + template + '`,');
script = script.replace('static get is()', 'static get template(){return `' + template + '`}static get is()');
$this.after($('<script>' + script + '</script>'));
$this.remove();
return;
}
}
$this.after($('<script>Polymer.addToHead(`' + $.html(this) + '`);</script>'));
$this.remove();
});
}, parserOptions: {decodeEntities: false}
}))
где код
Polymer.addToHead = (code) => {
let a = document.createElement('div');
a.style.display = 'none;';
a.innerHTML = code;
document.head.appendChild(a);
};
Должен быть подключен сразу после <link rel="import" href="../../libraries/polymer/polymer.html"/>, ну или как вы там сами себе придумаете.
В результате мы получаем html состоящий исключительно из тегов <script>, что уже намного ближе к желаемому результату.
.pipe(splitJsCss({
type: ['js']
}))
.pipe(gzip())
И вот у нас уже сжатый js на выходе, который можно подключить как любой другой js так, как это принято в вашем проекте.
Внезапно, вдруг(tm) исчезает задержка в Firefox. Нет накладных расходов на догрузку и парсинг, всё исполняется синхронно. И кешируется согласно общим политикам сайта.
Не могу сказать, что всё это так же изящно, как стрелочные функции в ES6, но библиотекой Polymer стало можно пользоваться гораздо гораздее, чем буквально за час до прочтения этой статьи.
P.S. Есть ли недостатки? Ну если вы особенно хитро раньше подгружали компоненты по требованию, вам теперь придётся самостоятельно следить за двойным исполнением, если конечно оно у вас было.
P.P.S. Почему драка, потому что перед написанием собственного сборщика я пытался предложить разработчикам самим перенести шаблоны в яваскрипт, но общего языка не удалось найти. Библиотека позволяющая писать красивый код и разработчики душащие своими руками саму возможность широкого её использования уже сегодня.
Комментарии (24)
Punk_UnDeaD Автор
18.12.2017 22:08platform-status.mozilla.org/#html-imports
Добавил в статью.sshikov
18.12.2017 22:15Ну, про "никогда" они кажется все-таки не писали. Пишут, что нет дескать консенсуса по стандартам. Что на мой взгляд — просто чепуха. Когда это статус драфта кого-то останавливал?
SirEdvin
18.12.2017 22:17Статус драфта значит, что пока можно не пилить, а заняться другими делами. Вроде так…
sshikov
18.12.2017 22:22Чтобы потом, когда стандарт утвержден, оказаться едиственным, у кого еще не допилено? :) Всегда и все начинали делать именно в статусе драфта. Мне кажется, это синдром NIH в чистом виде.
Punk_UnDeaD Автор
18.12.2017 22:18Ну считайте, что я ставлю сотню против ржавого гвоздя, что никогда.
На ближайшие два года нет разницы, а там может и концепция изменится.sshikov
18.12.2017 22:20Не, я могу сам поставить, что не сделают :) я только говорю про тексты, которые встречал. Там все-таки более расплывчато, типа, мы не хотим пилить два механизма импорта, туды-сюды, мы ждем консенсуса по стандарту… тьфу.
sshikov
18.12.2017 22:29Но я бы скорее такой вариант предсказал, что все у них давно реализовано, потому что чего там реализовывать, когда у других уже все есть? Html imports, по крайней мере на первый взгляд, самая простая из четырех составляющих web components.
Самое противное знаете что? Что сто лет назад (ну хорошо, не 100, а в 2009 для определенности), в Flex, уже все было как надо. Т.е. можно было в MXML написать xml namespace, и воспользоваться элементами для создания компонент внутри своей разметки, а можно было написать import в AS3 коде, импортировать классы, и создавать компоненты динамически. Т.е. попросту говоря, хочешь статическую компоновку страницы из custom компонент — к своим услугам язык а-ля HTML, хочешь динамически и с финтифлюшками — берешь полноценный язык программирования, и ваяешь на нем.
vintage
18.12.2017 23:19В итоге от "будущего" ничего и не осталось — собрали всё в js бандл как любой другой фреймворк :-) Как я всегда говорил web-components — мертворождённая технология.
eugef
19.12.2017 13:58HTML imports лишь одна из трех спецификаций, из которых состоят Web-components. Остальные — либо уже реализованы, либо в разработке во всех современных браузерах.
P.S. В Polymer 3 HTML imports уже не будет из коробки.
P.P.S. Избавление от HTML imports также очень сильно ускоряет IE и Edge.
RomanPokrovskij
20.12.2017 03:29А можно почитать где вы об этом говорили? (не в смысле проверить, а в смысли ознакомится с авторитетными аргументами).
vintage
20.12.2017 09:24Аргументы простые:
- Каскадная загрузка зависимостей приводит к долгой загрузке всего, ибо пока браузер не загрузит зависимость, он не узнает какие у неё зависимости.
- Каскадная загрузка зависимостей приводит к визуальным артефактам во время первичной загрузки.
- Из-за тотальной изоляции крайне сложно кастомизировать компоненты извне.
- Вместо одного дом-дерева у вас много дом-деревьев и кривой апи, где половина ручек работает с локальным деревом, половина с глобальным. Не помню деталей, но там всё довольно кривосыро. Вроде были проблемы с получением шаблона при импорте компонента из компонента.
RomanPokrovskij
20.12.2017 12:54Спасибо. Может быть глупый вопрос: а чем тотальна изоляция polymer web component? Более чем react component?
vintage
20.12.2017 21:17Я сейчас говорил про нативные web-components. Полимер-то умеет "вулканизировать", собирая бандлы, что лишний раз показывает бестолковость изначальной идеи о пофайловой загрузке модулей. Это на сервере можно себе позволить ходить за модулями по требованию, ибо до файловой системы латентность крайне низка. Для фронта это не годится.
Punk_UnDeaD Автор
20.12.2017 21:23Вроде как подразумевается, что с http/2 всё становится волшебно.
А ещё есть манифест. Но особенного смысла по сравнению с упаковкой я тоже не вижу.
Только давайте отдельно про загрузку, а отдельно про изоляцию.
Boyd_Rice
19.12.2017 13:49Как-то с трудом представляю веб-компоненты в конвейере какого-либо популярного фреймворка, особенно Angular.
PS: «Полимерная» версия Youtube работает отвратительно медленно что в Chrome, что в Edge, что в FF, что в Опере.
TargetSan
А можете кинуть ссылку, почему Firefox "никогда не будет поддерживать" этот тег? Или это вендорское MS-style расширение от Google?
sshikov
https://www.w3.org/TR/html-imports/
Ну какое-же это вендорское?
Почему не будет? Потому что они упоротые болваны. В мозилле, ясное дело. Не, есть конечно шанс, что их кто-то убедит, но до сего момента их аргументы настолько слабые, что непонятно, как убеждать.
Punk_UnDeaD Автор
Да там со всех сторон красавцы. В стиле «это наша песочница и она будет зелёной».
Google то тоже отказывается от этого тега в полумерах. Надо понимать, потом и из браузера выбросят.
sshikov
Гугль в смысле разработчики полимера? Нет слов… неужели они все не понимают, что импорты в html и импорты в js — это разные вещи? Что удобно иметь и то, и другое.