Treeshaking — это механизм оптимизации сборки приложения, при котором из итогового бандла удаляется неиспользуемый код. Название происходит от метафоры «стряхивания дерева»: сборщик проходит по дереву зависимостей и удаляет ветви, которые не используются в приложении.
В контексте интерфейсных библиотек treeshaking особенно важен. UI-фреймворки часто содержат десятки или сотни компонентов, утилит, директив и вспомогательных модулей. Если подключить всю библиотеку целиком, итоговый размер JavaScript-бандла может значительно увеличиться, что приводит к:
Vuetify — крупная библиотека компонентов для Vue, поэтому поддержка treeshaking является ключевым элементом её архитектуры.
Treeshaking выполняется на этапе сборки приложения. Современные сборщики анализируют структуру модулей ES Modules и определяют, какие экспортированные элементы реально используются.
Механизм основан на двух ключевых свойствах ES-модулей:
1. Статический импорт
Импорт должен быть определён на верхнем уровне файла.
import { VBtn } from 'vuetify/components'
Сборщик может определить, что используется только
VBtn.
2. Статический анализ
Так как структура модулей известна заранее, сборщик строит граф зависимостей и исключает неиспользуемые экспорты.
Например:
export const A = ...
export const B = ...
export const C = ...
Если импортируется только A, то B и
C удаляются из итогового бандла.
Vuetify проектируется таким образом, чтобы его можно было импортировать частично. Каждый компонент экспортируется отдельно.
Основные категории экспортов:
Это позволяет подключать только необходимый функционал.
Пример выборочного импорта:
import { createVuetify } from 'vuetify'
import { VBtn, VCard } from 'vuetify/components'
import { Ripple } from 'vuetify/directives'
export const vuetify = createVuetify({
components: {
VBtn,
VCard
},
directives: {
Ripple
}
})
В этом случае в сборку попадут только:
VBtnVCardRippleОстальные компоненты будут исключены.
Vuetify использует модульную архитектуру, оптимизированную для treeshaking.
Основные точки входа:
vuetify
vuetify/components
vuetify/directives
vuetify/iconsets
vuetify/labs
import { VBtn } from 'vuetify/components'
import { Ripple } from 'vuetify/directives'
import { VDataTable } from 'vuetify/labs/VDataTable'
Такая структура позволяет сборщику точно определить используемые части библиотеки.
В некоторых проектах используется импорт всей библиотеки:
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
createVuetify({
components,
directives
})
Такой подход отключает преимущества treeshaking, потому что сборщик считает, что используются все экспорты.
В результате:
Поэтому для production-сборок рекомендуется выборочный импорт.
Treeshaking выполняется сборщиком проекта. Наиболее распространённые инструменты:
Vite использует Rollup при production-сборке, поэтому treeshaking работает автоматически.
Пример конфигурации:
import { createVuetify } from 'vuetify'
import { VBtn } from 'vuetify/components'
export default createVuetify({
components: {
VBtn
}
})
Rollup исключит все неиспользуемые компоненты.
Для корректного treeshaking должны выполняться условия:
Пример настройки:
mode: 'production'
Webpack анализирует импорты и удаляет неиспользуемые части.
Rollup изначально разработан для эффективного treeshaking.
Особенности:
Treeshaking невозможен, если модуль имеет побочные эффекты.
Пример side effect:
console.log('module loaded')
Или:
window.someGlobal = true
Сборщик не может удалить такой модуль, потому что его выполнение влияет на поведение программы.
Vuetify спроектирован так, чтобы минимизировать side effects и позволить сборщикам безопасно удалять неиспользуемые компоненты.
Vuetify использует систему стилей на основе Sass и CSS-переменных.
Существует два подхода к подключению стилей.
import 'vuetify/styles'
Этот вариант подключает полный набор базовых стилей.
В некоторых случаях можно подключать только необходимые стили, особенно при кастомных сборках.
Однако большинство проектов используют стандартный набор, поскольку размер CSS относительно невелик по сравнению с JavaScript-частью библиотеки.
Для упрощения разработки используются плагины автоматического импорта.
Популярный инструмент:
unplugin-vue-components
Он автоматически анализирует шаблоны Vue и добавляет необходимые импорты.
Пример:
<template>
<v-btn>Click</v-btn>
</template>
Плагин автоматически преобразует это в:
import { VBtn } from 'vuetify/components'
В результате:
Динамический импорт позволяет дополнительно уменьшить размер начального бандла.
Пример:
const Dialog = () => import('./Dialog.vue')
Компонент будет загружен только при необходимости.
В сочетании с Vuetify это позволяет:
После сборки проекта полезно анализировать размер бандла.
Инструменты:
Они показывают:
Это помогает убедиться, что treeshaking работает корректно.
Неправильный вариант:
import * as Vuetify from 'vuetify/components'
Это приводит к загрузке всех компонентов.
Treeshaking плохо работает с CommonJS.
Нежелательный вариант:
const vuetify = require('vuetify')
Предпочтительно использовать ES Modules.
Некоторые плагины могут нарушать оптимизацию сборки, если они:
Минимальная конфигурация Vuetify с поддержкой treeshaking:
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import { VBtn, VCard } from 'vuetify/components'
import { Ripple } from 'vuetify/directives'
export const vuetify = createVuetify({
components: {
VBtn,
VCard
},
directives: {
Ripple
}
})
Такой подход обеспечивает: