Производительность
Гранулярность — главное обещание продукта. Страница показывает, чем оно измеряется и как проверить его самому.
Обещание формулируется коротко: бандл растёт от того, что вы используете, а не от того, что есть в пакете. Ниже — чем это обеспечено, сколько стоит на самом деле и как померить у себя, не веря на слово.
Две стороны, и они не коррелируют
Вес компонента складывается из кода и стилей, и эти величины живут отдельно:
| Компонент | CSS, прирост листа | JS, сам компонент |
|---|---|---|
GrCard | 235 B | 2 779 B |
GrDialog | 670 B | 9 989 B |
GrDataTable | 2 911 B | 36 431 B |
GrSelect | 3 037 B | 23 216 B |
Тяжёлый по коду компонент может почти ничего не добавить к листу, и наоборот. Поэтому «вес компонента» одним числом не измеряется, а любая таблица с одной колонкой врёт. Числа те же, что на главной: их снимает скрипт замера по ядру, а не человек.
Код: подпуть вместо бареля
// один компонент и его граф
import { GrButton } from '@feugene/granularity/components/GrButton'
// весь пакет — granum 2 отвергает такой импорт: ComponentRootImportError
import { GrButton } from '@feugene/granularity'Верхняя строка — это и есть гранулярность. Вес подпути — gzip всего, что он
тянет из dist, вместе с вложенными компонентами, но без внешних пакетов и без
CSS. Самый лёгкий подпуть — обёртка GrButtonGroup: сама по себе она весит
1.5 kB, но без своих кнопок не используется — GrButton приходит в неё слотом
и импортируется своим подпутём. Самый тяжёлый — GrDataTable, 115.8 kB. Весь
пакет из корня — 655.4 kB.
Складывать веса подпутей нельзя. Общий чанк посчитан в каждой строке заново, а платится один раз: сумма пяти самых тяжёлых строк даёт 487.1 kB, а вместе они весят 251.9 kB. Набор считается объединением, а не суммой — и это верхняя граница: бандлер приложения трясёт дерево дальше и минифицирует повторно.
Полная таблица по каждому подпути генерируется из собранного dist на каждом
релизе — она лежит в пакете и на странице каждого компонента в
каталоге.
Стили: платите за выбранное
CSS не импортируется файлами — его собирает granum ровно для тех компонентов,
которые вы перечислили в components, и для их зависимостей. Что нужно каждому
компоненту — классы, собственный styles.css, токены, — записано в манифесте
пакета, и лист собирается по манифестам, а не по node_modules. Структура
расхода такая:
- Первый компонент несёт фундамент — токены, базовый слой, preflight, тему. Это разовая плата.
- Каждый следующий добавляет свои сотни байт — от двух сотен у карточки до трёх килобайт у селекта.
- Вторая тема стоит около полутора килобайт, а не вдвое: темы отличаются значениями ролей, а не правилами.
Не перечислять components вовсе — рабочий вариант: тогда в лист приедут все
компоненты провайдера. Разница между «всё» и «один» на общем листе — примерно
вдвое, а не в сто раз, потому что фундамент один на всех. Гранулярность стилей
имеет смысл, но её эффект скромнее, чем у кода, и честно сказать об этом дешевле,
чем потом объясняться.
Рантайм
- Ноль runtime-зависимостей у ядра. Единственная обязательная внешняя
библиотека —
@floating-ui/dom, и она объявлена peer-зависимостью приложения, чтобы не приехать второй копией. - CSS компонента приходит через манифест, а не через чанк. JS-чанки пакета
стилей не импортируют: granum берёт
styles.cssкомпонента из манифеста и кладёт его в слойgranum.components— только для выбранных компонентов. Отдельного стилевого импорта нет, и это не удобство, а условие: иначе гранулярность ломалась бы на первом же забытом импорте. - Справочник токенов и тест-помощники — отдельные подпути (
/tokens,/testing), и барель ядра их не импортирует. Подсветки кода в ядре нет вовсе: она живёт в@feugene/granularity-code/highlight.
Как померить у себя
- Соберите приложение с одним компонентом и снимите gzip эмитированного CSS и JS.
- Добавьте второй компонент и снимите снова. Разница — его настоящая цена в вашем проекте.
- Сравните с барелем: импорт из корня granum не пропустит, поэтому на время замера выключите guard (
js: { guard: 'off' }) и повторите. Разница — то, от чего бережёт подпуть.
Числа на этом сайте снимают скрипты, а не сборка приложения. В таблице в начале
страницы лист собирает granum по манифесту ядра без исходников приложения, а
код — esbuild по подпути компонента, где vue, @floating-ui/dom и
@feugene/fint-i18n вынесены наружу. Поэтому смотреть на них стоит как на
порядок величины: ваш результат зависит от версии бандлера, настроек
минификации и от того, что ещё лежит в графе.
Что не ускорит ничего
importStyle: trueу резолвера авто-импорта. Ядру он не нужен: стили компонентов granum уже взял из манифестов, а подпутейcomponents/<Name>/styles.cssядро не публикует — включённая опция сломала бы сборку.- Ручные импорты
styles/*.cssповерх листа granum. Они добавят вес, а не уберут: токены, базу и темы granum уже положил в свои слои, а файл, импортированный вне слоёв, ещё и перебьёт их в каскаде. - Сужение
themes.namesдо одной темы ради экономии. Вторая тема стоит около полутора килобайт — это не то место, где стоит терять переключение.