Производительность
Гранулярность — главное обещание продукта. Страница показывает, чем оно измеряется и как проверить его самому.
Обещание формулируется коротко: бандл растёт от того, что вы используете, а не от того, что есть в пакете. Ниже — чем это обеспечено, сколько стоит на самом деле и как померить у себя, не веря на слово.
Две стороны, и они не коррелируют
Вес компонента складывается из кода и стилей, и эти величины живут отдельно:
| Компонент | CSS, прирост листа | JS, сам компонент |
|---|---|---|
GrCard | 223 B | 1 870 B |
GrDialog | 318 B | 9 789 B |
GrDataTable | 705 B | 16 243 B |
GrSelect | 2 335 B | 19 819 B |
Тяжёлый по коду компонент может почти ничего не добавить к листу, и наоборот. Поэтому «вес компонента» одним числом не измеряется, а любая таблица с одной колонкой врёт.
Код: подпуть вместо бареля
// один компонент и его граф
import { GrButton } from '@feugene/granularity/components/GrButton'
// весь пакет
import { GrButton } from '@feugene/granularity'Верхняя строка — это и есть гранулярность. Разброс между самым лёгким и самым
тяжёлым подпутём — почти два порядка: GrButtonGroup тянет 1.8 kB gzip, меньше
процента от бареля, GrDialogService — 89.3 kB. Весь пакет из корня — 537.9 kB.
Складывать веса подпутей нельзя. Общий чанк посчитан в каждой строке заново, а платится один раз: сумма пяти самых тяжёлых строк даёт 382.3 kB, а вместе они весят 171.7 kB. Набор считается объединением, а не суммой — и это верхняя граница: бандлер приложения трясёт дерево дальше и минифицирует повторно.
Полная таблица по каждому подпути генерируется из собранного dist на каждом
релизе — она лежит в пакете и на странице каждого компонента в
каталоге.
Стили: платите за выбранное
CSS не импортируется файлами — его генерирует пресет ровно для тех компонентов,
которые вы перечислили в components. Структура расхода такая:
- Первый компонент несёт фундамент — токены, базовый слой, preflight, тему. Это разовая плата.
- Каждый следующий добавляет свои сотни байт — от двух сотен у карточки до пары килобайт у селекта.
- Вторая тема стоит около килобайта, а не вдвое: темы отличаются значениями ролей, а не правилами.
Не перечислять components вовсе — рабочий вариант: тогда в лист приедут все
компоненты провайдера. Разница между «всё» и «один» на общем листе — примерно
вдвое, а не в сто раз, потому что фундамент один на всех. Гранулярность стилей
имеет смысл, но её эффект скромнее, чем у кода, и честно сказать об этом дешевле,
чем потом объясняться.
Рантайм
- Ноль runtime-зависимостей у ядра. Единственная обязательная внешняя
библиотека —
@floating-ui/dom, и она объявлена peer-зависимостью приложения, чтобы не приехать второй копией. - CSS компонента едет в его же чанке. Отдельного стилевого импорта нет — и это не удобство, а условие: иначе гранулярность ломалась бы на первом же забытом импорте.
- Подсветка, справочник токенов и тест-помощники — отдельные подпути, и в основной бандл они не попадают вовсе.
Как померить у себя
- Соберите приложение с одним компонентом и снимите gzip эмитированного CSS и JS.
- Добавьте второй компонент и снимите снова. Разница — его настоящая цена в вашем проекте.
- Сравните с барелем: замените подпуть на импорт из корня и повторите. Разница — то, за что вы платите за удобство.
Числа на этом сайте сняты ровно так же. Смотреть на них стоит как на порядок величины: ваш результат зависит от версии бандлера, настроек минификации и от того, что ещё лежит в графе.
Что не ускорит ничего
importStyle: trueу резолвера авто-импорта. Ядру он не нужен: у большинства компонентов своего CSS нет, а у остальных он уже в чанке.- Ручные импорты
styles/*.cssповерх пресета. Они добавят вес, а не уберут: то же самое пресет уже сгенерировал. - Сужение
themes.namesдо одной темы ради экономии. Вторая тема стоит около килобайта — это не то место, где стоит терять переключение.