- PVSM.RU - https://www.pvsm.ru -
Проекте, над которым я сейчас работаю, имеет виджетоподобную клиентскую архитектуру. Причем виджеты системы могут использовать любую библиотеку для своей реализации, например, ReactJS, PolymerJS, VueJS, d3JS и другие. Несколько виджетов системы реализованы, как раз, как вэб-компоненты на базе PolymerJS [1].
Поэтому предлагаю вашему вниманию один из подходов для оптимизации polymer-виджетов.
1. Описание проблемы [2]
2. Какие сложности возникают? [3]
3. Как их можно решить? [4]
4. Библиотека vulcanize-polymer-module [5]
4.1. Структура [6]
4.2. Описание bower.json [7]
4.3. Описание package.json [8]
4.3.1. Установка утилит [9]
4.3.2. Настройка RollupJS [10]
4.4. vulcanize-utils.js [11]
5. Выводы [12]
Одним из главных проблем polymer-приложений — это множественная подгрузка, используемых компонентов и всех зависимых компонентов, которые в свою очередь, могут состоять из вспомогательных стилей, behavior-ов [13], подгружаемых так же дополнительно. В результате консоль в network-разделе будет «засыпана» данными файлами. В виду всего этого, первая загрузка такого виджета может быть достаточно долгой, в зависимости от количества используемых составных вэб-компонентов.
Для этих целей в polymer-приложениях применяется вулканизация. Подразумевается, что у данного приложения, есть точка входа в виде, например, index.html, в котором разворачивается главный компонент-контейнер, например <App/>. В данном файле подключается само ядро polymer и файл компонента-контейнера <App/> и далее иерархически подключаются все используемые компоненты, которые сами являются отдельными html-файлами. Сам процесс вулканизации заключается в «склеивании» всех используемых компонентов и ядра polymer в один файл, который и будет в итоге являться точкой входа для index.html.
Если рассмотреть первую сложность, я бы мог вулканизировать отдельно каждый УК, но тогда, если взять третью проблему возможно дублирование одних и тех же ГК, и точно будет дублирование ядра polymer, если рассмотреть ситуацию, при которой за одну сессию были использованы как минимум два УК. Поэтому необходимо другое решение.
Если рассмотреть вторую сложность, нужно сделать так, что бы ядро polymer и ГКы загружались только один раз, при первом обращении к одному из УК, и на момент обращения ко второму, нет необходимости загружать заново все, а только загрузить динамически сам УК.
Если рассмотреть третью сложность, то нам нужно составить список всех используемых глупых компонентов в умных, который в итоге мы и будем вулканизировать вместе с самим polymer.
Все выше сказанные тезисы я оформил в виде библиотеки vulcanize-polymer-module.
Хочу рассказать о ней подробней.
vulcanize-polymer-module/
├── imports.html
├── vulcanize-utils.js
├── rollup.config.js
├── bower.json
└── package.json
В нем мы описываем все ГК, которые нам необходимы, как зависимости, включая так же само ядро polymer.
Например, раздел dependencies может выглядеть так:
"dependencies": {
"polymer": "Polymer/polymer#^2.0.0",
"polymer-redux": "^1.0.0",
"iron-flex-layout": "PolymerElements/iron-flex-layout#^2.0.0",
"paper-button": "PolymerElements/paper-button#^2.0.0",
"paper-badge": "PolymerElements/paper-badge#^2.0.0",
"paper-icon-button": "PolymerElements/paper-icon-button#^2.0.0",
"paper-input": "PolymerElements/paper-input#^2.0.0",
"paper-item": "PolymerElements/paper-item#^2.0.0",
"paper-checkbox": "PolymerElements/paper-checkbox#^2.0.0",
"paper-tabs": "PolymerElements/paper-tabs#^2.0.0",
"paper-listbox": "PolymerElements/paper-listbox#^2.0.0",
"iron-a11y-keys": "PolymerElements/iron-a11y-keys#^2.0.0",
"iron-list": "PolymerElements/iron-list#^2.0.0",
"iron-icons": "PolymerElements/iron-icons#^2.0.0",
"paper-progress": "PolymerElements/paper-progress#^2.0.0",
"vaadin-split-layout": "vaadin/vaadin-split-layout#^2.0.0",
"vaadin-grid": "^3.0.0",
"iron-pages": "PolymerElements/iron-pages#^2.0.0",
"iron-collapse": "PolymerElements/iron-collapse#^2.0.0",
"iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#^2.0.0",
"vaadin-context-menu": "^3.0.0"
}
Так как я совместно с polymer использую redux, я включил библиотеку polymer-redux [16].
В нем прописаны зависимости, необходимые нам для сборки, в частности RollupJS [17], который используется для промежуточной очистки кода выходного файла. Так же описаны команды, используемые для вулканизации, давайте рассмотрим их подробнее.
"scripts": {
"build": "rollup -c",
"vulcanize": "vulcanize imports.html --inline-scripts --inline-css --strip-comments",
"run-vulcanize": "npm run vulcanize > imports.vulcanize.html",
"vulcanized": "vulcanize imports.html --inline-scripts --inline-css --strip-comments | crisper --html imports.vulcanized.html --js imports.vulcanized.js > imports.vulcanized.html",
"html-minifier": "html-minifier imports.vulcanized.html --remove-optional-tags --collapse-whitespace --preserve-line-breaks -o imports.vulcanized.min.html",
"build-all": "npm run vulcanized && npm run build && npm run html-minifier"
}
Команды, в порядке и приоритетности их использования:
Как видим используется множество дополнительных утилит, которые нам необходимо предварительно установить в систему.
npm install -g vulcanize
npm install -g crisper
npm install -g html-minifier
Так как rollup используется только для очистки js-кода я использую только один плагин к нему- rollup-plugin-cleanup [21]. Плагин rollup-plugin-progress [22] используется для визуализации процесса сборки.
import progress from 'rollup-plugin-progress';
import cleanup from 'rollup-plugin-cleanup';
export default {
entry: 'imports.vulcanized.js',
dest: 'imports.vulcanized.js',
plugins: [
cleanup(),
progress({
}),
]
};
Для решения второго требования был написан утилитарный метод loadVulcanized, который загружает УК, но перед этим загружает вулканизированный файл, причем делает это один раз и в случаи повторного вызова загружает только сам УК.
Рассмотрим подробнее его параметры.
Конечно можно использовать polymer-cli [23] с параметром build, но при сборке с его помощью подразумевается, что билдится polymer-проект, а так как мы используем компоненты не в одном контейнере <App/>, то собирать каждый УК придется по отдельности и файлы сборки будут иметь дублирование ядра polymer и составных ГК. Поэтому подход, описанный в статье имеет достаточную эффективность в системах использующих несколько UI-библиотек совместно, за счет единой точки входа для всех УК на базе polymer.
Один из возможных минусов можно рассмотреть, как избыточность ГК в вулканизированном файле, так как в нем собраны все ГК всех УК, используемых
в системе, но при этом не все УК могут быть использованы за сессию работы, в виду чего не все ГК будут использованы в загруженом вулканизированном файле.
Так же, как небольшое неудобство, можно рассмотреть тот факт, что после добавления нового компонента необходимо запустить сборку заново, после чего сделать обновление репозитория(push), а другие пользователи должны обновить данную библиотеку через bower update.
Несмотря на все это данная библиотека решает свою задачу в данном проекте, а значит может пригодится и кому-то еще.
Так что форкайте [24], милости просим.
Автор: kolesoffac
Источник [25]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/261486
Ссылки в тексте:
[1] PolymerJS: https://www.polymer-project.org/
[2] 1. Описание проблемы: #1
[3] 2. Какие сложности возникают?: #2
[4] 3. Как их можно решить?: #3
[5] 4. Библиотека vulcanize-polymer-module: #4
[6] 4.1. Структура: #41
[7] 4.2. Описание bower.json: #42
[8] 4.3. Описание package.json: #43
[9] 4.3.1. Установка утилит: #431
[10] 4.3.2. Настройка RollupJS: #432
[11] 4.4. vulcanize-utils.js: #44
[12] 5. Выводы: #5
[13] behavior-ов: https://www.polymer-project.org/1.0/docs/devguide/behaviors
[14] paper-: https://www.webcomponents.org/collection/PolymerElements/paper-elements
[15] iron-: https://www.webcomponents.org/collection/PolymerElements/iron-elements
[16] polymer-redux: https://github.com/tur-nr/polymer-redux
[17] RollupJS: https://habrahabr.ru/post/331412/
[18] vulcanize : https://www.npmjs.com/package/vulcanize
[19] crisper: https://github.com/PolymerLabs/crisper
[20] html-minifier: https://www.npmjs.com/package/html-minifier
[21] rollup-plugin-cleanup: https://github.com/aMarCruz/rollup-plugin-cleanup
[22] rollup-plugin-progress: https://github.com/jkuri/rollup-plugin-progress
[23] polymer-cli: https://www.polymer-project.org/2.0/docs/tools/polymer-cli-commands
[24] форкайте: https://github.com/kolesoffac/vulcanize-polymer-module
[25] Источник: https://habrahabr.ru/post/333660/
Нажмите здесь для печати.