Минификация — процесс удаления из исходного кода лишних символов, комментариев, пробелов и переносов строк без изменения поведения программы. В проектах с Tom Sel ect минификация влияет не только на скорость загрузки интерфейса, но и на производительность поиска, рендеринга элементов и инициализации компонентов формы.
Tom Sel ect активно используется в административных панелях, CRM, SPA-приложениях и сложных формах, где одновременно может существовать множество селекторов. При большом количестве экземпляров библиотеки размер итогового bundle-файла становится критически важным.
Минификация в контексте Tom Sel ect обычно решает несколько задач:
В npm-пакете библиотеки уже присутствуют готовые минифицированные файлы:
<link rel="stylesheet" href="tom-select.default.min.css">
<script src="tom-select.complete.min.js"></script>
Файл tom-select.complete.min.js содержит:
Размер complete-сборки значительно больше минимальной модульной конфигурации.
Наиболее эффективный способ оптимизации — импорт только необходимых частей библиотеки.
import TomSelect fr om 'tom-select';
Подобный импорт может подтянуть:
Tom Sel ect позволяет подключать плагины вручную.
import TomSelect fr om 'tom-select/base';
import TomSelect fr om 'tom-select/base';
import remove_button fr om 'tom-select/plugins/remove_button';
TomSelect.define('remove_button', remove_button);
Такой подход уменьшает итоговый размер bundle-файла.
Tree Shaking — механизм удаления неиспользуемого кода во время сборки проекта.
Наиболее эффективно работает в:
import TomSelect from 'tom-select/base';
new TomSelect('#tags', {
plugins: ['remove_button']
});
При правильной конфигурации сборщик удалит:
Tom Sel ect поставляется с несколькими темами оформления:
Подключение всех тем одновременно приводит к значительному увеличению CSS-файла.
import 'tom-select/dist/css/tom-select.default.css';
import 'tom-select/dist/css/tom-select.bootstrap4.css';
import 'tom-select/dist/css/tom-select.bootstrap5.css';
import 'tom-select/dist/css/tom-select.default.css';
Tom Sel ect содержит множество CSS-классов, часть которых может никогда не использоваться в конкретном проекте.
PurgeCSS позволяет удалить:
module.exports = {
content: [
'./src/**/*.html',
'./src/**/*.js'
],
css: [
'./node_modules/tom-select/dist/css/tom-select.default.css'
]
};
Terser — стандартный минификатор JavaScript.
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false
})
]
}
};
Terser выполняет:
В production-сборках большое количество логов может влиять на производительность.
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true
}
}
})
esbuild работает значительно быстрее классических минификаторов.
require('esbuild').build({
entryPoints: ['src/app.js'],
bundle: true,
minify: true,
outfile: 'dist/app.js'
});
Преимущества:
Rollup особенно эффективен для ESM-библиотек.
import resolve fr om '@rollup/plugin-node-resolve';
import terser fr om '@rollup/plugin-terser';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
},
plugins: [
resolve(),
terser()
]
};
Tom Sel ect не всегда нужен на всех страницах приложения.
Code splitting позволяет загружать библиотеку только там, где она действительно используется.
async function initSelect() {
const { default: TomSelect } = await import('tom-select');
new TomSelect('#users');
}
Преимущества:
При большом количестве элементов полезно откладывать создание экземпляров Tom Sel ect.
const observer = new IntersectionObserver(entries => {
entries.forEach(async entry => {
if (entry.isIntersecting) {
const { default: TomSelect } =
await import('tom-select');
new TomSelect(entry.target);
observer.unobserve(entry.target);
}
});
});
document.querySelectorAll('.lazy-select')
.forEach(el => observer.observe(el));
Многие проекты используют только 1–2 плагина из полного набора.
Каждый плагин увеличивает:
Tom Sel ect поддерживает кастомный рендеринг через функцию
render.
Сложные шаблоны существенно замедляют интерфейс.
render: {
option(data) {
return `
<div class="option">
<img src="${data.avatar}">
<div>
<strong>${data.name}</strong>
<small>${data.email}</small>
</div>
</div>
`;
}
}
Проблемы:
render: {
option(data) {
return `<div>${data.name}</div>`;
}
}
Минимальный DOM ускоряет:
Tom Select использует внутренний механизм поиска по полям.
Чем больше полей участвует в поиске, тем выше нагрузка.
searchField: [
'name',
'email',
'company',
'address',
'department'
]
searchField: ['name']
Большие списки сильно нагружают DOM.
maxOptions: 50
Преимущества:
При работе с тысячами записей полезно использовать серверную фильтрацию вместо полной загрузки.
options: hugeArray
load(query, callback) {
fetch(`/api/users?q=${query}`)
.then(r => r.json())
.then(data => callback(data));
}
Такой подход:
Без debounce Tom Select может отправлять множество запросов подряд.
loadThrottle: 300
Это уменьшает:
При динамическом удалении компонентов важно корректно уничтожать экземпляры Tom Select.
const select = new TomSelect('#users');
select.destroy();
Без destroy():
Некоторые плагины используют встроенные SVG-элементы.
SVG также нуждаются в оптимизации.
npx svgo icon.svg
Даже минифицированные файлы желательно дополнительно сжимать на сервере.
gzip on;
gzip_types text/css application/javascript;
brotli on;
brotli_types text/css application/javascript;
Brotli обычно обеспечивает лучшее сжатие JavaScript.
В production source maps часто отключают для уменьшения размера сборки.
module.exports = {
devtool: false
};
Использование CDN уменьшает задержки загрузки.
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/tom-select/dist/css/tom-select.css"
/>
<script
src="https://cdn.jsdelivr.net/npm/tom-select/dist/js/tom-select.complete.min.js">
</script>
Tom Select редко обновляется в production.
Для статических файлов полезно включать длительное кеширование.
location /assets/ {
expires 1y;
add_header Cache-Control "public";
}
Для поиска проблемных зависимостей используются анализаторы бандла.
npm install webpack-bundle-analyzer
const BundleAnalyzerPlugin =
require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
plugins: [
new BundleAnalyzerPlugin()
]
Анализатор позволяет определить:
Инициализация десятков экземпляров Tom Select одновременно может замедлять интерфейс.
document.querySelectorAll('select')
.forEach(el => new TomSelect(el));
requestIdleCallback(() => {
document.querySelectorAll('select')
.forEach(el => new TomSelect(el));
});
Tom Select может использоваться вместе с динамическими интерфейсами.
Чрезмерное использование MutationObserver приводит к:
Наблюдатели следует ограничивать:
| Метод | Влияние на размер | Влияние на скорость |
|---|---|---|
| Tree shaking | Высокое | Среднее |
| Минификация JS | Среднее | Среднее |
| PurgeCSS | Высокое | Низкое |
| Code splitting | Высокое | Высокое |
| Lazy loading | Низкое | Высокое |
| Async load | Низкое | Высокое |
| Ограничение maxOptions | Низкое | Высокое |
| Удаление плагинов | Высокое | Среднее |
import { defineConfig } fr om 'vite';
export default defineConfig({
build: {
minify: 'esbuild',
cssCodeSplit: true,
sourcemap: false,
rollupOptions: {
output: {
manualChunks: {
tomselect: ['tom-select']
}
}
}
}
});
import TomSelect fr om 'tom-select/base';
import remove_button fr om
'tom-select/plugins/remove_button';
TomSelect.define(
'remove_button',
remove_button
);
document.querySelectorAll('.select')
.forEach(el => {
new TomSelect(el, {
plugins: ['remove_button'],
maxOptions: 30,
loadThrottle: 300,
searchField: ['name']
});
});
Такая конфигурация обеспечивает: