Tailwind vs BEM — 1 (сравнение производительности)17.11.2023 10:00
В этих двух статьях я буду сравнивать TailwindCSS с чистым CSS + BEM. Цель — разобраться что является лучшим решением для хорошей архитектуры приложения. Это не вопрос предпочтений, от этого выбора будет зависеть очень многое на поздних этапах разработки и оно должно быть очень хорошо обосновано. Начну со сравнения производительности.Tailwind позволяет значительно уменьшить размер итогового CSS и тем самым ускорить время отображения страницы. Но это сработает только в том случае, если Tailwind классы будут написаны прямо в HTML коде, а не в виде @apply в CSS. Tailwind уменьшает CSS, но увеличивает HTML. Давайте посчитаем разницу с учетом HTML. Будем сравнивать чистый Tailwind с чистым CSS + BEM.
На каждый Tailwind класс — одно свойство. На каждый HTML элемент — полтора BEM класса (если учитывать модификаторы).
u - средняя длина Tailwind класса
c - средняя длина BEM класса
p - средняя длина CSS свойства
Nu - количество уникальных свойств
Np - среднее количество свойств на элемент
Nc - среднее количество BEM классов на элемент
M - количество элементов
Структура CSS для Tailwind:
.u * Nu {
p * Nu;
}
Структура CSS для BEM:
.c * M * Nc {
p * M * Np;
}
Структура HTML для Tailwind:
Структура HTML для BEM
Считаем общий размер:
Tailwind: u * Nu + p * Nu + u * M * Np
BEM: c * M * Nc + p * M * Np + c * M * Nc
Функция для экспериментов в браузере:
function calc({u, c, p, Nu, Np, Nc, M}) {
const Tailwind = u * Nu + p * Nu + u * M * Np
const BEM = c * M * Nc + p * M * Np + c * M * Nc
return {
Tailwind,
BEM,
diff: BEM / Tailwind
}
}
Посмотрим что будет в худшем для Tailwind случае:
calc({
u: 15, // средняя длина Tailwind класса
c: 5, // средняя длина BEM класса (допустим мы сделали обфускацию)
p: 30, // средняя длина CSS свойства
Nu: 500, // количество уникальных свойств
Np: 30, // среднее количество свойств на элемент
Nc: 1.5, // среднее количество BEM классов на элемент
M: 2000, // количество элементов
})
// Tailwind: 922500
// BEM: 1830000
// BEM / Tailwind: 1.98
Вывод 1: В худшем для Tailwind случае размер CSS в 2 раза меньше.
Рассмотрим реалистичный случай:
calc({
u: 10, // средняя длина Tailwind класса
c: 35, // средняя длина BEM класса
p: 30, // средняя длина CSS свойства
Nu: 500, // количество уникальных свойств
Np: 10, // среднее количество свойств на элемент
Nc: 1.5, // среднее количество BEM классов на элемент
M: 2000, // количество элементов
})
// Tailwind: 810000
// BEM: 220000
// BEM / Tailwind: 3.68
Вывод 2: В реалистичном случае размер Tailwind CSS в 4 раза меньше.
Оптимизация
Для BEM мы могли бы сделать оптимизацию CSS и для каждого свойства прописать все классы с этим свойства в селекторе. Тогда общая длина всех свойств должна уменьшиться:
.c * M * Nc * Np {
p * M;
}
Формула для BEM будет такой:
c * M * Nc * Np + p * M + c * M * Nc
Рассмотрим реалистичный случай, но с обфускацией имен классов:
calc({
u: 10, // средняя длина Tailwind класса
c: 5, // средняя длина BEM класса
p: 30, // средняя длина CSS свойства
Nu: 500, // количество уникальных свойств
Np: 10, // среднее количество свойств на элемент
Nc: 1.5, // среднее количество BEM классов на элемент
M: 2000, // количество элементов
})
// Tailwind: 220000
// BEM: 225000
// BEM / Tailwind: 1.023
Предположение: С такой оптимизацией нет никакой разницы в размерах между Tailwind и CSS!
Но, к сожалению, такая оптимизация невозможна. Этот пример иллюстрирует почему:
Насколько вообще большим может быть CSS? На BEM не сложно получить 3 мегабайта. Но gzip сжимает 3MB до всего 60kB. Конечно, после скачивания браузеру нужно еще распаковать CSS, а затем проанализировать, что занимает какое-то время. По моим тестам это 0.5–1 сек на десктопе. На мобильных устройствах это время должно быть значительно больше.Быстрая загрузка и быстрый анализ CSS/HTML важнее, чем изображения или даже скрипты. Скриптам дается небольшая фора, т.к. пользователь не сразу взаимодействует со страницей. А без HTML/CSS страница даже не отобразится корректно, и не начнется загрузка изображений.
Альтернативы
Я не вижу никаких альтернативных способов уменьшить размер CSS столь значительно (в 2–4 раза), кроме как писать стили в виде utility классов прямо в HTML.
Буду рад услышать любую критику, замечания, ваш личный опыт, …